diff --git a/README.md b/README.md index 24c798b..ec31192 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ + + +//testing git.... :) + + A beginner tutorial series for everyone whosoever is enthusiatic to begin with Python apps. This is the first commit in series, and I am beginning with Flask-app tutorial. diff --git a/basic python programmes/.idea/encodings.xml b/basic python programmes/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/basic python programmes/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/basic python programmes/.idea/misc.xml b/basic python programmes/.idea/misc.xml new file mode 100644 index 0000000..06d6bc1 --- /dev/null +++ b/basic python programmes/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/basic python programmes/.idea/modules.xml b/basic python programmes/.idea/modules.xml new file mode 100644 index 0000000..6514061 --- /dev/null +++ b/basic python programmes/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/basic python programmes/.idea/pythonp.iml b/basic python programmes/.idea/pythonp.iml new file mode 100644 index 0000000..85c7612 --- /dev/null +++ b/basic python programmes/.idea/pythonp.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/basic python programmes/.idea/workspace.xml b/basic python programmes/.idea/workspace.xml new file mode 100644 index 0000000..e7bef1d --- /dev/null +++ b/basic python programmes/.idea/workspace.xml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1545323175328 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/basic python programmes/ascii.py b/basic python programmes/ascii.py new file mode 100644 index 0000000..6f29ceb --- /dev/null +++ b/basic python programmes/ascii.py @@ -0,0 +1,18 @@ +'''this programme converts asccii code to character +and a character into an ascii code''' +print("Choose an option from below : ") +print("1.covert ascii to character.") +print('2.Covert character to ascii') +i = int(input('Enter choice : ')) +if i == 1: + print('Enter a number from 1 - 256 ') + num = int(input("NUMBER : ")) + print("your character : ", chr(num)) +# chr returns a string of one character +elif i == 2: + print('Enter a character ') + char = input("CHARACTER : ") + print("your number : ", ord(char)) +# ord returns code for one character +else: + print('Invalid input ') diff --git a/basic python programmes/calculator.py b/basic python programmes/calculator.py new file mode 100644 index 0000000..5fb582e --- /dev/null +++ b/basic python programmes/calculator.py @@ -0,0 +1,32 @@ +# calculator +num1 = int(input('Enter first number : ')) + +print('Choose one of the following operators :') +print('1> +\n2> -\n3> *\n4> /\n5> ^ ') + +op = input('Operator : ') + +num2 = int(input('Enter second number : ')) + +ans = 1 + +if op == '+': + ans = num1 + num2 + +elif op == '-': + ans = num1 - num2 + +elif op == '*': + ans = num1 * num2 + +elif op == '/': + ans = num1 / num2 + +elif op == '^': + ans = num1 ** num2 + +else: + print('Invalid operator input..exiting') + exit() + +print(num1, op, num2, '=', ans) diff --git a/basic python programmes/circlearea.py b/basic python programmes/circlearea.py new file mode 100644 index 0000000..32657f9 --- /dev/null +++ b/basic python programmes/circlearea.py @@ -0,0 +1,8 @@ +# programme to find circumference and are of a circle +import math +print("Enter the radius of the circle :") +r = float(input("RADIUS : ")) +c = 2 * math.pi * r +ar = math.pi * pow(r, 2) +print("AREA : ", ar) +print("CIRCUMFERENCE : ", c) diff --git a/basic python programmes/firstfile.py b/basic python programmes/firstfile.py new file mode 100644 index 0000000..d6a54bf --- /dev/null +++ b/basic python programmes/firstfile.py @@ -0,0 +1,7 @@ +x=float(input('Enter First Number : ')) +y=float(input('Enter Second Number : ')) +z=float(input('Enter Third Number : ')) + +print('The max value is ',max(x,y,z)) + +input('Press anykey to exit..') diff --git a/basic python programmes/funcalc.py b/basic python programmes/funcalc.py new file mode 100644 index 0000000..fbf8fc6 --- /dev/null +++ b/basic python programmes/funcalc.py @@ -0,0 +1,54 @@ +# calculator using functions + + +def add(num1, num2): + ans = num1 + num2 + return ans + + +def sub(num1, num2): + ans = num1 - num2 + return ans + + +def mult(num1, num2): + ans = num1 * num2 + return ans + + +def dev(num1, num2): + ans = num1 / num2 + return ans + + +def pow(num1, num2): + ans = num1 ** num2 + return ans + + +""" end of functions + the so called main""" + + +rep = 'yes' +while rep == 'yes': + num1 = float(input('Enter number 1 : ')) + print('Enter one of the following operator :\n+ - * / ^ ') + op = input('Operator : ') + num2 = float(input('Enter number 2 : ')) + if op == '+': + ans = add(num1, num2) + elif op == '-': + ans = sub(num1, num2) + elif op == '*': + ans = mult(num1, num2) + elif op == '/': + ans = dev(num1, num2) + elif op == '^': + ans = pow(num1, num2) + else: + print('Invalid input .....Exiting ') + exit() + + print(num1, op, num2, '=', ans) + rep = input('Do you want to countinue(yes/no) ? :') diff --git a/basic python programmes/listsasarray.py b/basic python programmes/listsasarray.py new file mode 100644 index 0000000..6141eb6 --- /dev/null +++ b/basic python programmes/listsasarray.py @@ -0,0 +1,12 @@ +# using lists as array +n = int(input('Enter the number of elements of the array : ')) +arr = [] +print('Enter the elements') +count = 0 +for x in range(n): + print('Element', count + 1, ':') + ele = int(input()) + count += 1 + arr.append(ele) + +print('Array = ', arr) diff --git a/basic python programmes/palindrome.py b/basic python programmes/palindrome.py new file mode 100644 index 0000000..5858de3 --- /dev/null +++ b/basic python programmes/palindrome.py @@ -0,0 +1,15 @@ +# to check if the given number is palindrome or not + +print('Enter a number ') +num = int(input('NUMBER : ')) +rev = 0 +temp = num +while num > 0: + b = num % 10 + rev = (rev * 10) + b + num = num // 10 + +if temp == rev: + print('Palindrome') +else: + print('Not a Palindrome') diff --git a/basic python programmes/prime.py b/basic python programmes/prime.py new file mode 100644 index 0000000..62b157f --- /dev/null +++ b/basic python programmes/prime.py @@ -0,0 +1,7 @@ +# programme to check if a number is prime or not +print('Enter a number to check') +num = int(input('NUMBER : ')) +if num % 2 == 0: + print('The number is composite') +else: + print('The number is prime') diff --git a/basic python programmes/secondprog.py b/basic python programmes/secondprog.py new file mode 100644 index 0000000..5f0782c --- /dev/null +++ b/basic python programmes/secondprog.py @@ -0,0 +1,5 @@ +x = int(input("Enter number 1 : ")) +y = int(input("Enter number 2 : ")) +z = int(input("Enter NUmber 3 : ")) +print("Max value is : ", max(x, y, z)) +input("Enter any key to exit..") diff --git a/basic python programmes/strings.py b/basic python programmes/strings.py new file mode 100644 index 0000000..3aa2abc --- /dev/null +++ b/basic python programmes/strings.py @@ -0,0 +1,16 @@ +# programme to calculate number of spaces in a string +str = input('Enter a string : ') +space = 0 +vovels = 0 +char = 0 +for x in str: + if x == ' ': + space += 1 + elif x == 'a' or x == 'A' or x == 'e' or x == 'E' or x == 'i' or x == 'I' or x == 'o' or x == 'O' or x == 'u' or x == 'U': + vovels += 1 + if x != ' ': + char += 1 + +print("Number of spaces : ", space) +print("Number of vovels : ", vovels) +print("Number of characters : ", char) diff --git a/basic python programmes/strings2.py b/basic python programmes/strings2.py new file mode 100644 index 0000000..ae8ad28 --- /dev/null +++ b/basic python programmes/strings2.py @@ -0,0 +1,9 @@ +# programme to remove all vovels from a string + +vovels = ('a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U') +text = input('Enter a string : ') +for x in text: + if x in vovels: + text = text.replace(x, '') + +print('New text : ', text) diff --git a/basic python programmes/strings3.py b/basic python programmes/strings3.py new file mode 100644 index 0000000..f74507c --- /dev/null +++ b/basic python programmes/strings3.py @@ -0,0 +1,8 @@ +# programme to convert lower case letters in string to upper case +import string +text = input('Enter a string : ') +for x in text: + if x in string.ascii_lowercase: + text = text.replace(x, x.upper()) + +print('New string : ', text) diff --git a/basic python programmes/subtexttest.py b/basic python programmes/subtexttest.py new file mode 100644 index 0000000..3acc78b --- /dev/null +++ b/basic python programmes/subtexttest.py @@ -0,0 +1,4 @@ +x = int(input('Enter number 1 : ')) +y = int(input('Enter number 2 : ')) +z = int(input('Enter number 3 : ')) +print("The greatest number is : ", max(x, y, z)) diff --git a/basic python programmes/third.py b/basic python programmes/third.py new file mode 100644 index 0000000..c759e8a --- /dev/null +++ b/basic python programmes/third.py @@ -0,0 +1,7 @@ +name = 'Nirbhay Vashisht' +age = 19 +college = 'BMCEM' +course = 'btech' +Sem = 3 +print("Hello {0} of age {1} ! You are persuing {2} sem {3} in college {4}".format( + name, age, course, Sem, college)) diff --git a/basic python programmes/venv/Lib/site-packages/__pycache__/mccabe.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/__pycache__/mccabe.cpython-37.pyc new file mode 100644 index 0000000..aec4114 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/__pycache__/mccabe.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/__pycache__/six.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000..208d32a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/__pycache__/six.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/DESCRIPTION.rst b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..0bcf160 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,76 @@ +Astroid +======= + +.. image:: https://travis-ci.org/PyCQA/astroid.svg?branch=master + :target: https://travis-ci.org/PyCQA/astroid + +.. image:: https://ci.appveyor.com/api/projects/status/co3u42kunguhbh6l/branch/master?svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/PCManticore/astroid + +.. image:: https://coveralls.io/repos/github/PyCQA/astroid/badge.svg?branch=master + :target: https://coveralls.io/github/PyCQA/astroid?branch=master + +.. image:: https://readthedocs.org/projects/astroid/badge/?version=latest + :target: http://astroid.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + + + +What's this? +------------ + +The aim of this module is to provide a common base representation of +python source code. It is currently the library powering pylint's capabilities. + +It provides a compatible representation which comes from the `_ast` +module. It rebuilds the tree generated by the builtin _ast module by +recursively walking down the AST and building an extended ast. The new +node classes have additional methods and attributes for different +usages. They include some support for static inference and local name +scopes. Furthermore, astroid can also build partial trees by inspecting living +objects. + + +Installation +------------ + +Extract the tarball, jump into the created directory and run:: + + pip install . + + +If you want to do an editable installation, you can run:: + + pip install -e . + + +If you have any questions, please mail the code-quality@python.org +mailing list for support. See +http://mail.python.org/mailman/listinfo/code-quality for subscription +information and archives. + +Documentation +------------- +http://astroid.readthedocs.io/en/latest/ + + +Python Versions +--------------- + +astroid 2.0 is currently available for Python 3 only. If you want Python 2 +support, older versions of astroid will still supported until 2020. + +Test +---- + +Tests are in the 'test' subdirectory. To launch the whole tests suite, you can use +either `tox` or `pytest`:: + + tox + pytest astroid + + diff --git a/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/INSTALLER b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/METADATA b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/METADATA new file mode 100644 index 0000000..f3e913a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.0 +Name: astroid +Version: 2.1.0 +Summary: An abstract syntax tree for Python with inference support. +Home-page: https://github.com/PyCQA/astroid +Author: Python Code Quality Authority +Author-email: code-quality@python.org +License: LGPL +Description-Content-Type: UNKNOWN +Platform: UNKNOWN +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Quality Assurance +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=3.4.* +Requires-Dist: lazy-object-proxy +Requires-Dist: six +Requires-Dist: wrapt +Requires-Dist: typing; python_version < "3.5" +Requires-Dist: typed-ast; python_version < "3.7" and implementation_name == "cpython" + +Astroid +======= + +.. image:: https://travis-ci.org/PyCQA/astroid.svg?branch=master + :target: https://travis-ci.org/PyCQA/astroid + +.. image:: https://ci.appveyor.com/api/projects/status/co3u42kunguhbh6l/branch/master?svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/PCManticore/astroid + +.. image:: https://coveralls.io/repos/github/PyCQA/astroid/badge.svg?branch=master + :target: https://coveralls.io/github/PyCQA/astroid?branch=master + +.. image:: https://readthedocs.org/projects/astroid/badge/?version=latest + :target: http://astroid.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + + + +What's this? +------------ + +The aim of this module is to provide a common base representation of +python source code. It is currently the library powering pylint's capabilities. + +It provides a compatible representation which comes from the `_ast` +module. It rebuilds the tree generated by the builtin _ast module by +recursively walking down the AST and building an extended ast. The new +node classes have additional methods and attributes for different +usages. They include some support for static inference and local name +scopes. Furthermore, astroid can also build partial trees by inspecting living +objects. + + +Installation +------------ + +Extract the tarball, jump into the created directory and run:: + + pip install . + + +If you want to do an editable installation, you can run:: + + pip install -e . + + +If you have any questions, please mail the code-quality@python.org +mailing list for support. See +http://mail.python.org/mailman/listinfo/code-quality for subscription +information and archives. + +Documentation +------------- +http://astroid.readthedocs.io/en/latest/ + + +Python Versions +--------------- + +astroid 2.0 is currently available for Python 3 only. If you want Python 2 +support, older versions of astroid will still supported until 2020. + +Test +---- + +Tests are in the 'test' subdirectory. To launch the whole tests suite, you can use +either `tox` or `pytest`:: + + tox + pytest astroid + + diff --git a/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/RECORD b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/RECORD new file mode 100644 index 0000000..24fc2fa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/RECORD @@ -0,0 +1,123 @@ +astroid/__init__.py,sha256=tJJMsKzMv8hUgw3y0VQAAMx9BO-nrNUcNy_wI0XBFXo,5538 +astroid/__pkginfo__.py,sha256=BbpwFP_8Yd6vSqi29HWRX5_29cLS3-LLYKiEkp3r1k0,2143 +astroid/_ast.py,sha256=mHrblK8bCph2bSA4lz7MlhGHW1zPCwSpfqOudUMey7I,1158 +astroid/arguments.py,sha256=cui-UmbEeywSk0eitSrOhi9F0Ci2clS4qYXTi8uXRs4,11783 +astroid/as_string.py,sha256=WOnmoyFPbRV3M_Oe5ykkncPlaXY_eu9nQzzREHoRFRg,22231 +astroid/bases.py,sha256=Hjzwwftyn1VQ9ELZ7HuPueGolhljc3yvsh_k73qSSZQ,18941 +astroid/builder.py,sha256=0wrC4-ausU_nEEkgI8LJTsrNFN_XCbOkqoG2DsKCsks,16023 +astroid/context.py,sha256=QLpfM-S0WHbK3XKdB9Dr3EXwv_A0MrziPHx1GCPlVvw,5023 +astroid/decorators.py,sha256=ya-Fyn2Uqzi384FARjYf9v2oqwt64KAEG3mlOzuJrEc,4279 +astroid/exceptions.py,sha256=_IJRdLfyNSPVjxYgEd11Uu9XpdqE7uBCVOEIxt3ua70,7047 +astroid/helpers.py,sha256=9L1VT4TcL8Y3eifLIJNCvMp14QVaiRNoWnG2G4cL-Dk,9087 +astroid/inference.py,sha256=UG4DiAFvq32nqIsXWTen2bvCcJbaGpYJDBbny_3fy08,31945 +astroid/manager.py,sha256=eaj_pEomBFDp-BsTyEWhtm8UeIPSrB40rPWJls1-vDc,12426 +astroid/mixins.py,sha256=F2rv2Ow7AU3YT_2jitVJik95ZWRVK6hpf8BrkkspzUY,5571 +astroid/modutils.py,sha256=8zpeNSGwKLA_hlk36o0Q7m3bzCumVP5c-1DJ1dkllYU,23568 +astroid/node_classes.py,sha256=eRi9Wg_U_xUBbRElTQ9gRDo0PuwmVc8temvVfo9kD90,136690 +astroid/nodes.py,sha256=FIa3fF-rJ5BlhlGIcJGrEoyO_r5rMmWeajdAxtGEYFk,2927 +astroid/objects.py,sha256=XpJVSv3z-D2j50-5KLFM7AHXQB0DmFPWKSvaPqXc930,8634 +astroid/protocols.py,sha256=zdLu8TJcNViuqZubMmfENoMs3yGVB0BEh4HxHISVje4,26448 +astroid/raw_building.py,sha256=RpniuHnac0Za5U8tOXBnVNiyUnFb9IplkkuCKlLw7sA,16257 +astroid/rebuilder.py,sha256=XNrjCLgs6JunlcFprK8l4_ol1b8bjiJ0-vK7KRnG4PA,40508 +astroid/scoped_nodes.py,sha256=cracwywITGItGxrDdg6-xzH7isBOzlH2cww5O7WIOlw,92496 +astroid/test_utils.py,sha256=NmVu0GTYA3Fz3BG9sF0KQt2nrd6vMSBoKpGkkIjKz28,2309 +astroid/transforms.py,sha256=1npwJWcQUSIjcpcWd1pc-dJhtHOyiboQHsETAIQd5co,3377 +astroid/util.py,sha256=jg5LnqbWSZTZP1KgpxGBuC6Lfwhn9Jb2T2TohXghmC0,4785 +astroid/brain/brain_argparse.py,sha256=VEeMCr3OIjHmCy35uc-kX6nJ5_NUOAimpGJMr6CChoA,1024 +astroid/brain/brain_attrs.py,sha256=UiqX-t2DhW4v6PISVrZXsnpuk0Lml3JIrtfLiKqCKEw,1900 +astroid/brain/brain_builtin_inference.py,sha256=zSmhGQrIYApV25dLG3v9GulaMaJMJTCsrCffF4fyjvE,26914 +astroid/brain/brain_collections.py,sha256=XBlyS-6J3rlEqv_44EyB6z6YbJq4KJCoN_pKTxdBhOA,2828 +astroid/brain/brain_curses.py,sha256=tDnlCP1bEvleqCMz856yua9mM5um1p_JendFhT4rBFk,3303 +astroid/brain/brain_dateutil.py,sha256=q2dyV2907Bw4n7m2W4EEdok3Ndv8NzeIQxAZwXBiS14,795 +astroid/brain/brain_fstrings.py,sha256=VKVMijgLE2pg2dtXM6GGFgONOxOg8qA9D5V6dYzWTbQ,2121 +astroid/brain/brain_functools.py,sha256=M_Z99A43QUpmAmcA4mC5C-VsOiXpqvb1JxMb43-WYAY,6312 +astroid/brain/brain_gi.py,sha256=-EpcKf9z3wT_7v0k0WXIZtgk3-213lkfUX9bxeKOM3Y,6810 +astroid/brain/brain_hashlib.py,sha256=cp30hX5HhWqbWG3zqcNu8N3aHGeQK4DPi4ac8owBonU,2163 +astroid/brain/brain_io.py,sha256=DJcTFMTexrsHaGg2-kHoXwonddu13ImT7NEjiF1xPiU,1470 +astroid/brain/brain_mechanize.py,sha256=xTBc-u2DMmMPeci7DVFs4L2T98DwwLF_Ob5YZviLPp8,889 +astroid/brain/brain_multiprocessing.py,sha256=zXqLXg6dVYTkik1qSjo1cPJMZAGrkobVslp7ArwEXYQ,3108 +astroid/brain/brain_namedtuple_enum.py,sha256=d1TotHYqvfmPxVXKt7uGtdUetB3txEuSRxrhsEKb7lw,14028 +astroid/brain/brain_nose.py,sha256=kECw2jHmX0IUPX4Gx3XVGrflKGnlgPB79QHt6WU2cwQ,2211 +astroid/brain/brain_numpy.py,sha256=b55v7T5ps9ShC_qps2CAfU7u_mbW523ddtiaKDwx8Mo,14791 +astroid/brain/brain_pkg_resources.py,sha256=S_5UED1Zg8ObEJumRdpYGnjxZzemh_G_NFj3p5NGPfc,2262 +astroid/brain/brain_pytest.py,sha256=RXaNUVqy2R0et0Upn4GJkVgq5SG8Pl7zLlhqQg8Xx3Q,2384 +astroid/brain/brain_qt.py,sha256=U3VOrHer0cLvpxJC55MLEYrKn1Z3RQRXsc6fQ7u5hvI,2437 +astroid/brain/brain_random.py,sha256=2RZY-QEXMNWp7E6h0l0-ke-DtjKTOFlTdjiQZi3XdQc,2432 +astroid/brain/brain_re.py,sha256=le7VJHUAf80HyE_aQCh7_8FyDVK6JwNWA--c9RaMVQ8,1128 +astroid/brain/brain_six.py,sha256=6QHcKXoYf8yMMXWkx3g3lK0kqB5OFeYcXwjUTdgWTMw,6146 +astroid/brain/brain_ssl.py,sha256=8AvwQnF9eX7t_aqECEbQf2ob3dJUlpbg_alXcp-KWbk,3558 +astroid/brain/brain_subprocess.py,sha256=8EyK2m0DKAZM7DEf1ivJ7PY9TD2RpMWO8EFovZ_e7Rc,3631 +astroid/brain/brain_threading.py,sha256=Qv06IeuEwDlk8cibAlUxlPx2FWMyRpoSCMQTkCrL04Q,767 +astroid/brain/brain_typing.py,sha256=5lbwLS0a9BgxmqJIf26UXBAEyaFRpGigAowFHcdwp3I,2723 +astroid/brain/brain_uuid.py,sha256=flWrk1Ve7oqYrO8GTZ3To8RBYteRfYwvash-s9KiU9o,564 +astroid/interpreter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +astroid/interpreter/dunder_lookup.py,sha256=dP-AZU_aGPNt03b1ttrMglxzeU3NtgnG0MfpSLPH6sg,2155 +astroid/interpreter/objectmodel.py,sha256=ww1UQPL3iQdAJj8REjOANW7dBhiLA4Ynd7qJp7bl8d4,21307 +astroid/interpreter/_import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +astroid/interpreter/_import/spec.py,sha256=oDdgvZZCuagrsjaiNOq3MbmEhabWyWUfX7xjJaTXEpE,10942 +astroid/interpreter/_import/util.py,sha256=inubUz6F3_kaMFaeleKUW6E6wCMIPrhU882zvwEZ02I,255 +astroid-2.1.0.dist-info/DESCRIPTION.rst,sha256=Ql_Ui1POiy9SIMSRfy_GV9u8xN0085VlNlyzi8h2C1o,2158 +astroid-2.1.0.dist-info/METADATA,sha256=Jm0lbRRcHDS_20vdBfDv0fQ0O4KvULJtfvNmacnGG-s,3262 +astroid-2.1.0.dist-info/RECORD,, +astroid-2.1.0.dist-info/WHEEL,sha256=8Lm45v9gcYRm70DrgFGVe4WsUtUMi1_0Tso1hqPGMjA,92 +astroid-2.1.0.dist-info/metadata.json,sha256=OlYXVfIFjUmEMAOGa9U2dE4-Y1VqM9BHfUROm2iQvnY,1332 +astroid-2.1.0.dist-info/top_level.txt,sha256=HsdW4O2x7ZXRj6k-agi3RaQybGLobI3VSE-jt4vQUXM,8 +astroid-2.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +astroid/brain/__pycache__/brain_argparse.cpython-37.pyc,, +astroid/brain/__pycache__/brain_attrs.cpython-37.pyc,, +astroid/brain/__pycache__/brain_builtin_inference.cpython-37.pyc,, +astroid/brain/__pycache__/brain_collections.cpython-37.pyc,, +astroid/brain/__pycache__/brain_curses.cpython-37.pyc,, +astroid/brain/__pycache__/brain_dateutil.cpython-37.pyc,, +astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc,, +astroid/brain/__pycache__/brain_functools.cpython-37.pyc,, +astroid/brain/__pycache__/brain_gi.cpython-37.pyc,, +astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc,, +astroid/brain/__pycache__/brain_io.cpython-37.pyc,, +astroid/brain/__pycache__/brain_mechanize.cpython-37.pyc,, +astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc,, +astroid/brain/__pycache__/brain_namedtuple_enum.cpython-37.pyc,, +astroid/brain/__pycache__/brain_nose.cpython-37.pyc,, +astroid/brain/__pycache__/brain_numpy.cpython-37.pyc,, +astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc,, +astroid/brain/__pycache__/brain_pytest.cpython-37.pyc,, +astroid/brain/__pycache__/brain_qt.cpython-37.pyc,, +astroid/brain/__pycache__/brain_random.cpython-37.pyc,, +astroid/brain/__pycache__/brain_re.cpython-37.pyc,, +astroid/brain/__pycache__/brain_six.cpython-37.pyc,, +astroid/brain/__pycache__/brain_ssl.cpython-37.pyc,, +astroid/brain/__pycache__/brain_subprocess.cpython-37.pyc,, +astroid/brain/__pycache__/brain_threading.cpython-37.pyc,, +astroid/brain/__pycache__/brain_typing.cpython-37.pyc,, +astroid/brain/__pycache__/brain_uuid.cpython-37.pyc,, +astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc,, +astroid/interpreter/_import/__pycache__/util.cpython-37.pyc,, +astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc,, +astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc,, +astroid/interpreter/__pycache__/objectmodel.cpython-37.pyc,, +astroid/interpreter/__pycache__/__init__.cpython-37.pyc,, +astroid/__pycache__/arguments.cpython-37.pyc,, +astroid/__pycache__/as_string.cpython-37.pyc,, +astroid/__pycache__/bases.cpython-37.pyc,, +astroid/__pycache__/builder.cpython-37.pyc,, +astroid/__pycache__/context.cpython-37.pyc,, +astroid/__pycache__/decorators.cpython-37.pyc,, +astroid/__pycache__/exceptions.cpython-37.pyc,, +astroid/__pycache__/helpers.cpython-37.pyc,, +astroid/__pycache__/inference.cpython-37.pyc,, +astroid/__pycache__/manager.cpython-37.pyc,, +astroid/__pycache__/mixins.cpython-37.pyc,, +astroid/__pycache__/modutils.cpython-37.pyc,, +astroid/__pycache__/nodes.cpython-37.pyc,, +astroid/__pycache__/node_classes.cpython-37.pyc,, +astroid/__pycache__/objects.cpython-37.pyc,, +astroid/__pycache__/protocols.cpython-37.pyc,, +astroid/__pycache__/raw_building.cpython-37.pyc,, +astroid/__pycache__/rebuilder.cpython-37.pyc,, +astroid/__pycache__/scoped_nodes.cpython-37.pyc,, +astroid/__pycache__/test_utils.cpython-37.pyc,, +astroid/__pycache__/transforms.cpython-37.pyc,, +astroid/__pycache__/util.cpython-37.pyc,, +astroid/__pycache__/_ast.cpython-37.pyc,, +astroid/__pycache__/__init__.cpython-37.pyc,, +astroid/__pycache__/__pkginfo__.cpython-37.pyc,, diff --git a/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/WHEEL b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/WHEEL new file mode 100644 index 0000000..6261a26 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/metadata.json b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/metadata.json new file mode 100644 index 0000000..fdce336 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Quality Assurance", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"contacts": [{"email": "code-quality@python.org", "name": "Python Code Quality Authority", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/PyCQA/astroid"}}}, "extras": [], "generator": "bdist_wheel (0.30.0)", "license": "LGPL", "metadata_version": "2.0", "name": "astroid", "requires_python": ">=3.4.*", "run_requires": [{"requires": ["lazy-object-proxy", "six", "wrapt"]}, {"environment": "python_version < \"3.5\"", "requires": ["typing"]}, {"environment": "python_version < \"3.7\" and implementation_name == \"cpython\"", "requires": ["typed-ast"]}], "summary": "An abstract syntax tree for Python with inference support.", "test_requires": [{"requires": ["pytest"]}], "version": "2.1.0"} \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/top_level.txt new file mode 100644 index 0000000..450d4fe --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid-2.1.0.dist-info/top_level.txt @@ -0,0 +1 @@ +astroid diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__init__.py b/basic python programmes/venv/Lib/site-packages/astroid/__init__.py new file mode 100644 index 0000000..d36a5b4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/__init__.py @@ -0,0 +1,166 @@ +# Copyright (c) 2006-2013, 2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Python Abstract Syntax Tree New Generation + +The aim of this module is to provide a common base representation of +python source code for projects such as pychecker, pyreverse, +pylint... Well, actually the development of this library is essentially +governed by pylint's needs. + +It extends class defined in the python's _ast module with some +additional methods and attributes. Instance attributes are added by a +builder object, which can either generate extended ast (let's call +them astroid ;) by visiting an existent ast tree or by inspecting living +object. Methods are added by monkey patching ast classes. + +Main modules are: + +* nodes and scoped_nodes for more information about methods and + attributes added to different node classes + +* the manager contains a high level object to get astroid trees from + source files and living objects. It maintains a cache of previously + constructed tree for quick access + +* builder contains the class responsible to build astroid trees +""" + +import enum +import itertools +import os +import sys + +import wrapt + + +_Context = enum.Enum("Context", "Load Store Del") +Load = _Context.Load +Store = _Context.Store +Del = _Context.Del +del _Context + + +from .__pkginfo__ import version as __version__ + +# WARNING: internal imports order matters ! + +# pylint: disable=redefined-builtin + +# make all exception classes accessible from astroid package +from astroid.exceptions import * + +# make all node classes accessible from astroid package +from astroid.nodes import * + +# trigger extra monkey-patching +from astroid import inference + +# more stuff available +from astroid import raw_building +from astroid.bases import BaseInstance, Instance, BoundMethod, UnboundMethod +from astroid.node_classes import are_exclusive, unpack_infer +from astroid.scoped_nodes import builtin_lookup +from astroid.builder import parse, extract_node +from astroid.util import Uninferable + +# make a manager instance (borg) accessible from astroid package +from astroid.manager import AstroidManager + +MANAGER = AstroidManager() +del AstroidManager + +# transform utilities (filters and decorator) + + +# pylint: disable=dangerous-default-value +@wrapt.decorator +def _inference_tip_cached(func, instance, args, kwargs, _cache={}): + """Cache decorator used for inference tips""" + node = args[0] + try: + return iter(_cache[func, node]) + except KeyError: + result = func(*args, **kwargs) + # Need to keep an iterator around + original, copy = itertools.tee(result) + _cache[func, node] = list(copy) + return original + + +# pylint: enable=dangerous-default-value + + +def inference_tip(infer_function, raise_on_overwrite=False): + """Given an instance specific inference function, return a function to be + given to MANAGER.register_transform to set this inference function. + + :param bool raise_on_overwrite: Raise an `InferenceOverwriteError` + if the inference tip will overwrite another. Used for debugging + + Typical usage + + .. sourcecode:: python + + MANAGER.register_transform(Call, inference_tip(infer_named_tuple), + predicate) + + .. Note:: + + Using an inference tip will override + any previously set inference tip for the given + node. Use a predicate in the transform to prevent + excess overwrites. + """ + + def transform(node, infer_function=infer_function): + if ( + raise_on_overwrite + and node._explicit_inference is not None + and node._explicit_inference is not infer_function + ): + raise InferenceOverwriteError( + "Inference already set to {existing_inference}. " + "Trying to overwrite with {new_inference} for {node}".format( + existing_inference=infer_function, + new_inference=node._explicit_inference, + node=node, + ) + ) + # pylint: disable=no-value-for-parameter + node._explicit_inference = _inference_tip_cached(infer_function) + return node + + return transform + + +def register_module_extender(manager, module_name, get_extension_mod): + def transform(node): + extension_module = get_extension_mod() + for name, objs in extension_module.locals.items(): + node.locals[name] = objs + for obj in objs: + if obj.parent is extension_module: + obj.parent = node + + manager.register_transform(Module, transform, lambda n: n.name == module_name) + + +# load brain plugins +BRAIN_MODULES_DIR = os.path.join(os.path.dirname(__file__), "brain") +if BRAIN_MODULES_DIR not in sys.path: + # add it to the end of the list so user path take precedence + sys.path.append(BRAIN_MODULES_DIR) +# load modules in this directory +for module in os.listdir(BRAIN_MODULES_DIR): + if module.endswith(".py"): + __import__(module[:-3]) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pkginfo__.py b/basic python programmes/venv/Lib/site-packages/astroid/__pkginfo__.py new file mode 100644 index 0000000..4ab6756 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/__pkginfo__.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2017 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Radosław Ganczarek +# Copyright (c) 2016 Moises Lopez +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""astroid packaging information""" + +distname = "astroid" + +modname = "astroid" + +version = "2.1.0" +numversion = tuple(int(elem) for elem in version.split(".") if elem.isdigit()) + +extras_require = {} +install_requires = [ + "lazy_object_proxy", + "six", + "wrapt", + 'typing;python_version<"3.5"', + 'typed_ast;python_version<"3.7" and implementation_name== "cpython"', +] + +# pylint: disable=redefined-builtin; why license is a builtin anyway? +license = "LGPL" + +author = "Python Code Quality Authority" +author_email = "code-quality@python.org" +mailinglist = "mailto://%s" % author_email +web = "https://github.com/PyCQA/astroid" + +description = "An abstract syntax tree for Python with inference support." + +classifiers = [ + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Quality Assurance", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..17566c3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/__pkginfo__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/__pkginfo__.cpython-37.pyc new file mode 100644 index 0000000..2271b05 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/__pkginfo__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/_ast.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/_ast.cpython-37.pyc new file mode 100644 index 0000000..24556b6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/_ast.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/arguments.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/arguments.cpython-37.pyc new file mode 100644 index 0000000..f25f4f6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/arguments.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/as_string.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/as_string.cpython-37.pyc new file mode 100644 index 0000000..90b6d4a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/as_string.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/bases.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/bases.cpython-37.pyc new file mode 100644 index 0000000..09eed81 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/bases.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/builder.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/builder.cpython-37.pyc new file mode 100644 index 0000000..6a7ad0e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/builder.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/context.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/context.cpython-37.pyc new file mode 100644 index 0000000..6c4b788 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/context.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/decorators.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/decorators.cpython-37.pyc new file mode 100644 index 0000000..91cc363 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/decorators.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000..2e95c17 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/helpers.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000..4ef3f7e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/helpers.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/inference.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/inference.cpython-37.pyc new file mode 100644 index 0000000..45d1da5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/inference.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/manager.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/manager.cpython-37.pyc new file mode 100644 index 0000000..8f3eb7f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/manager.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/mixins.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/mixins.cpython-37.pyc new file mode 100644 index 0000000..c27209e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/mixins.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/modutils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/modutils.cpython-37.pyc new file mode 100644 index 0000000..832cf2c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/modutils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/node_classes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/node_classes.cpython-37.pyc new file mode 100644 index 0000000..545780b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/node_classes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/nodes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/nodes.cpython-37.pyc new file mode 100644 index 0000000..b0fff01 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/nodes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/objects.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/objects.cpython-37.pyc new file mode 100644 index 0000000..a918856 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/objects.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/protocols.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/protocols.cpython-37.pyc new file mode 100644 index 0000000..c746fbb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/protocols.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/raw_building.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/raw_building.cpython-37.pyc new file mode 100644 index 0000000..1bb1902 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/raw_building.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/rebuilder.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/rebuilder.cpython-37.pyc new file mode 100644 index 0000000..27199bb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/rebuilder.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/scoped_nodes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/scoped_nodes.cpython-37.pyc new file mode 100644 index 0000000..d35a250 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/scoped_nodes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/test_utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/test_utils.cpython-37.pyc new file mode 100644 index 0000000..1c55476 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/test_utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/transforms.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/transforms.cpython-37.pyc new file mode 100644 index 0000000..0fa5a22 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/transforms.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/util.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000..3ac74f2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/__pycache__/util.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/_ast.py b/basic python programmes/venv/Lib/site-packages/astroid/_ast.py new file mode 100644 index 0000000..7868a7f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/_ast.py @@ -0,0 +1,39 @@ +import ast +import sys +from collections import namedtuple +from typing import Optional + +_ast_py2 = _ast_py3 = None +try: + import typed_ast.ast3 as _ast_py3 + import typed_ast.ast27 as _ast_py2 +except ImportError: + pass + + +FunctionType = namedtuple("FunctionType", ["argtypes", "returns"]) + + +def _get_parser_module(parse_python_two: bool = False): + if parse_python_two: + parser_module = _ast_py2 + elif sys.version_info[:2] >= (3, 7): + # The typed_ast module doesn't support the full 3.7 syntax yet. + # Remove once typed_ast is updated. + parser_module = ast + else: + parser_module = _ast_py3 + return parser_module or ast + + +def _parse(string: str, parse_python_two: bool = False): + return _get_parser_module(parse_python_two=parse_python_two).parse(string) + + +def parse_function_type_comment(type_comment: str) -> Optional[FunctionType]: + """Given a correct type comment, obtain a FunctionType object""" + if _ast_py3 is None: + return None + + func_type = _ast_py3.parse(type_comment, "", "func_type") + return FunctionType(argtypes=func_type.argtypes, returns=func_type.returns) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/arguments.py b/basic python programmes/venv/Lib/site-packages/astroid/arguments.py new file mode 100644 index 0000000..c4bdc6d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/arguments.py @@ -0,0 +1,285 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import nodes +from astroid import util + + +class CallSite: + """Class for understanding arguments passed into a call site + + It needs a call context, which contains the arguments and the + keyword arguments that were passed into a given call site. + In order to infer what an argument represents, call + :meth:`infer_argument` with the corresponding function node + and the argument name. + """ + + def __init__(self, callcontext, argument_context_map=None): + if argument_context_map is None: + argument_context_map = {} + self.argument_context_map = argument_context_map + args = callcontext.args + keywords = callcontext.keywords + self.duplicated_keywords = set() + self._unpacked_args = self._unpack_args(args) + self._unpacked_kwargs = self._unpack_keywords(keywords) + + self.positional_arguments = [ + arg for arg in self._unpacked_args if arg is not util.Uninferable + ] + self.keyword_arguments = { + key: value + for key, value in self._unpacked_kwargs.items() + if value is not util.Uninferable + } + + @classmethod + def from_call(cls, call_node): + """Get a CallSite object from the given Call node.""" + callcontext = contextmod.CallContext(call_node.args, call_node.keywords) + return cls(callcontext) + + def has_invalid_arguments(self): + """Check if in the current CallSite were passed *invalid* arguments + + This can mean multiple things. For instance, if an unpacking + of an invalid object was passed, then this method will return True. + Other cases can be when the arguments can't be inferred by astroid, + for example, by passing objects which aren't known statically. + """ + return len(self.positional_arguments) != len(self._unpacked_args) + + def has_invalid_keywords(self): + """Check if in the current CallSite were passed *invalid* keyword arguments + + For instance, unpacking a dictionary with integer keys is invalid + (**{1:2}), because the keys must be strings, which will make this + method to return True. Other cases where this might return True if + objects which can't be inferred were passed. + """ + return len(self.keyword_arguments) != len(self._unpacked_kwargs) + + def _unpack_keywords(self, keywords): + values = {} + context = contextmod.InferenceContext() + context.extra_context = self.argument_context_map + for name, value in keywords: + if name is None: + # Then it's an unpacking operation (**) + try: + inferred = next(value.infer(context=context)) + except exceptions.InferenceError: + values[name] = util.Uninferable + continue + + if not isinstance(inferred, nodes.Dict): + # Not something we can work with. + values[name] = util.Uninferable + continue + + for dict_key, dict_value in inferred.items: + try: + dict_key = next(dict_key.infer(context=context)) + except exceptions.InferenceError: + values[name] = util.Uninferable + continue + if not isinstance(dict_key, nodes.Const): + values[name] = util.Uninferable + continue + if not isinstance(dict_key.value, str): + values[name] = util.Uninferable + continue + if dict_key.value in values: + # The name is already in the dictionary + values[dict_key.value] = util.Uninferable + self.duplicated_keywords.add(dict_key.value) + continue + values[dict_key.value] = dict_value + else: + values[name] = value + return values + + def _unpack_args(self, args): + values = [] + context = contextmod.InferenceContext() + context.extra_context = self.argument_context_map + for arg in args: + if isinstance(arg, nodes.Starred): + try: + inferred = next(arg.value.infer(context=context)) + except exceptions.InferenceError: + values.append(util.Uninferable) + continue + + if inferred is util.Uninferable: + values.append(util.Uninferable) + continue + if not hasattr(inferred, "elts"): + values.append(util.Uninferable) + continue + values.extend(inferred.elts) + else: + values.append(arg) + return values + + def infer_argument(self, funcnode, name, context): + """infer a function argument value according to the call context + + Arguments: + funcnode: The function being called. + name: The name of the argument whose value is being inferred. + context: Inference context object + """ + if name in self.duplicated_keywords: + raise exceptions.InferenceError( + "The arguments passed to {func!r} " " have duplicate keywords.", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + + # Look into the keywords first, maybe it's already there. + try: + return self.keyword_arguments[name].infer(context) + except KeyError: + pass + + # Too many arguments given and no variable arguments. + if len(self.positional_arguments) > len(funcnode.args.args): + if not funcnode.args.vararg: + raise exceptions.InferenceError( + "Too many positional arguments " + "passed to {func!r} that does " + "not have *args.", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + + positional = self.positional_arguments[: len(funcnode.args.args)] + vararg = self.positional_arguments[len(funcnode.args.args) :] + argindex = funcnode.args.find_argname(name)[0] + kwonlyargs = {arg.name for arg in funcnode.args.kwonlyargs} + kwargs = { + key: value + for key, value in self.keyword_arguments.items() + if key not in kwonlyargs + } + # If there are too few positionals compared to + # what the function expects to receive, check to see + # if the missing positional arguments were passed + # as keyword arguments and if so, place them into the + # positional args list. + if len(positional) < len(funcnode.args.args): + for func_arg in funcnode.args.args: + if func_arg.name in kwargs: + arg = kwargs.pop(func_arg.name) + positional.append(arg) + + if argindex is not None: + # 2. first argument of instance/class method + if argindex == 0 and funcnode.type in ("method", "classmethod"): + if context.boundnode is not None: + boundnode = context.boundnode + else: + # XXX can do better ? + boundnode = funcnode.parent.frame() + + if isinstance(boundnode, nodes.ClassDef): + # Verify that we're accessing a method + # of the metaclass through a class, as in + # `cls.metaclass_method`. In this case, the + # first argument is always the class. + method_scope = funcnode.parent.scope() + if method_scope is boundnode.metaclass(): + return iter((boundnode,)) + + if funcnode.type == "method": + if not isinstance(boundnode, bases.Instance): + boundnode = bases.Instance(boundnode) + return iter((boundnode,)) + if funcnode.type == "classmethod": + return iter((boundnode,)) + # if we have a method, extract one position + # from the index, so we'll take in account + # the extra parameter represented by `self` or `cls` + if funcnode.type in ("method", "classmethod"): + argindex -= 1 + # 2. search arg index + try: + return self.positional_arguments[argindex].infer(context) + except IndexError: + pass + + if funcnode.args.kwarg == name: + # It wants all the keywords that were passed into + # the call site. + if self.has_invalid_keywords(): + raise exceptions.InferenceError( + "Inference failed to find values for all keyword arguments " + "to {func!r}: {unpacked_kwargs!r} doesn't correspond to " + "{keyword_arguments!r}.", + keyword_arguments=self.keyword_arguments, + unpacked_kwargs=self._unpacked_kwargs, + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + kwarg = nodes.Dict( + lineno=funcnode.args.lineno, + col_offset=funcnode.args.col_offset, + parent=funcnode.args, + ) + kwarg.postinit( + [(nodes.const_factory(key), value) for key, value in kwargs.items()] + ) + return iter((kwarg,)) + if funcnode.args.vararg == name: + # It wants all the args that were passed into + # the call site. + if self.has_invalid_arguments(): + raise exceptions.InferenceError( + "Inference failed to find values for all positional " + "arguments to {func!r}: {unpacked_args!r} doesn't " + "correspond to {positional_arguments!r}.", + positional_arguments=self.positional_arguments, + unpacked_args=self._unpacked_args, + call_site=self, + func=funcnode, + arg=name, + context=context, + ) + args = nodes.Tuple( + lineno=funcnode.args.lineno, + col_offset=funcnode.args.col_offset, + parent=funcnode.args, + ) + args.postinit(vararg) + return iter((args,)) + + # Check if it's a default parameter. + try: + return funcnode.args.default_value(name).infer(context) + except exceptions.NoDefault: + pass + raise exceptions.InferenceError( + "No value found for argument {name} to " "{func!r}", + call_site=self, + func=funcnode, + arg=name, + context=context, + ) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/as_string.py b/basic python programmes/venv/Lib/site-packages/astroid/as_string.py new file mode 100644 index 0000000..7042272 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/as_string.py @@ -0,0 +1,630 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2013-2016, 2018 Claudiu Popa +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 brendanator +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module renders Astroid nodes as string: + +* :func:`to_code` function return equivalent (hopefully valid) python string + +* :func:`dump` function return an internal representation of nodes found + in the tree, useful for debugging or understanding the tree structure +""" +import sys + + +# pylint: disable=unused-argument + +DOC_NEWLINE = "\0" + + +class AsStringVisitor: + """Visitor to render an Astroid node as a valid python code string""" + + def __init__(self, indent): + self.indent = indent + + def __call__(self, node): + """Makes this visitor behave as a simple function""" + return node.accept(self).replace(DOC_NEWLINE, "\n") + + def _docs_dedent(self, doc): + """Stop newlines in docs being indented by self._stmt_list""" + return '\n%s"""%s"""' % (self.indent, doc.replace("\n", DOC_NEWLINE)) + + def _stmt_list(self, stmts, indent=True): + """return a list of nodes to string""" + stmts = "\n".join(nstr for nstr in [n.accept(self) for n in stmts] if nstr) + if indent: + return self.indent + stmts.replace("\n", "\n" + self.indent) + + return stmts + + def _precedence_parens(self, node, child, is_left=True): + """Wrap child in parens only if required to keep same semantics""" + if self._should_wrap(node, child, is_left): + return "(%s)" % child.accept(self) + + return child.accept(self) + + def _should_wrap(self, node, child, is_left): + """Wrap child if: + - it has lower precedence + - same precedence with position opposite to associativity direction + """ + node_precedence = node.op_precedence() + child_precedence = child.op_precedence() + + if node_precedence > child_precedence: + # 3 * (4 + 5) + return True + + if ( + node_precedence == child_precedence + and is_left != node.op_left_associative() + ): + # 3 - (4 - 5) + # (2**3)**4 + return True + + return False + + ## visit_ methods ########################################### + + def visit_arguments(self, node): + """return an astroid.Function node as string""" + return node.format_args() + + def visit_assignattr(self, node): + """return an astroid.AssAttr node as string""" + return self.visit_attribute(node) + + def visit_assert(self, node): + """return an astroid.Assert node as string""" + if node.fail: + return "assert %s, %s" % (node.test.accept(self), node.fail.accept(self)) + return "assert %s" % node.test.accept(self) + + def visit_assignname(self, node): + """return an astroid.AssName node as string""" + return node.name + + def visit_assign(self, node): + """return an astroid.Assign node as string""" + lhs = " = ".join(n.accept(self) for n in node.targets) + return "%s = %s" % (lhs, node.value.accept(self)) + + def visit_augassign(self, node): + """return an astroid.AugAssign node as string""" + return "%s %s %s" % (node.target.accept(self), node.op, node.value.accept(self)) + + def visit_annassign(self, node): + """Return an astroid.AugAssign node as string""" + + target = node.target.accept(self) + annotation = node.annotation.accept(self) + if node.value is None: + return "%s: %s" % (target, annotation) + return "%s: %s = %s" % (target, annotation, node.value.accept(self)) + + def visit_repr(self, node): + """return an astroid.Repr node as string""" + return "`%s`" % node.value.accept(self) + + def visit_binop(self, node): + """return an astroid.BinOp node as string""" + left = self._precedence_parens(node, node.left) + right = self._precedence_parens(node, node.right, is_left=False) + if node.op == "**": + return "%s%s%s" % (left, node.op, right) + + return "%s %s %s" % (left, node.op, right) + + def visit_boolop(self, node): + """return an astroid.BoolOp node as string""" + values = ["%s" % self._precedence_parens(node, n) for n in node.values] + return (" %s " % node.op).join(values) + + def visit_break(self, node): + """return an astroid.Break node as string""" + return "break" + + def visit_call(self, node): + """return an astroid.Call node as string""" + expr_str = self._precedence_parens(node, node.func) + args = [arg.accept(self) for arg in node.args] + if node.keywords: + keywords = [kwarg.accept(self) for kwarg in node.keywords] + else: + keywords = [] + + args.extend(keywords) + return "%s(%s)" % (expr_str, ", ".join(args)) + + def visit_classdef(self, node): + """return an astroid.ClassDef node as string""" + decorate = node.decorators.accept(self) if node.decorators else "" + bases = ", ".join(n.accept(self) for n in node.bases) + metaclass = node.metaclass() + if metaclass and not node.has_metaclass_hack(): + if bases: + bases = "(%s, metaclass=%s)" % (bases, metaclass.name) + else: + bases = "(metaclass=%s)" % metaclass.name + else: + bases = "(%s)" % bases if bases else "" + docs = self._docs_dedent(node.doc) if node.doc else "" + return "\n\n%sclass %s%s:%s\n%s\n" % ( + decorate, + node.name, + bases, + docs, + self._stmt_list(node.body), + ) + + def visit_compare(self, node): + """return an astroid.Compare node as string""" + rhs_str = " ".join( + [ + "%s %s" % (op, self._precedence_parens(node, expr, is_left=False)) + for op, expr in node.ops + ] + ) + return "%s %s" % (self._precedence_parens(node, node.left), rhs_str) + + def visit_comprehension(self, node): + """return an astroid.Comprehension node as string""" + ifs = "".join(" if %s" % n.accept(self) for n in node.ifs) + return "for %s in %s%s" % ( + node.target.accept(self), + node.iter.accept(self), + ifs, + ) + + def visit_const(self, node): + """return an astroid.Const node as string""" + if node.value is Ellipsis: + return "..." + return repr(node.value) + + def visit_continue(self, node): + """return an astroid.Continue node as string""" + return "continue" + + def visit_delete(self, node): # XXX check if correct + """return an astroid.Delete node as string""" + return "del %s" % ", ".join(child.accept(self) for child in node.targets) + + def visit_delattr(self, node): + """return an astroid.DelAttr node as string""" + return self.visit_attribute(node) + + def visit_delname(self, node): + """return an astroid.DelName node as string""" + return node.name + + def visit_decorators(self, node): + """return an astroid.Decorators node as string""" + return "@%s\n" % "\n@".join(item.accept(self) for item in node.nodes) + + def visit_dict(self, node): + """return an astroid.Dict node as string""" + return "{%s}" % ", ".join(self._visit_dict(node)) + + def _visit_dict(self, node): + for key, value in node.items: + key = key.accept(self) + value = value.accept(self) + if key == "**": + # It can only be a DictUnpack node. + yield key + value + else: + yield "%s: %s" % (key, value) + + def visit_dictunpack(self, node): + return "**" + + def visit_dictcomp(self, node): + """return an astroid.DictComp node as string""" + return "{%s: %s %s}" % ( + node.key.accept(self), + node.value.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_expr(self, node): + """return an astroid.Discard node as string""" + return node.value.accept(self) + + def visit_emptynode(self, node): + """dummy method for visiting an Empty node""" + return "" + + def visit_excepthandler(self, node): + if node.type: + if node.name: + excs = "except %s, %s" % ( + node.type.accept(self), + node.name.accept(self), + ) + else: + excs = "except %s" % node.type.accept(self) + else: + excs = "except" + return "%s:\n%s" % (excs, self._stmt_list(node.body)) + + def visit_ellipsis(self, node): + """return an astroid.Ellipsis node as string""" + return "..." + + def visit_empty(self, node): + """return an Empty node as string""" + return "" + + def visit_exec(self, node): + """return an astroid.Exec node as string""" + if node.locals: + return "exec %s in %s, %s" % ( + node.expr.accept(self), + node.locals.accept(self), + node.globals.accept(self), + ) + if node.globals: + return "exec %s in %s" % (node.expr.accept(self), node.globals.accept(self)) + return "exec %s" % node.expr.accept(self) + + def visit_extslice(self, node): + """return an astroid.ExtSlice node as string""" + return ", ".join(dim.accept(self) for dim in node.dims) + + def visit_for(self, node): + """return an astroid.For node as string""" + fors = "for %s in %s:\n%s" % ( + node.target.accept(self), + node.iter.accept(self), + self._stmt_list(node.body), + ) + if node.orelse: + fors = "%s\nelse:\n%s" % (fors, self._stmt_list(node.orelse)) + return fors + + def visit_importfrom(self, node): + """return an astroid.ImportFrom node as string""" + return "from %s import %s" % ( + "." * (node.level or 0) + node.modname, + _import_string(node.names), + ) + + def visit_functiondef(self, node): + """return an astroid.Function node as string""" + decorate = node.decorators.accept(self) if node.decorators else "" + docs = self._docs_dedent(node.doc) if node.doc else "" + trailer = ":" + if node.returns: + return_annotation = "->" + node.returns.as_string() + trailer = return_annotation + ":" + def_format = "\n%sdef %s(%s)%s%s\n%s" + return def_format % ( + decorate, + node.name, + node.args.accept(self), + trailer, + docs, + self._stmt_list(node.body), + ) + + def visit_generatorexp(self, node): + """return an astroid.GeneratorExp node as string""" + return "(%s %s)" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_attribute(self, node): + """return an astroid.Getattr node as string""" + return "%s.%s" % (self._precedence_parens(node, node.expr), node.attrname) + + def visit_global(self, node): + """return an astroid.Global node as string""" + return "global %s" % ", ".join(node.names) + + def visit_if(self, node): + """return an astroid.If node as string""" + ifs = ["if %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body))] + if node.has_elif_block(): + ifs.append("el%s" % self._stmt_list(node.orelse, indent=False)) + elif node.orelse: + ifs.append("else:\n%s" % self._stmt_list(node.orelse)) + return "\n".join(ifs) + + def visit_ifexp(self, node): + """return an astroid.IfExp node as string""" + return "%s if %s else %s" % ( + self._precedence_parens(node, node.body, is_left=True), + self._precedence_parens(node, node.test, is_left=True), + self._precedence_parens(node, node.orelse, is_left=False), + ) + + def visit_import(self, node): + """return an astroid.Import node as string""" + return "import %s" % _import_string(node.names) + + def visit_keyword(self, node): + """return an astroid.Keyword node as string""" + if node.arg is None: + return "**%s" % node.value.accept(self) + return "%s=%s" % (node.arg, node.value.accept(self)) + + def visit_lambda(self, node): + """return an astroid.Lambda node as string""" + args = node.args.accept(self) + body = node.body.accept(self) + if args: + return "lambda %s: %s" % (args, body) + + return "lambda: %s" % body + + def visit_list(self, node): + """return an astroid.List node as string""" + return "[%s]" % ", ".join(child.accept(self) for child in node.elts) + + def visit_listcomp(self, node): + """return an astroid.ListComp node as string""" + return "[%s %s]" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_module(self, node): + """return an astroid.Module node as string""" + docs = '"""%s"""\n\n' % node.doc if node.doc else "" + return docs + "\n".join(n.accept(self) for n in node.body) + "\n\n" + + def visit_name(self, node): + """return an astroid.Name node as string""" + return node.name + + def visit_pass(self, node): + """return an astroid.Pass node as string""" + return "pass" + + def visit_print(self, node): + """return an astroid.Print node as string""" + nodes = ", ".join(n.accept(self) for n in node.values) + if not node.nl: + nodes = "%s," % nodes + if node.dest: + return "print >> %s, %s" % (node.dest.accept(self), nodes) + return "print %s" % nodes + + def visit_raise(self, node): + """return an astroid.Raise node as string""" + if node.exc: + if node.inst: + if node.tback: + return "raise %s, %s, %s" % ( + node.exc.accept(self), + node.inst.accept(self), + node.tback.accept(self), + ) + return "raise %s, %s" % (node.exc.accept(self), node.inst.accept(self)) + return "raise %s" % node.exc.accept(self) + return "raise" + + def visit_return(self, node): + """return an astroid.Return node as string""" + if node.is_tuple_return() and len(node.value.elts) > 1: + elts = [child.accept(self) for child in node.value.elts] + return "return %s" % ", ".join(elts) + + if node.value: + return "return %s" % node.value.accept(self) + + return "return" + + def visit_index(self, node): + """return an astroid.Index node as string""" + return node.value.accept(self) + + def visit_set(self, node): + """return an astroid.Set node as string""" + return "{%s}" % ", ".join(child.accept(self) for child in node.elts) + + def visit_setcomp(self, node): + """return an astroid.SetComp node as string""" + return "{%s %s}" % ( + node.elt.accept(self), + " ".join(n.accept(self) for n in node.generators), + ) + + def visit_slice(self, node): + """return an astroid.Slice node as string""" + lower = node.lower.accept(self) if node.lower else "" + upper = node.upper.accept(self) if node.upper else "" + step = node.step.accept(self) if node.step else "" + if step: + return "%s:%s:%s" % (lower, upper, step) + return "%s:%s" % (lower, upper) + + def visit_subscript(self, node): + """return an astroid.Subscript node as string""" + idx = node.slice + if idx.__class__.__name__.lower() == "index": + idx = idx.value + idxstr = idx.accept(self) + if idx.__class__.__name__.lower() == "tuple" and idx.elts: + # Remove parenthesis in tuple and extended slice. + # a[(::1, 1:)] is not valid syntax. + idxstr = idxstr[1:-1] + return "%s[%s]" % (self._precedence_parens(node, node.value), idxstr) + + def visit_tryexcept(self, node): + """return an astroid.TryExcept node as string""" + trys = ["try:\n%s" % self._stmt_list(node.body)] + for handler in node.handlers: + trys.append(handler.accept(self)) + if node.orelse: + trys.append("else:\n%s" % self._stmt_list(node.orelse)) + return "\n".join(trys) + + def visit_tryfinally(self, node): + """return an astroid.TryFinally node as string""" + return "try:\n%s\nfinally:\n%s" % ( + self._stmt_list(node.body), + self._stmt_list(node.finalbody), + ) + + def visit_tuple(self, node): + """return an astroid.Tuple node as string""" + if len(node.elts) == 1: + return "(%s, )" % node.elts[0].accept(self) + return "(%s)" % ", ".join(child.accept(self) for child in node.elts) + + def visit_unaryop(self, node): + """return an astroid.UnaryOp node as string""" + if node.op == "not": + operator = "not " + else: + operator = node.op + return "%s%s" % (operator, self._precedence_parens(node, node.operand)) + + def visit_while(self, node): + """return an astroid.While node as string""" + whiles = "while %s:\n%s" % (node.test.accept(self), self._stmt_list(node.body)) + if node.orelse: + whiles = "%s\nelse:\n%s" % (whiles, self._stmt_list(node.orelse)) + return whiles + + def visit_with(self, node): # 'with' without 'as' is possible + """return an astroid.With node as string""" + items = ", ".join( + ("%s" % expr.accept(self)) + (vars and " as %s" % (vars.accept(self)) or "") + for expr, vars in node.items + ) + return "with %s:\n%s" % (items, self._stmt_list(node.body)) + + def visit_yield(self, node): + """yield an ast.Yield node as string""" + yi_val = (" " + node.value.accept(self)) if node.value else "" + expr = "yield" + yi_val + if node.parent.is_statement: + return expr + + return "(%s)" % (expr,) + + def visit_starred(self, node): + """return Starred node as string""" + return "*" + node.value.accept(self) + + # These aren't for real AST nodes, but for inference objects. + + def visit_frozenset(self, node): + return node.parent.accept(self) + + def visit_super(self, node): + return node.parent.accept(self) + + def visit_uninferable(self, node): + return str(node) + + +class AsStringVisitor3(AsStringVisitor): + """AsStringVisitor3 overwrites some AsStringVisitor methods""" + + def visit_excepthandler(self, node): + if node.type: + if node.name: + excs = "except %s as %s" % ( + node.type.accept(self), + node.name.accept(self), + ) + else: + excs = "except %s" % node.type.accept(self) + else: + excs = "except" + return "%s:\n%s" % (excs, self._stmt_list(node.body)) + + def visit_nonlocal(self, node): + """return an astroid.Nonlocal node as string""" + return "nonlocal %s" % ", ".join(node.names) + + def visit_raise(self, node): + """return an astroid.Raise node as string""" + if node.exc: + if node.cause: + return "raise %s from %s" % ( + node.exc.accept(self), + node.cause.accept(self), + ) + return "raise %s" % node.exc.accept(self) + return "raise" + + def visit_yieldfrom(self, node): + """ Return an astroid.YieldFrom node as string. """ + yi_val = (" " + node.value.accept(self)) if node.value else "" + expr = "yield from" + yi_val + if node.parent.is_statement: + return expr + + return "(%s)" % (expr,) + + def visit_asyncfunctiondef(self, node): + function = super(AsStringVisitor3, self).visit_functiondef(node) + return "async " + function.strip() + + def visit_await(self, node): + return "await %s" % node.value.accept(self) + + def visit_asyncwith(self, node): + return "async %s" % self.visit_with(node) + + def visit_asyncfor(self, node): + return "async %s" % self.visit_for(node) + + def visit_joinedstr(self, node): + # Special treatment for constants, + # as we want to join literals not reprs + string = "".join( + value.value if type(value).__name__ == "Const" else value.accept(self) + for value in node.values + ) + return "f'%s'" % string + + def visit_formattedvalue(self, node): + return "{%s}" % node.value.accept(self) + + def visit_comprehension(self, node): + """return an astroid.Comprehension node as string""" + return "%s%s" % ( + "async " if node.is_async else "", + super(AsStringVisitor3, self).visit_comprehension(node), + ) + + +def _import_string(names): + """return a list of (name, asname) formatted as a string""" + _names = [] + for name, asname in names: + if asname is not None: + _names.append("%s as %s" % (name, asname)) + else: + _names.append(name) + return ", ".join(_names) + + +if sys.version_info >= (3, 0): + AsStringVisitor = AsStringVisitor3 + +# This sets the default indent to 4 spaces. +to_code = AsStringVisitor(" ") diff --git a/basic python programmes/venv/Lib/site-packages/astroid/bases.py b/basic python programmes/venv/Lib/site-packages/astroid/bases.py new file mode 100644 index 0000000..318ddb5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/bases.py @@ -0,0 +1,545 @@ +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Daniel Colascione + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module contains base classes and functions for the nodes and some +inference utils. +""" + +import builtins +import collections +import sys + +from astroid import context as contextmod +from astroid import exceptions +from astroid import util + +objectmodel = util.lazy_import("interpreter.objectmodel") +helpers = util.lazy_import("helpers") +BUILTINS = builtins.__name__ +manager = util.lazy_import("manager") +MANAGER = manager.AstroidManager() + +if sys.version_info >= (3, 0): + # TODO: check if needs special treatment + BUILTINS = "builtins" + BOOL_SPECIAL_METHOD = "__bool__" +else: + BUILTINS = "__builtin__" + BOOL_SPECIAL_METHOD = "__nonzero__" +PROPERTIES = {BUILTINS + ".property", "abc.abstractproperty"} +# List of possible property names. We use this list in order +# to see if a method is a property or not. This should be +# pretty reliable and fast, the alternative being to check each +# decorator to see if its a real property-like descriptor, which +# can be too complicated. +# Also, these aren't qualified, because each project can +# define them, we shouldn't expect to know every possible +# property-like decorator! +POSSIBLE_PROPERTIES = { + "cached_property", + "cachedproperty", + "lazyproperty", + "lazy_property", + "reify", + "lazyattribute", + "lazy_attribute", + "LazyProperty", + "lazy", + "cache_readonly", +} + + +def _is_property(meth): + if PROPERTIES.intersection(meth.decoratornames()): + return True + stripped = { + name.split(".")[-1] + for name in meth.decoratornames() + if name is not util.Uninferable + } + if any(name in stripped for name in POSSIBLE_PROPERTIES): + return True + + # Lookup for subclasses of *property* + if not meth.decorators: + return False + for decorator in meth.decorators.nodes or (): + inferred = helpers.safe_infer(decorator) + if inferred is None or inferred is util.Uninferable: + continue + if inferred.__class__.__name__ == "ClassDef": + for base_class in inferred.bases: + module, _ = base_class.lookup(base_class.name) + if module.name == BUILTINS and base_class.name == "property": + return True + + return False + + +class Proxy: + """a simple proxy object + + Note: + + Subclasses of this object will need a custom __getattr__ + if new instance attributes are created. See the Const class + """ + + _proxied = None # proxied object may be set by class or by instance + + def __init__(self, proxied=None): + if proxied is not None: + self._proxied = proxied + + def __getattr__(self, name): + if name == "_proxied": + return getattr(self.__class__, "_proxied") + if name in self.__dict__: + return self.__dict__[name] + return getattr(self._proxied, name) + + def infer(self, context=None): + yield self + + +def _infer_stmts(stmts, context, frame=None): + """Return an iterator on statements inferred by each statement in *stmts*.""" + inferred = False + if context is not None: + name = context.lookupname + context = context.clone() + else: + name = None + context = contextmod.InferenceContext() + + for stmt in stmts: + if stmt is util.Uninferable: + yield stmt + inferred = True + continue + context.lookupname = stmt._infer_name(frame, name) + try: + for inferred in stmt.infer(context=context): + yield inferred + inferred = True + except exceptions.NameInferenceError: + continue + except exceptions.InferenceError: + yield util.Uninferable + inferred = True + if not inferred: + raise exceptions.InferenceError( + "Inference failed for all members of {stmts!r}.", + stmts=stmts, + frame=frame, + context=context, + ) + + +def _infer_method_result_truth(instance, method_name, context): + # Get the method from the instance and try to infer + # its return's truth value. + meth = next(instance.igetattr(method_name, context=context), None) + if meth and hasattr(meth, "infer_call_result"): + if not meth.callable(): + return util.Uninferable + try: + for value in meth.infer_call_result(instance, context=context): + if value is util.Uninferable: + return value + + inferred = next(value.infer(context=context)) + return inferred.bool_value() + except exceptions.InferenceError: + pass + return util.Uninferable + + +class BaseInstance(Proxy): + """An instance base class, which provides lookup methods for potential instances.""" + + special_attributes = None + + def display_type(self): + return "Instance of" + + def getattr(self, name, context=None, lookupclass=True): + try: + values = self._proxied.instance_attr(name, context) + except exceptions.AttributeInferenceError as exc: + if self.special_attributes and name in self.special_attributes: + return [self.special_attributes.lookup(name)] + + if lookupclass: + # Class attributes not available through the instance + # unless they are explicitly defined. + return self._proxied.getattr(name, context, class_context=False) + + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) from exc + # since we've no context information, return matching class members as + # well + if lookupclass: + try: + return values + self._proxied.getattr( + name, context, class_context=False + ) + except exceptions.AttributeInferenceError: + pass + return values + + def igetattr(self, name, context=None): + """inferred getattr""" + if not context: + context = contextmod.InferenceContext() + try: + # avoid recursively inferring the same attr on the same class + if context.push((self._proxied, name)): + return + + # XXX frame should be self._proxied, or not ? + get_attr = self.getattr(name, context, lookupclass=False) + yield from _infer_stmts( + self._wrap_attr(get_attr, context), context, frame=self + ) + except exceptions.AttributeInferenceError as error: + try: + # fallback to class.igetattr since it has some logic to handle + # descriptors + # But only if the _proxied is the Class. + if self._proxied.__class__.__name__ != "ClassDef": + raise exceptions.InferenceError(**vars(error)) from error + attrs = self._proxied.igetattr(name, context, class_context=False) + yield from self._wrap_attr(attrs, context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError(**vars(error)) from error + + def _wrap_attr(self, attrs, context=None): + """wrap bound methods of attrs in a InstanceMethod proxies""" + for attr in attrs: + if isinstance(attr, UnboundMethod): + if _is_property(attr): + yield from attr.infer_call_result(self, context) + else: + yield BoundMethod(attr, self) + elif hasattr(attr, "name") and attr.name == "": + # This is a lambda function defined at class level, + # since its scope is the underlying _proxied class. + # Unfortunately, we can't do an isinstance check here, + # because of the circular dependency between astroid.bases + # and astroid.scoped_nodes. + if attr.statement().scope() == self._proxied: + if attr.args.args and attr.args.args[0].name == "self": + yield BoundMethod(attr, self) + continue + yield attr + else: + yield attr + + def infer_call_result(self, caller, context=None): + """infer what a class instance is returning when called""" + context = contextmod.bind_context_to_node(context, self) + inferred = False + for node in self._proxied.igetattr("__call__", context): + if node is util.Uninferable or not node.callable(): + continue + for res in node.infer_call_result(caller, context): + inferred = True + yield res + if not inferred: + raise exceptions.InferenceError(node=self, caller=caller, context=context) + + +class Instance(BaseInstance): + """A special node representing a class instance.""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.InstanceModel()) + + def __repr__(self): + return "" % ( + self._proxied.root().name, + self._proxied.name, + id(self), + ) + + def __str__(self): + return "Instance of %s.%s" % (self._proxied.root().name, self._proxied.name) + + def callable(self): + try: + self._proxied.getattr("__call__", class_context=False) + return True + except exceptions.AttributeInferenceError: + return False + + def pytype(self): + return self._proxied.qname() + + def display_type(self): + return "Instance of" + + def bool_value(self): + """Infer the truth value for an Instance + + The truth value of an instance is determined by these conditions: + + * if it implements __bool__ on Python 3 or __nonzero__ + on Python 2, then its bool value will be determined by + calling this special method and checking its result. + * when this method is not defined, __len__() is called, if it + is defined, and the object is considered true if its result is + nonzero. If a class defines neither __len__() nor __bool__(), + all its instances are considered true. + """ + context = contextmod.InferenceContext() + context.callcontext = contextmod.CallContext(args=[]) + context.boundnode = self + + try: + result = _infer_method_result_truth(self, BOOL_SPECIAL_METHOD, context) + except (exceptions.InferenceError, exceptions.AttributeInferenceError): + # Fallback to __len__. + try: + result = _infer_method_result_truth(self, "__len__", context) + except (exceptions.AttributeInferenceError, exceptions.InferenceError): + return True + return result + + # This is set in inference.py. + def getitem(self, index, context=None): + pass + + +class UnboundMethod(Proxy): + """a special node representing a method not bound to an instance""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.UnboundMethodModel()) + + def __repr__(self): + frame = self._proxied.parent.frame() + return "<%s %s of %s at 0x%s" % ( + self.__class__.__name__, + self._proxied.name, + frame.qname(), + id(self), + ) + + def implicit_parameters(self): + return 0 + + def is_bound(self): + return False + + def getattr(self, name, context=None): + if name in self.special_attributes: + return [self.special_attributes.lookup(name)] + return self._proxied.getattr(name, context) + + def igetattr(self, name, context=None): + if name in self.special_attributes: + return iter((self.special_attributes.lookup(name),)) + return self._proxied.igetattr(name, context) + + def infer_call_result(self, caller, context): + """ + The boundnode of the regular context with a function called + on ``object.__new__`` will be of type ``object``, + which is incorrect for the argument in general. + If no context is given the ``object.__new__`` call argument will + correctly inferred except when inside a call that requires + the additional context (such as a classmethod) of the boundnode + to determine which class the method was called from + """ + + # If we're unbound method __new__ of builtin object, the result is an + # instance of the class given as first argument. + if ( + self._proxied.name == "__new__" + and self._proxied.parent.frame().qname() == "%s.object" % BUILTINS + ): + if caller.args: + node_context = context.extra_context.get(caller.args[0]) + infer = caller.args[0].infer(context=node_context) + else: + infer = [] + return (Instance(x) if x is not util.Uninferable else x for x in infer) + return self._proxied.infer_call_result(caller, context) + + def bool_value(self): + return True + + +class BoundMethod(UnboundMethod): + """a special node representing a method bound to an instance""" + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.BoundMethodModel()) + + def __init__(self, proxy, bound): + UnboundMethod.__init__(self, proxy) + self.bound = bound + + def implicit_parameters(self): + return 1 + + def is_bound(self): + return True + + def _infer_type_new_call(self, caller, context): + """Try to infer what type.__new__(mcs, name, bases, attrs) returns. + + In order for such call to be valid, the metaclass needs to be + a subtype of ``type``, the name needs to be a string, the bases + needs to be a tuple of classes + """ + from astroid import node_classes + + # Verify the metaclass + mcs = next(caller.args[0].infer(context=context)) + if mcs.__class__.__name__ != "ClassDef": + # Not a valid first argument. + return None + if not mcs.is_subtype_of("%s.type" % BUILTINS): + # Not a valid metaclass. + return None + + # Verify the name + name = next(caller.args[1].infer(context=context)) + if name.__class__.__name__ != "Const": + # Not a valid name, needs to be a const. + return None + if not isinstance(name.value, str): + # Needs to be a string. + return None + + # Verify the bases + bases = next(caller.args[2].infer(context=context)) + if bases.__class__.__name__ != "Tuple": + # Needs to be a tuple. + return None + inferred_bases = [next(elt.infer(context=context)) for elt in bases.elts] + if any(base.__class__.__name__ != "ClassDef" for base in inferred_bases): + # All the bases needs to be Classes + return None + + # Verify the attributes. + attrs = next(caller.args[3].infer(context=context)) + if attrs.__class__.__name__ != "Dict": + # Needs to be a dictionary. + return None + cls_locals = collections.defaultdict(list) + for key, value in attrs.items: + key = next(key.infer(context=context)) + value = next(value.infer(context=context)) + # Ignore non string keys + if key.__class__.__name__ == "Const" and isinstance(key.value, str): + cls_locals[key.value].append(value) + + # Build the class from now. + cls = mcs.__class__( + name=name.value, + lineno=caller.lineno, + col_offset=caller.col_offset, + parent=caller, + ) + empty = node_classes.Pass() + cls.postinit( + bases=bases.elts, + body=[empty], + decorators=[], + newstyle=True, + metaclass=mcs, + keywords=[], + ) + cls.locals = cls_locals + return cls + + def infer_call_result(self, caller, context=None): + context = contextmod.bind_context_to_node(context, self.bound) + if ( + self.bound.__class__.__name__ == "ClassDef" + and self.bound.name == "type" + and self.name == "__new__" + and len(caller.args) == 4 + ): + # Check if we have a ``type.__new__(mcs, name, bases, attrs)`` call. + new_cls = self._infer_type_new_call(caller, context) + if new_cls: + return iter((new_cls,)) + + return super(BoundMethod, self).infer_call_result(caller, context) + + def bool_value(self): + return True + + +class Generator(BaseInstance): + """a special node representing a generator. + + Proxied class is set once for all in raw_building. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.GeneratorModel()) + + # pylint: disable=super-init-not-called + def __init__(self, parent=None): + self.parent = parent + + def callable(self): + return False + + def pytype(self): + return "%s.generator" % BUILTINS + + def display_type(self): + return "Generator" + + def bool_value(self): + return True + + def __repr__(self): + return "" % ( + self._proxied.name, + self.lineno, + id(self), + ) + + def __str__(self): + return "Generator(%s)" % (self._proxied.name) + + +class AsyncGenerator(Generator): + """Special node representing an async generator""" + + def pytype(self): + return "%s.async_generator" % BUILTINS + + def display_type(self): + return "AsyncGenerator" + + def __repr__(self): + return "" % ( + self._proxied.name, + self.lineno, + id(self), + ) + + def __str__(self): + return "AsyncGenerator(%s)" % (self._proxied.name) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-37.pyc new file mode 100644 index 0000000..473b2ec Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_argparse.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_attrs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_attrs.cpython-37.pyc new file mode 100644 index 0000000..8a5e3e2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_attrs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-37.pyc new file mode 100644 index 0000000..f7110e3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_builtin_inference.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_collections.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_collections.cpython-37.pyc new file mode 100644 index 0000000..9f6475c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_collections.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_curses.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_curses.cpython-37.pyc new file mode 100644 index 0000000..89f1579 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_curses.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-37.pyc new file mode 100644 index 0000000..e305bc0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_dateutil.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc new file mode 100644 index 0000000..de0b1c9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_fstrings.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_functools.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_functools.cpython-37.pyc new file mode 100644 index 0000000..fbb970c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_functools.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_gi.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_gi.cpython-37.pyc new file mode 100644 index 0000000..a198b13 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_gi.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc new file mode 100644 index 0000000..de9ad58 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_hashlib.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_io.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_io.cpython-37.pyc new file mode 100644 index 0000000..e879d1b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_io.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-37.pyc new file mode 100644 index 0000000..235bea9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_mechanize.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc new file mode 100644 index 0000000..5f68a42 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_multiprocessing.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-37.pyc new file mode 100644 index 0000000..7eddd1a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_namedtuple_enum.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_nose.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_nose.cpython-37.pyc new file mode 100644 index 0000000..91dc680 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_nose.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_numpy.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_numpy.cpython-37.pyc new file mode 100644 index 0000000..a708632 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_numpy.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc new file mode 100644 index 0000000..dde3db2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_pkg_resources.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_pytest.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_pytest.cpython-37.pyc new file mode 100644 index 0000000..1207cf3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_pytest.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_qt.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_qt.cpython-37.pyc new file mode 100644 index 0000000..131753f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_qt.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_random.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_random.cpython-37.pyc new file mode 100644 index 0000000..9f35767 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_random.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_re.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_re.cpython-37.pyc new file mode 100644 index 0000000..604246f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_re.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_six.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_six.cpython-37.pyc new file mode 100644 index 0000000..29daef7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_six.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-37.pyc new file mode 100644 index 0000000..2947d8a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_ssl.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-37.pyc new file mode 100644 index 0000000..cd7031a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_subprocess.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_threading.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_threading.cpython-37.pyc new file mode 100644 index 0000000..3a55768 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_threading.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_typing.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_typing.cpython-37.pyc new file mode 100644 index 0000000..3401a84 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_typing.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-37.pyc new file mode 100644 index 0000000..d93ed26 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/brain/__pycache__/brain_uuid.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_argparse.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_argparse.py new file mode 100644 index 0000000..d489911 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_argparse.py @@ -0,0 +1,33 @@ +from astroid import MANAGER, arguments, nodes, inference_tip, UseInferenceDefault + + +def infer_namespace(node, context=None): + callsite = arguments.CallSite.from_call(node) + if not callsite.keyword_arguments: + # Cannot make sense of it. + raise UseInferenceDefault() + + class_node = nodes.ClassDef("Namespace", "docstring") + class_node.parent = node.parent + for attr in set(callsite.keyword_arguments): + fake_node = nodes.EmptyNode() + fake_node.parent = class_node + fake_node.attrname = attr + class_node.instance_attrs[attr] = [fake_node] + return iter((class_node.instantiate_class(),)) + + +def _looks_like_namespace(node): + func = node.func + if isinstance(func, nodes.Attribute): + return ( + func.attrname == "Namespace" + and isinstance(func.expr, nodes.Name) + and func.expr.name == "argparse" + ) + return False + + +MANAGER.register_transform( + nodes.Call, inference_tip(infer_namespace), _looks_like_namespace +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_attrs.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_attrs.py new file mode 100644 index 0000000..74d1aa3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_attrs.py @@ -0,0 +1,60 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +""" +Astroid hook for the attrs library + +Without this hook pylint reports unsupported-assignment-operation +for atrrs classes +""" + +import astroid +from astroid import MANAGER + + +ATTR_IB = "attr.ib" + + +def is_decorated_with_attrs( + node, decorator_names=("attr.s", "attr.attrs", "attr.attributes") +): + """Return True if a decorated node has + an attr decorator applied.""" + if not node.decorators: + return False + for decorator_attribute in node.decorators.nodes: + if isinstance(decorator_attribute, astroid.Call): # decorator with arguments + decorator_attribute = decorator_attribute.func + if decorator_attribute.as_string() in decorator_names: + return True + return False + + +def attr_attributes_transform(node): + """Given that the ClassNode has an attr decorator, + rewrite class attributes as instance attributes + """ + # Astroid can't infer this attribute properly + # Prevents https://github.com/PyCQA/pylint/issues/1884 + node.locals["__attrs_attrs__"] = [astroid.Unknown(parent=node)] + + for cdefbodynode in node.body: + if not isinstance(cdefbodynode, astroid.Assign): + continue + if isinstance(cdefbodynode.value, astroid.Call): + if cdefbodynode.value.func.as_string() != ATTR_IB: + continue + else: + continue + for target in cdefbodynode.targets: + + rhs_node = astroid.Unknown( + lineno=cdefbodynode.lineno, + col_offset=cdefbodynode.col_offset, + parent=cdefbodynode, + ) + node.locals[target.name] = [rhs_node] + + +MANAGER.register_transform( + astroid.ClassDef, attr_attributes_transform, is_decorated_with_attrs +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_builtin_inference.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_builtin_inference.py new file mode 100644 index 0000000..2655095 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_builtin_inference.py @@ -0,0 +1,823 @@ +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014-2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Rene Zhang +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for various builtins.""" + +from functools import partial +from textwrap import dedent + +import six +from astroid import ( + MANAGER, + Instance, + UseInferenceDefault, + AttributeInferenceError, + inference_tip, + InferenceError, + NameInferenceError, + AstroidTypeError, + MroError, +) +from astroid import arguments +from astroid.builder import AstroidBuilder +from astroid import helpers +from astroid import nodes +from astroid import objects +from astroid import scoped_nodes +from astroid import util + + +OBJECT_DUNDER_NEW = "object.__new__" + + +def _extend_str(class_node, rvalue): + """function to extend builtin str/unicode class""" + code = dedent( + """ + class whatever(object): + def join(self, iterable): + return {rvalue} + def replace(self, old, new, count=None): + return {rvalue} + def format(self, *args, **kwargs): + return {rvalue} + def encode(self, encoding='ascii', errors=None): + return '' + def decode(self, encoding='ascii', errors=None): + return u'' + def capitalize(self): + return {rvalue} + def title(self): + return {rvalue} + def lower(self): + return {rvalue} + def upper(self): + return {rvalue} + def swapcase(self): + return {rvalue} + def index(self, sub, start=None, end=None): + return 0 + def find(self, sub, start=None, end=None): + return 0 + def count(self, sub, start=None, end=None): + return 0 + def strip(self, chars=None): + return {rvalue} + def lstrip(self, chars=None): + return {rvalue} + def rstrip(self, chars=None): + return {rvalue} + def rjust(self, width, fillchar=None): + return {rvalue} + def center(self, width, fillchar=None): + return {rvalue} + def ljust(self, width, fillchar=None): + return {rvalue} + """ + ) + code = code.format(rvalue=rvalue) + fake = AstroidBuilder(MANAGER).string_build(code)["whatever"] + for method in fake.mymethods(): + method.parent = class_node + method.lineno = None + method.col_offset = None + if "__class__" in method.locals: + method.locals["__class__"] = [class_node] + class_node.locals[method.name] = [method] + method.parent = class_node + + +def _extend_builtins(class_transforms): + from astroid.bases import BUILTINS + + builtin_ast = MANAGER.astroid_cache[BUILTINS] + for class_name, transform in class_transforms.items(): + transform(builtin_ast[class_name]) + + +_extend_builtins( + { + "bytes": partial(_extend_str, rvalue="b''"), + "str": partial(_extend_str, rvalue="''"), + } +) + + +def _builtin_filter_predicate(node, builtin_name): + if isinstance(node.func, nodes.Name) and node.func.name == builtin_name: + return True + if isinstance(node.func, nodes.Attribute): + return ( + node.func.attrname == "fromkeys" + and isinstance(node.func.expr, nodes.Name) + and node.func.expr.name == "dict" + ) + return False + + +def register_builtin_transform(transform, builtin_name): + """Register a new transform function for the given *builtin_name*. + + The transform function must accept two parameters, a node and + an optional context. + """ + + def _transform_wrapper(node, context=None): + result = transform(node, context=context) + if result: + if not result.parent: + # Let the transformation function determine + # the parent for its result. Otherwise, + # we set it to be the node we transformed from. + result.parent = node + + if result.lineno is None: + result.lineno = node.lineno + if result.col_offset is None: + result.col_offset = node.col_offset + return iter([result]) + + MANAGER.register_transform( + nodes.Call, + inference_tip(_transform_wrapper), + partial(_builtin_filter_predicate, builtin_name=builtin_name), + ) + + +def _generic_inference(node, context, node_type, transform): + args = node.args + if not args: + return node_type() + if len(node.args) > 1: + raise UseInferenceDefault() + + arg, = args + transformed = transform(arg) + if not transformed: + try: + inferred = next(arg.infer(context=context)) + except (InferenceError, StopIteration): + raise UseInferenceDefault() + if inferred is util.Uninferable: + raise UseInferenceDefault() + transformed = transform(inferred) + if not transformed or transformed is util.Uninferable: + raise UseInferenceDefault() + return transformed + + +def _generic_transform(arg, klass, iterables, build_elts): + if isinstance(arg, klass): + return arg + elif isinstance(arg, iterables): + if not all(isinstance(elt, nodes.Const) for elt in arg.elts): + raise UseInferenceDefault() + elts = [elt.value for elt in arg.elts] + elif isinstance(arg, nodes.Dict): + if not all(isinstance(elt[0], nodes.Const) for elt in arg.items): + raise UseInferenceDefault() + elts = [item[0].value for item in arg.items] + elif isinstance(arg, nodes.Const) and isinstance( + arg.value, (six.string_types, six.binary_type) + ): + elts = arg.value + else: + return + return klass.from_constants(elts=build_elts(elts)) + + +def _infer_builtin(node, context, klass=None, iterables=None, build_elts=None): + transform_func = partial( + _generic_transform, klass=klass, iterables=iterables, build_elts=build_elts + ) + + return _generic_inference(node, context, klass, transform_func) + + +# pylint: disable=invalid-name +infer_tuple = partial( + _infer_builtin, + klass=nodes.Tuple, + iterables=( + nodes.List, + nodes.Set, + objects.FrozenSet, + objects.DictItems, + objects.DictKeys, + objects.DictValues, + ), + build_elts=tuple, +) + +infer_list = partial( + _infer_builtin, + klass=nodes.List, + iterables=( + nodes.Tuple, + nodes.Set, + objects.FrozenSet, + objects.DictItems, + objects.DictKeys, + objects.DictValues, + ), + build_elts=list, +) + +infer_set = partial( + _infer_builtin, + klass=nodes.Set, + iterables=(nodes.List, nodes.Tuple, objects.FrozenSet, objects.DictKeys), + build_elts=set, +) + +infer_frozenset = partial( + _infer_builtin, + klass=objects.FrozenSet, + iterables=(nodes.List, nodes.Tuple, nodes.Set, objects.FrozenSet, objects.DictKeys), + build_elts=frozenset, +) + + +def _get_elts(arg, context): + is_iterable = lambda n: isinstance(n, (nodes.List, nodes.Tuple, nodes.Set)) + try: + inferred = next(arg.infer(context)) + except (InferenceError, NameInferenceError): + raise UseInferenceDefault() + if isinstance(inferred, nodes.Dict): + items = inferred.items + elif is_iterable(inferred): + items = [] + for elt in inferred.elts: + # If an item is not a pair of two items, + # then fallback to the default inference. + # Also, take in consideration only hashable items, + # tuples and consts. We are choosing Names as well. + if not is_iterable(elt): + raise UseInferenceDefault() + if len(elt.elts) != 2: + raise UseInferenceDefault() + if not isinstance(elt.elts[0], (nodes.Tuple, nodes.Const, nodes.Name)): + raise UseInferenceDefault() + items.append(tuple(elt.elts)) + else: + raise UseInferenceDefault() + return items + + +def infer_dict(node, context=None): + """Try to infer a dict call to a Dict node. + + The function treats the following cases: + + * dict() + * dict(mapping) + * dict(iterable) + * dict(iterable, **kwargs) + * dict(mapping, **kwargs) + * dict(**kwargs) + + If a case can't be inferred, we'll fallback to default inference. + """ + call = arguments.CallSite.from_call(node) + if call.has_invalid_arguments() or call.has_invalid_keywords(): + raise UseInferenceDefault + + args = call.positional_arguments + kwargs = list(call.keyword_arguments.items()) + + if not args and not kwargs: + # dict() + return nodes.Dict() + elif kwargs and not args: + # dict(a=1, b=2, c=4) + items = [(nodes.Const(key), value) for key, value in kwargs] + elif len(args) == 1 and kwargs: + # dict(some_iterable, b=2, c=4) + elts = _get_elts(args[0], context) + keys = [(nodes.Const(key), value) for key, value in kwargs] + items = elts + keys + elif len(args) == 1: + items = _get_elts(args[0], context) + else: + raise UseInferenceDefault() + + value = nodes.Dict( + col_offset=node.col_offset, lineno=node.lineno, parent=node.parent + ) + value.postinit(items) + return value + + +def infer_super(node, context=None): + """Understand super calls. + + There are some restrictions for what can be understood: + + * unbounded super (one argument form) is not understood. + + * if the super call is not inside a function (classmethod or method), + then the default inference will be used. + + * if the super arguments can't be inferred, the default inference + will be used. + """ + if len(node.args) == 1: + # Ignore unbounded super. + raise UseInferenceDefault + + scope = node.scope() + if not isinstance(scope, nodes.FunctionDef): + # Ignore non-method uses of super. + raise UseInferenceDefault + if scope.type not in ("classmethod", "method"): + # Not interested in staticmethods. + raise UseInferenceDefault + + cls = scoped_nodes.get_wrapping_class(scope) + if not len(node.args): + mro_pointer = cls + # In we are in a classmethod, the interpreter will fill + # automatically the class as the second argument, not an instance. + if scope.type == "classmethod": + mro_type = cls + else: + mro_type = cls.instantiate_class() + else: + try: + mro_pointer = next(node.args[0].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + try: + mro_type = next(node.args[1].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + if mro_pointer is util.Uninferable or mro_type is util.Uninferable: + # No way we could understand this. + raise UseInferenceDefault + + super_obj = objects.Super( + mro_pointer=mro_pointer, mro_type=mro_type, self_class=cls, scope=scope + ) + super_obj.parent = node + return super_obj + + +def _infer_getattr_args(node, context): + if len(node.args) not in (2, 3): + # Not a valid getattr call. + raise UseInferenceDefault + + try: + obj = next(node.args[0].infer(context=context)) + attr = next(node.args[1].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + if obj is util.Uninferable or attr is util.Uninferable: + # If one of the arguments is something we can't infer, + # then also make the result of the getattr call something + # which is unknown. + return util.Uninferable, util.Uninferable + + is_string = isinstance(attr, nodes.Const) and isinstance( + attr.value, six.string_types + ) + if not is_string: + raise UseInferenceDefault + + return obj, attr.value + + +def infer_getattr(node, context=None): + """Understand getattr calls + + If one of the arguments is an Uninferable object, then the + result will be an Uninferable object. Otherwise, the normal attribute + lookup will be done. + """ + obj, attr = _infer_getattr_args(node, context) + if ( + obj is util.Uninferable + or attr is util.Uninferable + or not hasattr(obj, "igetattr") + ): + return util.Uninferable + + try: + return next(obj.igetattr(attr, context=context)) + except (StopIteration, InferenceError, AttributeInferenceError): + if len(node.args) == 3: + # Try to infer the default and return it instead. + try: + return next(node.args[2].infer(context=context)) + except InferenceError: + raise UseInferenceDefault + + raise UseInferenceDefault + + +def infer_hasattr(node, context=None): + """Understand hasattr calls + + This always guarantees three possible outcomes for calling + hasattr: Const(False) when we are sure that the object + doesn't have the intended attribute, Const(True) when + we know that the object has the attribute and Uninferable + when we are unsure of the outcome of the function call. + """ + try: + obj, attr = _infer_getattr_args(node, context) + if ( + obj is util.Uninferable + or attr is util.Uninferable + or not hasattr(obj, "getattr") + ): + return util.Uninferable + obj.getattr(attr, context=context) + except UseInferenceDefault: + # Can't infer something from this function call. + return util.Uninferable + except AttributeInferenceError: + # Doesn't have it. + return nodes.Const(False) + return nodes.Const(True) + + +def infer_callable(node, context=None): + """Understand callable calls + + This follows Python's semantics, where an object + is callable if it provides an attribute __call__, + even though that attribute is something which can't be + called. + """ + if len(node.args) != 1: + # Invalid callable call. + raise UseInferenceDefault + + argument = node.args[0] + try: + inferred = next(argument.infer(context=context)) + except InferenceError: + return util.Uninferable + if inferred is util.Uninferable: + return util.Uninferable + return nodes.Const(inferred.callable()) + + +def infer_bool(node, context=None): + """Understand bool calls.""" + if len(node.args) > 1: + # Invalid bool call. + raise UseInferenceDefault + + if not node.args: + return nodes.Const(False) + + argument = node.args[0] + try: + inferred = next(argument.infer(context=context)) + except InferenceError: + return util.Uninferable + if inferred is util.Uninferable: + return util.Uninferable + + bool_value = inferred.bool_value() + if bool_value is util.Uninferable: + return util.Uninferable + return nodes.Const(bool_value) + + +def infer_type(node, context=None): + """Understand the one-argument form of *type*.""" + if len(node.args) != 1: + raise UseInferenceDefault + + return helpers.object_type(node.args[0], context) + + +def infer_slice(node, context=None): + """Understand `slice` calls.""" + args = node.args + if not 0 < len(args) <= 3: + raise UseInferenceDefault + + args = list(map(helpers.safe_infer, args)) + for arg in args: + if not arg or arg is util.Uninferable: + raise UseInferenceDefault + if not isinstance(arg, nodes.Const): + raise UseInferenceDefault + if not isinstance(arg.value, (type(None), int)): + raise UseInferenceDefault + + if len(args) < 3: + # Make sure we have 3 arguments. + args.extend([None] * (3 - len(args))) + + slice_node = nodes.Slice( + lineno=node.lineno, col_offset=node.col_offset, parent=node.parent + ) + slice_node.postinit(*args) + return slice_node + + +def _infer_object__new__decorator(node, context=None): + # Instantiate class immediately + # since that's what @object.__new__ does + return iter((node.instantiate_class(),)) + + +def _infer_object__new__decorator_check(node): + """Predicate before inference_tip + + Check if the given ClassDef has an @object.__new__ decorator + """ + if not node.decorators: + return False + + for decorator in node.decorators.nodes: + if isinstance(decorator, nodes.Attribute): + if decorator.as_string() == OBJECT_DUNDER_NEW: + return True + return False + + +def infer_issubclass(callnode, context=None): + """Infer issubclass() calls + + :param nodes.Call callnode: an `issubclass` call + :param InferenceContext: the context for the inference + :rtype nodes.Const: Boolean Const value of the `issubclass` call + :raises UseInferenceDefault: If the node cannot be inferred + """ + call = arguments.CallSite.from_call(callnode) + if call.keyword_arguments: + # issubclass doesn't support keyword arguments + raise UseInferenceDefault("TypeError: issubclass() takes no keyword arguments") + if len(call.positional_arguments) != 2: + raise UseInferenceDefault( + "Expected two arguments, got {count}".format( + count=len(call.positional_arguments) + ) + ) + # The left hand argument is the obj to be checked + obj_node, class_or_tuple_node = call.positional_arguments + + try: + obj_type = next(obj_node.infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault from exc + if not isinstance(obj_type, nodes.ClassDef): + raise UseInferenceDefault("TypeError: arg 1 must be class") + + # The right hand argument is the class(es) that the given + # object is to be checked against. + try: + class_container = _class_or_tuple_to_container( + class_or_tuple_node, context=context + ) + except InferenceError as exc: + raise UseInferenceDefault from exc + try: + issubclass_bool = helpers.object_issubclass(obj_type, class_container, context) + except AstroidTypeError as exc: + raise UseInferenceDefault("TypeError: " + str(exc)) from exc + except MroError as exc: + raise UseInferenceDefault from exc + return nodes.Const(issubclass_bool) + + +def infer_isinstance(callnode, context=None): + """Infer isinstance calls + + :param nodes.Call callnode: an isinstance call + :param InferenceContext: context for call + (currently unused but is a common interface for inference) + :rtype nodes.Const: Boolean Const value of isinstance call + + :raises UseInferenceDefault: If the node cannot be inferred + """ + call = arguments.CallSite.from_call(callnode) + if call.keyword_arguments: + # isinstance doesn't support keyword arguments + raise UseInferenceDefault("TypeError: isinstance() takes no keyword arguments") + if len(call.positional_arguments) != 2: + raise UseInferenceDefault( + "Expected two arguments, got {count}".format( + count=len(call.positional_arguments) + ) + ) + # The left hand argument is the obj to be checked + obj_node, class_or_tuple_node = call.positional_arguments + # The right hand argument is the class(es) that the given + # obj is to be check is an instance of + try: + class_container = _class_or_tuple_to_container( + class_or_tuple_node, context=context + ) + except InferenceError: + raise UseInferenceDefault + try: + isinstance_bool = helpers.object_isinstance(obj_node, class_container, context) + except AstroidTypeError as exc: + raise UseInferenceDefault("TypeError: " + str(exc)) + except MroError as exc: + raise UseInferenceDefault from exc + if isinstance_bool is util.Uninferable: + raise UseInferenceDefault + return nodes.Const(isinstance_bool) + + +def _class_or_tuple_to_container(node, context=None): + # Move inferences results into container + # to simplify later logic + # raises InferenceError if any of the inferences fall through + node_infer = next(node.infer(context=context)) + # arg2 MUST be a type or a TUPLE of types + # for isinstance + if isinstance(node_infer, nodes.Tuple): + class_container = [ + next(node.infer(context=context)) for node in node_infer.elts + ] + class_container = [ + klass_node for klass_node in class_container if klass_node is not None + ] + else: + class_container = [node_infer] + return class_container + + +def infer_len(node, context=None): + """Infer length calls + + :param nodes.Call node: len call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const node with the inferred length, if possible + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: len() must take no keyword arguments") + if len(call.positional_arguments) != 1: + raise UseInferenceDefault( + "TypeError: len() must take exactly one argument " + "({len}) given".format(len=len(call.positional_arguments)) + ) + [argument_node] = call.positional_arguments + try: + return nodes.Const(helpers.object_len(argument_node)) + except (AstroidTypeError, InferenceError) as exc: + raise UseInferenceDefault(str(exc)) from exc + + +def infer_str(node, context=None): + """Infer str() calls + + :param nodes.Call node: str() call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const containing an empty string + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: str() must take no keyword arguments") + try: + return nodes.Const("") + except (AstroidTypeError, InferenceError) as exc: + raise UseInferenceDefault(str(exc)) from exc + + +def infer_int(node, context=None): + """Infer int() calls + + :param nodes.Call node: int() call to infer + :param context.InferenceContext: node context + :rtype nodes.Const: a Const containing the integer value of the int() call + """ + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: int() must take no keyword arguments") + + if call.positional_arguments: + try: + first_value = next(call.positional_arguments[0].infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault(str(exc)) from exc + + if first_value is util.Uninferable: + raise UseInferenceDefault + + if isinstance(first_value, nodes.Const) and isinstance( + first_value.value, (int, str) + ): + try: + actual_value = int(first_value.value) + except ValueError: + return nodes.Const(0) + return nodes.Const(actual_value) + + return nodes.Const(0) + + +def infer_dict_fromkeys(node, context=None): + """Infer dict.fromkeys + + :param nodes.Call node: dict.fromkeys() call to infer + :param context.InferenceContext: node context + :rtype nodes.Dict: + a Dictionary containing the values that astroid was able to infer. + In case the inference failed for any reason, an empty dictionary + will be inferred instead. + """ + + def _build_dict_with_elements(elements): + new_node = nodes.Dict( + col_offset=node.col_offset, lineno=node.lineno, parent=node.parent + ) + new_node.postinit(elements) + return new_node + + call = arguments.CallSite.from_call(node) + if call.keyword_arguments: + raise UseInferenceDefault("TypeError: int() must take no keyword arguments") + if len(call.positional_arguments) not in {1, 2}: + raise UseInferenceDefault( + "TypeError: Needs between 1 and 2 positional arguments" + ) + + default = nodes.Const(None) + values = call.positional_arguments[0] + try: + inferred_values = next(values.infer(context=context)) + except InferenceError: + return _build_dict_with_elements([]) + if inferred_values is util.Uninferable: + return _build_dict_with_elements([]) + + # Limit to a couple of potential values, as this can become pretty complicated + accepted_iterable_elements = (nodes.Const,) + if isinstance(inferred_values, (nodes.List, nodes.Set, nodes.Tuple)): + elements = inferred_values.elts + for element in elements: + if not isinstance(element, accepted_iterable_elements): + # Fallback to an empty dict + return _build_dict_with_elements([]) + + elements_with_value = [(element, default) for element in elements] + return _build_dict_with_elements(elements_with_value) + + elif isinstance(inferred_values, nodes.Const) and isinstance( + inferred_values.value, (str, bytes) + ): + elements = [ + (nodes.Const(element), default) for element in inferred_values.value + ] + return _build_dict_with_elements(elements) + elif isinstance(inferred_values, nodes.Dict): + keys = inferred_values.itered() + for key in keys: + if not isinstance(key, accepted_iterable_elements): + # Fallback to an empty dict + return _build_dict_with_elements([]) + + elements_with_value = [(element, default) for element in keys] + return _build_dict_with_elements(elements_with_value) + + # Fallback to an empty dictionary + return _build_dict_with_elements([]) + + +# Builtins inference +register_builtin_transform(infer_bool, "bool") +register_builtin_transform(infer_super, "super") +register_builtin_transform(infer_callable, "callable") +register_builtin_transform(infer_getattr, "getattr") +register_builtin_transform(infer_hasattr, "hasattr") +register_builtin_transform(infer_tuple, "tuple") +register_builtin_transform(infer_set, "set") +register_builtin_transform(infer_list, "list") +register_builtin_transform(infer_dict, "dict") +register_builtin_transform(infer_frozenset, "frozenset") +register_builtin_transform(infer_type, "type") +register_builtin_transform(infer_slice, "slice") +register_builtin_transform(infer_isinstance, "isinstance") +register_builtin_transform(infer_issubclass, "issubclass") +register_builtin_transform(infer_len, "len") +register_builtin_transform(infer_str, "str") +register_builtin_transform(infer_int, "int") +register_builtin_transform(infer_dict_fromkeys, "dict.fromkeys") + + +# Infer object.__new__ calls +MANAGER.register_transform( + nodes.ClassDef, + inference_tip(_infer_object__new__decorator), + _infer_object__new__decorator_check, +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_collections.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_collections.py new file mode 100644 index 0000000..b9eb9b9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_collections.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2016-2017 Łukasz Rogalski +# Copyright (c) 2017 Derek Gustafson +# Copyright (c) 2018 Ioana Tagirta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys + +import astroid + +PY34 = sys.version_info >= (3, 4) +PY35 = sys.version_info >= (3, 5) + + +def _collections_transform(): + return astroid.parse( + """ + class defaultdict(dict): + default_factory = None + def __missing__(self, key): pass + def __getitem__(self, key): return default_factory + + """ + + _deque_mock() + + _ordered_dict_mock() + ) + + +def _deque_mock(): + base_deque_class = """ + class deque(object): + maxlen = 0 + def __init__(self, iterable=None, maxlen=None): + self.iterable = iterable or [] + def append(self, x): pass + def appendleft(self, x): pass + def clear(self): pass + def count(self, x): return 0 + def extend(self, iterable): pass + def extendleft(self, iterable): pass + def pop(self): return self.iterable[0] + def popleft(self): return self.iterable[0] + def remove(self, value): pass + def reverse(self): return reversed(self.iterable) + def rotate(self, n=1): return self + def __iter__(self): return self + def __reversed__(self): return self.iterable[::-1] + def __getitem__(self, index): return self.iterable[index] + def __setitem__(self, index, value): pass + def __delitem__(self, index): pass + def __bool__(self): return bool(self.iterable) + def __nonzero__(self): return bool(self.iterable) + def __contains__(self, o): return o in self.iterable + def __len__(self): return len(self.iterable) + def __copy__(self): return deque(self.iterable)""" + if PY35: + base_deque_class += """ + def copy(self): return deque(self.iterable) + def index(self, x, start=0, end=0): return 0 + def insert(self, x, i): pass + def __add__(self, other): pass + def __iadd__(self, other): pass + def __mul__(self, other): pass + def __imul__(self, other): pass + def __rmul__(self, other): pass""" + return base_deque_class + + +def _ordered_dict_mock(): + base_ordered_dict_class = """ + class OrderedDict(dict): + def __reversed__(self): return self[::-1] + """ + if PY34: + base_ordered_dict_class += """ + def move_to_end(self, key, last=False): pass""" + return base_ordered_dict_class + + +astroid.register_module_extender(astroid.MANAGER, "collections", _collections_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_curses.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_curses.py new file mode 100644 index 0000000..68e88b9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_curses.py @@ -0,0 +1,179 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import astroid + + +def _curses_transform(): + return astroid.parse( + """ + A_ALTCHARSET = 1 + A_BLINK = 1 + A_BOLD = 1 + A_DIM = 1 + A_INVIS = 1 + A_ITALIC = 1 + A_NORMAL = 1 + A_PROTECT = 1 + A_REVERSE = 1 + A_STANDOUT = 1 + A_UNDERLINE = 1 + A_HORIZONTAL = 1 + A_LEFT = 1 + A_LOW = 1 + A_RIGHT = 1 + A_TOP = 1 + A_VERTICAL = 1 + A_CHARTEXT = 1 + A_ATTRIBUTES = 1 + A_CHARTEXT = 1 + A_COLOR = 1 + KEY_MIN = 1 + KEY_BREAK = 1 + KEY_DOWN = 1 + KEY_UP = 1 + KEY_LEFT = 1 + KEY_RIGHT = 1 + KEY_HOME = 1 + KEY_BACKSPACE = 1 + KEY_F0 = 1 + KEY_Fn = 1 + KEY_DL = 1 + KEY_IL = 1 + KEY_DC = 1 + KEY_IC = 1 + KEY_EIC = 1 + KEY_CLEAR = 1 + KEY_EOS = 1 + KEY_EOL = 1 + KEY_SF = 1 + KEY_SR = 1 + KEY_NPAGE = 1 + KEY_PPAGE = 1 + KEY_STAB = 1 + KEY_CTAB = 1 + KEY_CATAB = 1 + KEY_ENTER = 1 + KEY_SRESET = 1 + KEY_RESET = 1 + KEY_PRINT = 1 + KEY_LL = 1 + KEY_A1 = 1 + KEY_A3 = 1 + KEY_B2 = 1 + KEY_C1 = 1 + KEY_C3 = 1 + KEY_BTAB = 1 + KEY_BEG = 1 + KEY_CANCEL = 1 + KEY_CLOSE = 1 + KEY_COMMAND = 1 + KEY_COPY = 1 + KEY_CREATE = 1 + KEY_END = 1 + KEY_EXIT = 1 + KEY_FIND = 1 + KEY_HELP = 1 + KEY_MARK = 1 + KEY_MESSAGE = 1 + KEY_MOVE = 1 + KEY_NEXT = 1 + KEY_OPEN = 1 + KEY_OPTIONS = 1 + KEY_PREVIOUS = 1 + KEY_REDO = 1 + KEY_REFERENCE = 1 + KEY_REFRESH = 1 + KEY_REPLACE = 1 + KEY_RESTART = 1 + KEY_RESUME = 1 + KEY_SAVE = 1 + KEY_SBEG = 1 + KEY_SCANCEL = 1 + KEY_SCOMMAND = 1 + KEY_SCOPY = 1 + KEY_SCREATE = 1 + KEY_SDC = 1 + KEY_SDL = 1 + KEY_SELECT = 1 + KEY_SEND = 1 + KEY_SEOL = 1 + KEY_SEXIT = 1 + KEY_SFIND = 1 + KEY_SHELP = 1 + KEY_SHOME = 1 + KEY_SIC = 1 + KEY_SLEFT = 1 + KEY_SMESSAGE = 1 + KEY_SMOVE = 1 + KEY_SNEXT = 1 + KEY_SOPTIONS = 1 + KEY_SPREVIOUS = 1 + KEY_SPRINT = 1 + KEY_SREDO = 1 + KEY_SREPLACE = 1 + KEY_SRIGHT = 1 + KEY_SRSUME = 1 + KEY_SSAVE = 1 + KEY_SSUSPEND = 1 + KEY_SUNDO = 1 + KEY_SUSPEND = 1 + KEY_UNDO = 1 + KEY_MOUSE = 1 + KEY_RESIZE = 1 + KEY_MAX = 1 + ACS_BBSS = 1 + ACS_BLOCK = 1 + ACS_BOARD = 1 + ACS_BSBS = 1 + ACS_BSSB = 1 + ACS_BSSS = 1 + ACS_BTEE = 1 + ACS_BULLET = 1 + ACS_CKBOARD = 1 + ACS_DARROW = 1 + ACS_DEGREE = 1 + ACS_DIAMOND = 1 + ACS_GEQUAL = 1 + ACS_HLINE = 1 + ACS_LANTERN = 1 + ACS_LARROW = 1 + ACS_LEQUAL = 1 + ACS_LLCORNER = 1 + ACS_LRCORNER = 1 + ACS_LTEE = 1 + ACS_NEQUAL = 1 + ACS_PI = 1 + ACS_PLMINUS = 1 + ACS_PLUS = 1 + ACS_RARROW = 1 + ACS_RTEE = 1 + ACS_S1 = 1 + ACS_S3 = 1 + ACS_S7 = 1 + ACS_S9 = 1 + ACS_SBBS = 1 + ACS_SBSB = 1 + ACS_SBSS = 1 + ACS_SSBB = 1 + ACS_SSBS = 1 + ACS_SSSB = 1 + ACS_SSSS = 1 + ACS_STERLING = 1 + ACS_TTEE = 1 + ACS_UARROW = 1 + ACS_ULCORNER = 1 + ACS_URCORNER = 1 + ACS_VLINE = 1 + COLOR_BLACK = 1 + COLOR_BLUE = 1 + COLOR_CYAN = 1 + COLOR_GREEN = 1 + COLOR_MAGENTA = 1 + COLOR_RED = 1 + COLOR_WHITE = 1 + COLOR_YELLOW = 1 + """ + ) + + +astroid.register_module_extender(astroid.MANAGER, "curses", _curses_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_dateutil.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_dateutil.py new file mode 100644 index 0000000..a1c270f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_dateutil.py @@ -0,0 +1,28 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2015 raylu +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for dateutil""" + +import textwrap + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def dateutil_transform(): + return AstroidBuilder(MANAGER).string_build( + textwrap.dedent( + """ + import datetime + def parse(timestr, parserinfo=None, **kwargs): + return datetime.datetime() + """ + ) + ) + + +register_module_extender(MANAGER, "dateutil.parser", dateutil_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_fstrings.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_fstrings.py new file mode 100644 index 0000000..7d8c7b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_fstrings.py @@ -0,0 +1,51 @@ +# Copyright (c) 2017 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import collections +import sys + +import astroid + + +def _clone_node_with_lineno(node, parent, lineno): + cls = node.__class__ + other_fields = node._other_fields + _astroid_fields = node._astroid_fields + init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent} + postinit_params = {param: getattr(node, param) for param in _astroid_fields} + if other_fields: + init_params.update({param: getattr(node, param) for param in other_fields}) + new_node = cls(**init_params) + if hasattr(node, "postinit") and _astroid_fields: + for param, child in postinit_params.items(): + if child and not isinstance(child, collections.Sequence): + cloned_child = _clone_node_with_lineno( + node=child, lineno=new_node.lineno, parent=new_node + ) + postinit_params[param] = cloned_child + new_node.postinit(**postinit_params) + return new_node + + +def _transform_formatted_value(node): + if node.value and node.value.lineno == 1: + if node.lineno != node.value.lineno: + new_node = astroid.FormattedValue( + lineno=node.lineno, col_offset=node.col_offset, parent=node.parent + ) + new_value = _clone_node_with_lineno( + node=node.value, lineno=node.lineno, parent=new_node + ) + new_node.postinit(value=new_value, format_spec=node.format_spec) + return new_node + + +if sys.version_info[:2] >= (3, 6): + # TODO: this fix tries to *patch* http://bugs.python.org/issue29051 + # The problem is that FormattedValue.value, which is a Name node, + # has wrong line numbers, usually 1. This creates problems for pylint, + # which expects correct line numbers for things such as message control. + astroid.MANAGER.register_transform( + astroid.FormattedValue, _transform_formatted_value + ) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_functools.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_functools.py new file mode 100644 index 0000000..93bc9d3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_functools.py @@ -0,0 +1,179 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2018 Bryce Guinta + +"""Astroid hooks for understanding functools library module.""" +from functools import partial +from itertools import chain + +import astroid +from astroid import arguments +from astroid import BoundMethod +from astroid import extract_node +from astroid import helpers +from astroid.interpreter import objectmodel +from astroid import MANAGER + + +LRU_CACHE = "functools.lru_cache" + + +class LruWrappedModel(objectmodel.FunctionModel): + """Special attribute model for functions decorated with functools.lru_cache. + + The said decorators patches at decoration time some functions onto + the decorated function. + """ + + @property + def py__wrapped__(self): + return self._instance + + @property + def pycache_info(self): + cache_info = extract_node( + """ + from functools import _CacheInfo + _CacheInfo(0, 0, 0, 0) + """ + ) + + class CacheInfoBoundMethod(BoundMethod): + def infer_call_result(self, caller, context=None): + yield helpers.safe_infer(cache_info) + + return CacheInfoBoundMethod(proxy=self._instance, bound=self._instance) + + @property + def pycache_clear(self): + node = extract_node("""def cache_clear(self): pass""") + return BoundMethod(proxy=node, bound=self._instance.parent.scope()) + + +def _transform_lru_cache(node, context=None): + # TODO: this is not ideal, since the node should be immutable, + # but due to https://github.com/PyCQA/astroid/issues/354, + # there's not much we can do now. + # Replacing the node would work partially, because, + # in pylint, the old node would still be available, leading + # to spurious false positives. + node.special_attributes = LruWrappedModel()(node) + return + + +def _functools_partial_inference(node, context=None): + call = arguments.CallSite.from_call(node) + number_of_positional = len(call.positional_arguments) + if number_of_positional < 1: + raise astroid.UseInferenceDefault( + "functools.partial takes at least one argument" + ) + if number_of_positional == 1 and not call.keyword_arguments: + raise astroid.UseInferenceDefault( + "functools.partial needs at least to have some filled arguments" + ) + + partial_function = call.positional_arguments[0] + try: + inferred_wrapped_function = next(partial_function.infer(context=context)) + except astroid.InferenceError as exc: + raise astroid.UseInferenceDefault from exc + if inferred_wrapped_function is astroid.Uninferable: + raise astroid.UseInferenceDefault("Cannot infer the wrapped function") + if not isinstance(inferred_wrapped_function, astroid.FunctionDef): + raise astroid.UseInferenceDefault("The wrapped function is not a function") + + # Determine if the passed keywords into the callsite are supported + # by the wrapped function. + function_parameters = chain( + inferred_wrapped_function.args.args or (), + inferred_wrapped_function.args.kwonlyargs or (), + ) + parameter_names = set( + param.name + for param in function_parameters + if isinstance(param, astroid.AssignName) + ) + if set(call.keyword_arguments) - parameter_names: + raise astroid.UseInferenceDefault( + "wrapped function received unknown parameters" + ) + + # Return a wrapped() object that can be used further for inference + class PartialFunction(astroid.FunctionDef): + + filled_positionals = len(call.positional_arguments[1:]) + filled_keywords = list(call.keyword_arguments) + + def infer_call_result(self, caller=None, context=None): + nonlocal call + filled_args = call.positional_arguments[1:] + filled_keywords = call.keyword_arguments + + if context: + current_passed_keywords = { + keyword for (keyword, _) in context.callcontext.keywords + } + for keyword, value in filled_keywords.items(): + if keyword not in current_passed_keywords: + context.callcontext.keywords.append((keyword, value)) + + call_context_args = context.callcontext.args or [] + context.callcontext.args = filled_args + call_context_args + + return super().infer_call_result(caller=caller, context=context) + + partial_function = PartialFunction( + name=inferred_wrapped_function.name, + doc=inferred_wrapped_function.doc, + lineno=inferred_wrapped_function.lineno, + col_offset=inferred_wrapped_function.col_offset, + parent=inferred_wrapped_function.parent, + ) + partial_function.postinit( + args=inferred_wrapped_function.args, + body=inferred_wrapped_function.body, + decorators=inferred_wrapped_function.decorators, + returns=inferred_wrapped_function.returns, + type_comment_returns=inferred_wrapped_function.type_comment_returns, + type_comment_args=inferred_wrapped_function.type_comment_args, + ) + return iter((partial_function,)) + + +def _looks_like_lru_cache(node): + """Check if the given function node is decorated with lru_cache.""" + if not node.decorators: + return False + for decorator in node.decorators.nodes: + if not isinstance(decorator, astroid.Call): + continue + if _looks_like_functools_member(decorator, "lru_cache"): + return True + return False + + +def _looks_like_functools_member(node, member): + """Check if the given Call node is a functools.partial call""" + if isinstance(node.func, astroid.Name): + return node.func.name == member + elif isinstance(node.func, astroid.Attribute): + return ( + node.func.attrname == member + and isinstance(node.func.expr, astroid.Name) + and node.func.expr.name == "functools" + ) + + +_looks_like_partial = partial(_looks_like_functools_member, member="partial") + + +MANAGER.register_transform( + astroid.FunctionDef, _transform_lru_cache, _looks_like_lru_cache +) + + +MANAGER.register_transform( + astroid.Call, + astroid.inference_tip(_functools_partial_inference), + _looks_like_partial, +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_gi.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_gi.py new file mode 100644 index 0000000..0970610 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_gi.py @@ -0,0 +1,220 @@ +# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Cole Robinson +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 David Shea +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Giuseppe Scrivano + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the Python 2 GObject introspection bindings. + +Helps with understanding everything imported from 'gi.repository' +""" + +import inspect +import itertools +import sys +import re +import warnings + +from astroid import MANAGER, AstroidBuildingError, nodes +from astroid.builder import AstroidBuilder + + +_inspected_modules = {} + +_identifier_re = r"^[A-Za-z_]\w*$" + + +def _gi_build_stub(parent): + """ + Inspect the passed module recursively and build stubs for functions, + classes, etc. + """ + classes = {} + functions = {} + constants = {} + methods = {} + for name in dir(parent): + if name.startswith("__"): + continue + + # Check if this is a valid name in python + if not re.match(_identifier_re, name): + continue + + try: + obj = getattr(parent, name) + except: + continue + + if inspect.isclass(obj): + classes[name] = obj + elif inspect.isfunction(obj) or inspect.isbuiltin(obj): + functions[name] = obj + elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): + methods[name] = obj + elif ( + str(obj).startswith(", ) + # Only accept function calls with two constant arguments + if len(node.args) != 2: + return False + + if not all(isinstance(arg, nodes.Const) for arg in node.args): + return False + + func = node.func + if isinstance(func, nodes.Attribute): + if func.attrname != "require_version": + return False + if isinstance(func.expr, nodes.Name) and func.expr.name == "gi": + return True + + return False + + if isinstance(func, nodes.Name): + return func.name == "require_version" + + return False + + +def _register_require_version(node): + # Load the gi.require_version locally + try: + import gi + + gi.require_version(node.args[0].value, node.args[1].value) + except Exception: + pass + + return node + + +MANAGER.register_failed_import_hook(_import_gi_module) +MANAGER.register_transform( + nodes.Call, _register_require_version, _looks_like_require_version +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_hashlib.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_hashlib.py new file mode 100644 index 0000000..98ae774 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_hashlib.py @@ -0,0 +1,67 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2018 Ioana Tagirta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys + +import six + +import astroid + +PY36 = sys.version_info >= (3, 6) + + +def _hashlib_transform(): + signature = "value=''" + template = """ + class %(name)s(object): + def __init__(self, %(signature)s): pass + def digest(self): + return %(digest)s + def copy(self): + return self + def update(self, value): pass + def hexdigest(self): + return '' + @property + def name(self): + return %(name)r + @property + def block_size(self): + return 1 + @property + def digest_size(self): + return 1 + """ + algorithms_with_signature = dict.fromkeys( + ["md5", "sha1", "sha224", "sha256", "sha384", "sha512"], signature + ) + if PY36: + blake2b_signature = "data=b'', *, digest_size=64, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False" + blake2s_signature = "data=b'', *, digest_size=32, key=b'', salt=b'', \ + person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \ + node_depth=0, inner_size=0, last_node=False" + new_algorithms = dict.fromkeys( + ["sha3_224", "sha3_256", "sha3_384", "sha3_512", "shake_128", "shake_256"], + signature, + ) + algorithms_with_signature.update(new_algorithms) + algorithms_with_signature.update( + {"blake2b": blake2b_signature, "blake2s": blake2s_signature} + ) + classes = "".join( + template + % { + "name": hashfunc, + "digest": 'b""' if six.PY3 else '""', + "signature": signature, + } + for hashfunc, signature in algorithms_with_signature.items() + ) + return astroid.parse(classes) + + +astroid.register_module_extender(astroid.MANAGER, "hashlib", _hashlib_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_io.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_io.py new file mode 100644 index 0000000..4c68922 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_io.py @@ -0,0 +1,45 @@ +# Copyright (c) 2016 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid brain hints for some of the _io C objects.""" + +import astroid + + +BUFFERED = {"BufferedWriter", "BufferedReader"} +TextIOWrapper = "TextIOWrapper" +FileIO = "FileIO" +BufferedWriter = "BufferedWriter" + + +def _generic_io_transform(node, name, cls): + """Transform the given name, by adding the given *class* as a member of the node.""" + + io_module = astroid.MANAGER.ast_from_module_name("_io") + attribute_object = io_module[cls] + instance = attribute_object.instantiate_class() + node.locals[name] = [instance] + + +def _transform_text_io_wrapper(node): + # This is not always correct, since it can vary with the type of the descriptor, + # being stdout, stderr or stdin. But we cannot get access to the name of the + # stream, which is why we are using the BufferedWriter class as a default + # value + return _generic_io_transform(node, name="buffer", cls=BufferedWriter) + + +def _transform_buffered(node): + return _generic_io_transform(node, name="raw", cls=FileIO) + + +astroid.MANAGER.register_transform( + astroid.ClassDef, _transform_buffered, lambda node: node.name in BUFFERED +) +astroid.MANAGER.register_transform( + astroid.ClassDef, + _transform_text_io_wrapper, + lambda node: node.name == TextIOWrapper, +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_mechanize.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_mechanize.py new file mode 100644 index 0000000..93f282e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_mechanize.py @@ -0,0 +1,29 @@ +# Copyright (c) 2012-2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def mechanize_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +class Browser(object): + def open(self, url, data=None, timeout=None): + return None + def open_novisit(self, url, data=None, timeout=None): + return None + def open_local_file(self, filename): + return None + +""" + ) + + +register_module_extender(MANAGER, "mechanize", mechanize_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_multiprocessing.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_multiprocessing.py new file mode 100644 index 0000000..be575e9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_multiprocessing.py @@ -0,0 +1,112 @@ +# Copyright (c) 2016 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import sys + +import astroid +from astroid import exceptions + + +PY34 = sys.version_info >= (3, 4) + + +def _multiprocessing_transform(): + module = astroid.parse( + """ + from multiprocessing.managers import SyncManager + def Manager(): + return SyncManager() + """ + ) + if not PY34: + return module + + # On Python 3.4, multiprocessing uses a getattr lookup inside contexts, + # in order to get the attributes they need. Since it's extremely + # dynamic, we use this approach to fake it. + node = astroid.parse( + """ + from multiprocessing.context import DefaultContext, BaseContext + default = DefaultContext() + base = BaseContext() + """ + ) + try: + context = next(node["default"].infer()) + base = next(node["base"].infer()) + except exceptions.InferenceError: + return module + + for node in (context, base): + for key, value in node.locals.items(): + if key.startswith("_"): + continue + + value = value[0] + if isinstance(value, astroid.FunctionDef): + # We need to rebound this, since otherwise + # it will have an extra argument (self). + value = astroid.BoundMethod(value, node) + module[key] = value + return module + + +def _multiprocessing_managers_transform(): + return astroid.parse( + """ + import array + import threading + import multiprocessing.pool as pool + + import six + + class Namespace(object): + pass + + class Value(object): + def __init__(self, typecode, value, lock=True): + self._typecode = typecode + self._value = value + def get(self): + return self._value + def set(self, value): + self._value = value + def __repr__(self): + return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value) + value = property(get, set) + + def Array(typecode, sequence, lock=True): + return array.array(typecode, sequence) + + class SyncManager(object): + Queue = JoinableQueue = six.moves.queue.Queue + Event = threading.Event + RLock = threading.RLock + BoundedSemaphore = threading.BoundedSemaphore + Condition = threading.Condition + Barrier = threading.Barrier + Pool = pool.Pool + list = list + dict = dict + Value = Value + Array = Array + Namespace = Namespace + __enter__ = lambda self: self + __exit__ = lambda *args: args + + def start(self, initializer=None, initargs=None): + pass + def shutdown(self): + pass + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "multiprocessing.managers", _multiprocessing_managers_transform +) +astroid.register_module_extender( + astroid.MANAGER, "multiprocessing", _multiprocessing_transform +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_namedtuple_enum.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_namedtuple_enum.py new file mode 100644 index 0000000..85390a8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_namedtuple_enum.py @@ -0,0 +1,398 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2012-2015 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2015 David Shea +# Copyright (c) 2015 Philip Lorenz +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Mateusz Bysiek +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Łukasz Rogalski + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the Python standard library.""" + +import functools +import keyword +from textwrap import dedent + +from astroid import MANAGER, UseInferenceDefault, inference_tip, InferenceError +from astroid import arguments +from astroid import exceptions +from astroid import nodes +from astroid.builder import AstroidBuilder, extract_node +from astroid import util + + +TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"} +ENUM_BASE_NAMES = {"Enum", "IntEnum", "enum.Enum", "enum.IntEnum"} + + +def _infer_first(node, context): + if node is util.Uninferable: + raise UseInferenceDefault + try: + value = next(node.infer(context=context)) + if value is util.Uninferable: + raise UseInferenceDefault() + else: + return value + except StopIteration: + raise InferenceError() + + +def _find_func_form_arguments(node, context): + def _extract_namedtuple_arg_or_keyword(position, key_name=None): + + if len(args) > position: + return _infer_first(args[position], context) + if key_name and key_name in found_keywords: + return _infer_first(found_keywords[key_name], context) + + args = node.args + keywords = node.keywords + found_keywords = ( + {keyword.arg: keyword.value for keyword in keywords} if keywords else {} + ) + + name = _extract_namedtuple_arg_or_keyword(position=0, key_name="typename") + names = _extract_namedtuple_arg_or_keyword(position=1, key_name="field_names") + if name and names: + return name.value, names + + raise UseInferenceDefault() + + +def infer_func_form(node, base_type, context=None, enum=False): + """Specific inference function for namedtuple or Python 3 enum. """ + # node is a Call node, class name as first argument and generated class + # attributes as second argument + + # namedtuple or enums list of attributes can be a list of strings or a + # whitespace-separate string + try: + name, names = _find_func_form_arguments(node, context) + try: + attributes = names.value.replace(",", " ").split() + except AttributeError: + if not enum: + attributes = [ + _infer_first(const, context).value for const in names.elts + ] + else: + # Enums supports either iterator of (name, value) pairs + # or mappings. + if hasattr(names, "items") and isinstance(names.items, list): + attributes = [ + _infer_first(const[0], context).value + for const in names.items + if isinstance(const[0], nodes.Const) + ] + elif hasattr(names, "elts"): + # Enums can support either ["a", "b", "c"] + # or [("a", 1), ("b", 2), ...], but they can't + # be mixed. + if all(isinstance(const, nodes.Tuple) for const in names.elts): + attributes = [ + _infer_first(const.elts[0], context).value + for const in names.elts + if isinstance(const, nodes.Tuple) + ] + else: + attributes = [ + _infer_first(const, context).value for const in names.elts + ] + else: + raise AttributeError + if not attributes: + raise AttributeError + except (AttributeError, exceptions.InferenceError): + raise UseInferenceDefault() + + # If we can't infer the name of the class, don't crash, up to this point + # we know it is a namedtuple anyway. + name = name or "Uninferable" + # we want to return a Class node instance with proper attributes set + class_node = nodes.ClassDef(name, "docstring") + class_node.parent = node.parent + # set base class=tuple + class_node.bases.append(base_type) + # XXX add __init__(*attributes) method + for attr in attributes: + fake_node = nodes.EmptyNode() + fake_node.parent = class_node + fake_node.attrname = attr + class_node.instance_attrs[attr] = [fake_node] + return class_node, name, attributes + + +def _has_namedtuple_base(node): + """Predicate for class inference tip + + :type node: ClassDef + :rtype: bool + """ + return set(node.basenames) & TYPING_NAMEDTUPLE_BASENAMES + + +def _looks_like(node, name): + func = node.func + if isinstance(func, nodes.Attribute): + return func.attrname == name + if isinstance(func, nodes.Name): + return func.name == name + return False + + +_looks_like_namedtuple = functools.partial(_looks_like, name="namedtuple") +_looks_like_enum = functools.partial(_looks_like, name="Enum") +_looks_like_typing_namedtuple = functools.partial(_looks_like, name="NamedTuple") + + +def infer_named_tuple(node, context=None): + """Specific inference function for namedtuple Call node""" + tuple_base_name = nodes.Name(name="tuple", parent=node.root()) + class_node, name, attributes = infer_func_form( + node, tuple_base_name, context=context + ) + call_site = arguments.CallSite.from_call(node) + func = next(extract_node("import collections; collections.namedtuple").infer()) + try: + rename = next(call_site.infer_argument(func, "rename", context)).bool_value() + except InferenceError: + rename = False + + if rename: + attributes = _get_renamed_namedtuple_attributes(attributes) + + replace_args = ", ".join("{arg}=None".format(arg=arg) for arg in attributes) + + field_def = ( + " {name} = property(lambda self: self[{index:d}], " + "doc='Alias for field number {index:d}')" + ) + field_defs = "\n".join( + field_def.format(name=name, index=index) + for index, name in enumerate(attributes) + ) + fake = AstroidBuilder(MANAGER).string_build( + """ +class %(name)s(tuple): + __slots__ = () + _fields = %(fields)r + def _asdict(self): + return self.__dict__ + @classmethod + def _make(cls, iterable, new=tuple.__new__, len=len): + return new(cls, iterable) + def _replace(self, %(replace_args)s): + return self + def __getnewargs__(self): + return tuple(self) +%(field_defs)s + """ + % { + "name": name, + "fields": attributes, + "field_defs": field_defs, + "replace_args": replace_args, + } + ) + class_node.locals["_asdict"] = fake.body[0].locals["_asdict"] + class_node.locals["_make"] = fake.body[0].locals["_make"] + class_node.locals["_replace"] = fake.body[0].locals["_replace"] + class_node.locals["_fields"] = fake.body[0].locals["_fields"] + for attr in attributes: + class_node.locals[attr] = fake.body[0].locals[attr] + # we use UseInferenceDefault, we can't be a generator so return an iterator + return iter([class_node]) + + +def _get_renamed_namedtuple_attributes(field_names): + names = list(field_names) + seen = set() + for i, name in enumerate(field_names): + if ( + not all(c.isalnum() or c == "_" for c in name) + or keyword.iskeyword(name) + or not name + or name[0].isdigit() + or name.startswith("_") + or name in seen + ): + names[i] = "_%d" % i + seen.add(name) + return tuple(names) + + +def infer_enum(node, context=None): + """ Specific inference function for enum Call node. """ + enum_meta = extract_node( + """ + class EnumMeta(object): + 'docstring' + def __call__(self, node): + class EnumAttribute(object): + name = '' + value = 0 + return EnumAttribute() + def __iter__(self): + class EnumAttribute(object): + name = '' + value = 0 + return [EnumAttribute()] + def __next__(self): + return next(iter(self)) + def __getitem__(self, attr): + class Value(object): + @property + def name(self): + return '' + @property + def value(self): + return attr + + return Value() + __members__ = [''] + """ + ) + class_node = infer_func_form(node, enum_meta, context=context, enum=True)[0] + return iter([class_node.instantiate_class()]) + + +def infer_enum_class(node): + """ Specific inference for enums. """ + for basename in node.basenames: + # TODO: doesn't handle subclasses yet. This implementation + # is a hack to support enums. + if basename not in ENUM_BASE_NAMES: + continue + if node.root().name == "enum": + # Skip if the class is directly from enum module. + break + for local, values in node.locals.items(): + if any(not isinstance(value, nodes.AssignName) for value in values): + continue + + targets = [] + stmt = values[0].statement() + if isinstance(stmt, nodes.Assign): + if isinstance(stmt.targets[0], nodes.Tuple): + targets = stmt.targets[0].itered() + else: + targets = stmt.targets + elif isinstance(stmt, nodes.AnnAssign): + targets = [stmt.target] + + inferred_return_value = None + if isinstance(stmt.value, nodes.Const): + if isinstance(stmt.value.value, str): + inferred_return_value = '"{}"'.format(stmt.value.value) + else: + inferred_return_value = stmt.value.value + + new_targets = [] + for target in targets: + # Replace all the assignments with our mocked class. + classdef = dedent( + """ + class {name}({types}): + @property + def value(self): + return {return_value} + @property + def name(self): + return {name} + """.format( + name=target.name, + types=", ".join(node.basenames), + return_value=inferred_return_value, + ) + ) + fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name] + fake.parent = target.parent + for method in node.mymethods(): + fake.locals[method.name] = [method] + new_targets.append(fake.instantiate_class()) + node.locals[local] = new_targets + break + return node + + +def infer_typing_namedtuple_class(class_node, context=None): + """Infer a subclass of typing.NamedTuple""" + # Check if it has the corresponding bases + annassigns_fields = [ + annassign.target.name + for annassign in class_node.body + if isinstance(annassign, nodes.AnnAssign) + ] + code = dedent( + """ + from collections import namedtuple + namedtuple({typename!r}, {fields!r}) + """ + ).format(typename=class_node.name, fields=",".join(annassigns_fields)) + node = extract_node(code) + generated_class_node = next(infer_named_tuple(node, context)) + for method in class_node.mymethods(): + generated_class_node.locals[method.name] = [method] + return iter((generated_class_node,)) + + +def infer_typing_namedtuple(node, context=None): + """Infer a typing.NamedTuple(...) call.""" + # This is essentially a namedtuple with different arguments + # so we extract the args and infer a named tuple. + try: + func = next(node.func.infer()) + except InferenceError: + raise UseInferenceDefault + + if func.qname() != "typing.NamedTuple": + raise UseInferenceDefault + + if len(node.args) != 2: + raise UseInferenceDefault + + if not isinstance(node.args[1], (nodes.List, nodes.Tuple)): + raise UseInferenceDefault + + names = [] + for elt in node.args[1].elts: + if not isinstance(elt, (nodes.List, nodes.Tuple)): + raise UseInferenceDefault + if len(elt.elts) != 2: + raise UseInferenceDefault + names.append(elt.elts[0].as_string()) + + typename = node.args[0].as_string() + node = extract_node( + "namedtuple(%(typename)s, (%(fields)s,)) " + % {"typename": typename, "fields": ",".join(names)} + ) + return infer_named_tuple(node, context) + + +MANAGER.register_transform( + nodes.Call, inference_tip(infer_named_tuple), _looks_like_namedtuple +) +MANAGER.register_transform(nodes.Call, inference_tip(infer_enum), _looks_like_enum) +MANAGER.register_transform( + nodes.ClassDef, + infer_enum_class, + predicate=lambda cls: any( + basename for basename in cls.basenames if basename in ENUM_BASE_NAMES + ), +) +MANAGER.register_transform( + nodes.ClassDef, inference_tip(infer_typing_namedtuple_class), _has_namedtuple_base +) +MANAGER.register_transform( + nodes.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_nose.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_nose.py new file mode 100644 index 0000000..7b12d76 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_nose.py @@ -0,0 +1,77 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Hooks for nose library.""" + +import re +import textwrap + +import astroid +import astroid.builder + +_BUILDER = astroid.builder.AstroidBuilder(astroid.MANAGER) + + +def _pep8(name, caps=re.compile("([A-Z])")): + return caps.sub(lambda m: "_" + m.groups()[0].lower(), name) + + +def _nose_tools_functions(): + """Get an iterator of names and bound methods.""" + module = _BUILDER.string_build( + textwrap.dedent( + """ + import unittest + + class Test(unittest.TestCase): + pass + a = Test() + """ + ) + ) + try: + case = next(module["a"].infer()) + except astroid.InferenceError: + return + for method in case.methods(): + if method.name.startswith("assert") and "_" not in method.name: + pep8_name = _pep8(method.name) + yield pep8_name, astroid.BoundMethod(method, case) + if method.name == "assertEqual": + # nose also exports assert_equals. + yield "assert_equals", astroid.BoundMethod(method, case) + + +def _nose_tools_transform(node): + for method_name, method in _nose_tools_functions(): + node.locals[method_name] = [method] + + +def _nose_tools_trivial_transform(): + """Custom transform for the nose.tools module.""" + stub = _BUILDER.string_build("""__all__ = []""") + all_entries = ["ok_", "eq_"] + + for pep8_name, method in _nose_tools_functions(): + all_entries.append(pep8_name) + stub[pep8_name] = method + + # Update the __all__ variable, since nose.tools + # does this manually with .append. + all_assign = stub["__all__"].parent + all_object = astroid.List(all_entries) + all_object.parent = all_assign + all_assign.value = all_object + return stub + + +astroid.register_module_extender( + astroid.MANAGER, "nose.tools.trivial", _nose_tools_trivial_transform +) +astroid.MANAGER.register_transform( + astroid.Module, _nose_tools_transform, lambda n: n.name == "nose.tools" +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_numpy.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_numpy.py new file mode 100644 index 0000000..9d31a47 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_numpy.py @@ -0,0 +1,488 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2017-2018 hippo91 + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for numpy.""" + +import astroid + + +def numpy_random_mtrand_transform(): + return astroid.parse( + """ + def beta(a, b, size=None): pass + def binomial(n, p, size=None): pass + def bytes(length): pass + def chisquare(df, size=None): pass + def choice(a, size=None, replace=True, p=None): pass + def dirichlet(alpha, size=None): pass + def exponential(scale=1.0, size=None): pass + def f(dfnum, dfden, size=None): pass + def gamma(shape, scale=1.0, size=None): pass + def geometric(p, size=None): pass + def get_state(): pass + def gumbel(loc=0.0, scale=1.0, size=None): pass + def hypergeometric(ngood, nbad, nsample, size=None): pass + def laplace(loc=0.0, scale=1.0, size=None): pass + def logistic(loc=0.0, scale=1.0, size=None): pass + def lognormal(mean=0.0, sigma=1.0, size=None): pass + def logseries(p, size=None): pass + def multinomial(n, pvals, size=None): pass + def multivariate_normal(mean, cov, size=None): pass + def negative_binomial(n, p, size=None): pass + def noncentral_chisquare(df, nonc, size=None): pass + def noncentral_f(dfnum, dfden, nonc, size=None): pass + def normal(loc=0.0, scale=1.0, size=None): pass + def pareto(a, size=None): pass + def permutation(x): pass + def poisson(lam=1.0, size=None): pass + def power(a, size=None): pass + def rand(*args): pass + def randint(low, high=None, size=None, dtype='l'): pass + def randn(*args): pass + def random_integers(low, high=None, size=None): pass + def random_sample(size=None): pass + def rayleigh(scale=1.0, size=None): pass + def seed(seed=None): pass + def set_state(state): pass + def shuffle(x): pass + def standard_cauchy(size=None): pass + def standard_exponential(size=None): pass + def standard_gamma(shape, size=None): pass + def standard_normal(size=None): pass + def standard_t(df, size=None): pass + def triangular(left, mode, right, size=None): pass + def uniform(low=0.0, high=1.0, size=None): pass + def vonmises(mu, kappa, size=None): pass + def wald(mean, scale, size=None): pass + def weibull(a, size=None): pass + def zipf(a, size=None): pass + """ + ) + + +def numpy_core_umath_transform(): + ufunc_optional_keyword_arguments = ( + """out=None, where=True, casting='same_kind', order='K', """ + """dtype=None, subok=True""" + ) + return astroid.parse( + """ + # Constants + e = 2.718281828459045 + euler_gamma = 0.5772156649015329 + + # No arg functions + def geterrobj(): pass + + # One arg functions + def seterrobj(errobj): pass + + # One arg functions with optional kwargs + def arccos(x, {opt_args:s}): pass + def arccosh(x, {opt_args:s}): pass + def arcsin(x, {opt_args:s}): pass + def arcsinh(x, {opt_args:s}): pass + def arctan(x, {opt_args:s}): pass + def arctanh(x, {opt_args:s}): pass + def cbrt(x, {opt_args:s}): pass + def conj(x, {opt_args:s}): pass + def conjugate(x, {opt_args:s}): pass + def cosh(x, {opt_args:s}): pass + def deg2rad(x, {opt_args:s}): pass + def degrees(x, {opt_args:s}): pass + def exp2(x, {opt_args:s}): pass + def expm1(x, {opt_args:s}): pass + def fabs(x, {opt_args:s}): pass + def frexp(x, {opt_args:s}): pass + def isfinite(x, {opt_args:s}): pass + def isinf(x, {opt_args:s}): pass + def log(x, {opt_args:s}): pass + def log1p(x, {opt_args:s}): pass + def log2(x, {opt_args:s}): pass + def logical_not(x, {opt_args:s}): pass + def modf(x, {opt_args:s}): pass + def negative(x, {opt_args:s}): pass + def rad2deg(x, {opt_args:s}): pass + def radians(x, {opt_args:s}): pass + def reciprocal(x, {opt_args:s}): pass + def rint(x, {opt_args:s}): pass + def sign(x, {opt_args:s}): pass + def signbit(x, {opt_args:s}): pass + def sinh(x, {opt_args:s}): pass + def spacing(x, {opt_args:s}): pass + def square(x, {opt_args:s}): pass + def tan(x, {opt_args:s}): pass + def tanh(x, {opt_args:s}): pass + def trunc(x, {opt_args:s}): pass + + # Two args functions with optional kwargs + def bitwise_and(x1, x2, {opt_args:s}): pass + def bitwise_or(x1, x2, {opt_args:s}): pass + def bitwise_xor(x1, x2, {opt_args:s}): pass + def copysign(x1, x2, {opt_args:s}): pass + def divide(x1, x2, {opt_args:s}): pass + def equal(x1, x2, {opt_args:s}): pass + def float_power(x1, x2, {opt_args:s}): pass + def floor_divide(x1, x2, {opt_args:s}): pass + def fmax(x1, x2, {opt_args:s}): pass + def fmin(x1, x2, {opt_args:s}): pass + def fmod(x1, x2, {opt_args:s}): pass + def greater(x1, x2, {opt_args:s}): pass + def hypot(x1, x2, {opt_args:s}): pass + def ldexp(x1, x2, {opt_args:s}): pass + def left_shift(x1, x2, {opt_args:s}): pass + def less(x1, x2, {opt_args:s}): pass + def logaddexp(x1, x2, {opt_args:s}): pass + def logaddexp2(x1, x2, {opt_args:s}): pass + def logical_and(x1, x2, {opt_args:s}): pass + def logical_or(x1, x2, {opt_args:s}): pass + def logical_xor(x1, x2, {opt_args:s}): pass + def maximum(x1, x2, {opt_args:s}): pass + def minimum(x1, x2, {opt_args:s}): pass + def nextafter(x1, x2, {opt_args:s}): pass + def not_equal(x1, x2, {opt_args:s}): pass + def power(x1, x2, {opt_args:s}): pass + def remainder(x1, x2, {opt_args:s}): pass + def right_shift(x1, x2, {opt_args:s}): pass + def subtract(x1, x2, {opt_args:s}): pass + def true_divide(x1, x2, {opt_args:s}): pass + """.format( + opt_args=ufunc_optional_keyword_arguments + ) + ) + + +def numpy_core_numerictypes_transform(): + return astroid.parse( + """ + # different types defined in numerictypes.py + class generic(object): + def __init__(self, value): + self.T = None + self.base = None + self.data = None + self.dtype = None + self.flags = None + self.flat = None + self.imag = None + self.itemsize = None + self.nbytes = None + self.ndim = None + self.real = None + self.size = None + self.strides = None + + def all(self): pass + def any(self): pass + def argmax(self): pass + def argmin(self): pass + def argsort(self): pass + def astype(self): pass + def base(self): pass + def byteswap(self): pass + def choose(self): pass + def clip(self): pass + def compress(self): pass + def conj(self): pass + def conjugate(self): pass + def copy(self): pass + def cumprod(self): pass + def cumsum(self): pass + def data(self): pass + def diagonal(self): pass + def dtype(self): pass + def dump(self): pass + def dumps(self): pass + def fill(self): pass + def flags(self): pass + def flat(self): pass + def flatten(self): pass + def getfield(self): pass + def imag(self): pass + def item(self): pass + def itemset(self): pass + def itemsize(self): pass + def max(self): pass + def mean(self): pass + def min(self): pass + def nbytes(self): pass + def ndim(self): pass + def newbyteorder(self): pass + def nonzero(self): pass + def prod(self): pass + def ptp(self): pass + def put(self): pass + def ravel(self): pass + def real(self): pass + def repeat(self): pass + def reshape(self): pass + def resize(self): pass + def round(self): pass + def searchsorted(self): pass + def setfield(self): pass + def setflags(self): pass + def shape(self): pass + def size(self): pass + def sort(self): pass + def squeeze(self): pass + def std(self): pass + def strides(self): pass + def sum(self): pass + def swapaxes(self): pass + def take(self): pass + def tobytes(self): pass + def tofile(self): pass + def tolist(self): pass + def tostring(self): pass + def trace(self): pass + def transpose(self): pass + def var(self): pass + def view(self): pass + + + class dtype(object): + def __init__(self, obj, align=False, copy=False): + self.alignment = None + self.base = None + self.byteorder = None + self.char = None + self.descr = None + self.fields = None + self.flags = None + self.hasobject = None + self.isalignedstruct = None + self.isbuiltin = None + self.isnative = None + self.itemsize = None + self.kind = None + self.metadata = None + self.name = None + self.names = None + self.num = None + self.shape = None + self.str = None + self.subdtype = None + self.type = None + + def newbyteorder(self, new_order='S'): pass + + + class ndarray(object): + def __init__(self, shape, dtype=float, buffer=None, offset=0, + strides=None, order=None): + self.T = None + self.base = None + self.ctypes = None + self.data = None + self.dtype = None + self.flags = None + self.flat = None + self.imag = None + self.itemsize = None + self.nbytes = None + self.ndim = None + self.real = None + self.shape = None + self.size = None + self.strides = None + + def all(self): pass + def any(self): pass + def argmax(self): pass + def argmin(self): pass + def argpartition(self): pass + def argsort(self): pass + def astype(self): pass + def byteswap(self): pass + def choose(self): pass + def clip(self): pass + def compress(self): pass + def conj(self): pass + def conjugate(self): pass + def copy(self): pass + def cumprod(self): pass + def cumsum(self): pass + def diagonal(self): pass + def dot(self): pass + def dump(self): pass + def dumps(self): pass + def fill(self): pass + def flatten(self): pass + def getfield(self): pass + def item(self): pass + def itemset(self): pass + def max(self): pass + def mean(self): pass + def min(self): pass + def newbyteorder(self): pass + def nonzero(self): pass + def partition(self): pass + def prod(self): pass + def ptp(self): pass + def put(self): pass + def ravel(self): pass + def repeat(self): pass + def reshape(self): pass + def resize(self): pass + def round(self): pass + def searchsorted(self): pass + def setfield(self): pass + def setflags(self): pass + def sort(self): pass + def squeeze(self): pass + def std(self): pass + def sum(self): pass + def swapaxes(self): pass + def take(self): pass + def tobytes(self): pass + def tofile(self): pass + def tolist(self): pass + def tostring(self): pass + def trace(self): pass + def transpose(self): pass + def var(self): pass + def view(self): pass + + + class busdaycalendar(object): + def __init__(self, weekmask='1111100', holidays=None): + self.holidays = None + self.weekmask = None + + class flexible(generic): pass + class bool_(generic): pass + class number(generic): pass + class datetime64(generic): pass + + + class void(flexible): + def __init__(self, *args, **kwargs): + self.base = None + self.dtype = None + self.flags = None + def getfield(self): pass + def setfield(self): pass + + + class character(flexible): pass + + + class integer(number): + def __init__(self, value): + self.denominator = None + self.numerator = None + + + class inexact(number): pass + + + class str_(str, character): + def maketrans(self, x, y=None, z=None): pass + + + class bytes_(bytes, character): + def fromhex(self, string): pass + def maketrans(self, frm, to): pass + + + class signedinteger(integer): pass + + + class unsignedinteger(integer): pass + + + class complexfloating(inexact): pass + + + class floating(inexact): pass + + + class float64(floating, float): + def fromhex(self, string): pass + + + class uint64(unsignedinteger): pass + class complex64(complexfloating): pass + class int16(signedinteger): pass + class float96(floating): pass + class int8(signedinteger): pass + class uint32(unsignedinteger): pass + class uint8(unsignedinteger): pass + class _typedict(dict): pass + class complex192(complexfloating): pass + class timedelta64(signedinteger): pass + class int32(signedinteger): pass + class uint16(unsignedinteger): pass + class float32(floating): pass + class complex128(complexfloating, complex): pass + class float16(floating): pass + class int64(signedinteger): pass + + buffer_type = memoryview + bool8 = bool_ + byte = int8 + bytes0 = bytes_ + cdouble = complex128 + cfloat = complex128 + clongdouble = complex192 + clongfloat = complex192 + complex_ = complex128 + csingle = complex64 + double = float64 + float_ = float64 + half = float16 + int0 = int32 + int_ = int32 + intc = int32 + intp = int32 + long = int32 + longcomplex = complex192 + longdouble = float96 + longfloat = float96 + longlong = int64 + object0 = object_ + object_ = object_ + short = int16 + single = float32 + singlecomplex = complex64 + str0 = str_ + string_ = bytes_ + ubyte = uint8 + uint = uint32 + uint0 = uint32 + uintc = uint32 + uintp = uint32 + ulonglong = uint64 + unicode = str_ + unicode_ = str_ + ushort = uint16 + void0 = void + """ + ) + + +def numpy_funcs(): + return astroid.parse( + """ + import builtins + def sum(a, axis=None, dtype=None, out=None, keepdims=None): + return builtins.sum(a) + """ + ) + + +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.umath", numpy_core_umath_transform +) +astroid.register_module_extender( + astroid.MANAGER, "numpy.random.mtrand", numpy_random_mtrand_transform +) +astroid.register_module_extender( + astroid.MANAGER, "numpy.core.numerictypes", numpy_core_numerictypes_transform +) +astroid.register_module_extender(astroid.MANAGER, "numpy", numpy_funcs) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_pkg_resources.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_pkg_resources.py new file mode 100644 index 0000000..25e7649 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_pkg_resources.py @@ -0,0 +1,75 @@ +# Copyright (c) 2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +import astroid +from astroid import parse +from astroid import inference_tip +from astroid import register_module_extender +from astroid import MANAGER + + +def pkg_resources_transform(): + return parse( + """ +def require(*requirements): + return pkg_resources.working_set.require(*requirements) + +def run_script(requires, script_name): + return pkg_resources.working_set.run_script(requires, script_name) + +def iter_entry_points(group, name=None): + return pkg_resources.working_set.iter_entry_points(group, name) + +def resource_exists(package_or_requirement, resource_name): + return get_provider(package_or_requirement).has_resource(resource_name) + +def resource_isdir(package_or_requirement, resource_name): + return get_provider(package_or_requirement).resource_isdir( + resource_name) + +def resource_filename(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name) + +def resource_stream(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name) + +def resource_string(package_or_requirement, resource_name): + return get_provider(package_or_requirement).get_resource_string( + self, resource_name) + +def resource_listdir(package_or_requirement, resource_name): + return get_provider(package_or_requirement).resource_listdir( + resource_name) + +def extraction_error(): + pass + +def get_cache_path(archive_name, names=()): + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name+'-tmp', *names) + return target_path + +def postprocess(tempname, filename): + pass + +def set_extraction_path(path): + pass + +def cleanup_resources(force=False): + pass + +def get_distribution(dist): + return Distribution(dist) + +_namespace_packages = {} +""" + ) + + +register_module_extender(MANAGER, "pkg_resources", pkg_resources_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_pytest.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_pytest.py new file mode 100644 index 0000000..d7e3ac8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_pytest.py @@ -0,0 +1,88 @@ +# Copyright (c) 2014-2016 Claudiu Popa +# Copyright (c) 2014 Jeff Quast +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2016 Florian Bruhin +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for pytest.""" +from __future__ import absolute_import +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder + + +def pytest_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +try: + import _pytest.mark + import _pytest.recwarn + import _pytest.runner + import _pytest.python + import _pytest.skipping + import _pytest.assertion +except ImportError: + pass +else: + deprecated_call = _pytest.recwarn.deprecated_call + warns = _pytest.recwarn.warns + + exit = _pytest.runner.exit + fail = _pytest.runner.fail + skip = _pytest.runner.skip + importorskip = _pytest.runner.importorskip + + xfail = _pytest.skipping.xfail + mark = _pytest.mark.MarkGenerator() + raises = _pytest.python.raises + + # New in pytest 3.0 + try: + approx = _pytest.python.approx + register_assert_rewrite = _pytest.assertion.register_assert_rewrite + except AttributeError: + pass + + +# Moved in pytest 3.0 + +try: + import _pytest.freeze_support + freeze_includes = _pytest.freeze_support.freeze_includes +except ImportError: + try: + import _pytest.genscript + freeze_includes = _pytest.genscript.freeze_includes + except ImportError: + pass + +try: + import _pytest.debugging + set_trace = _pytest.debugging.pytestPDB().set_trace +except ImportError: + try: + import _pytest.pdb + set_trace = _pytest.pdb.pytestPDB().set_trace + except ImportError: + pass + +try: + import _pytest.fixtures + fixture = _pytest.fixtures.fixture + yield_fixture = _pytest.fixtures.yield_fixture +except ImportError: + try: + import _pytest.python + fixture = _pytest.python.fixture + yield_fixture = _pytest.python.yield_fixture + except ImportError: + pass +""" + ) + + +register_module_extender(MANAGER, "pytest", pytest_transform) +register_module_extender(MANAGER, "py.test", pytest_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_qt.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_qt.py new file mode 100644 index 0000000..d65f218 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_qt.py @@ -0,0 +1,82 @@ +# Copyright (c) 2015-2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2017 Roy Wright +# Copyright (c) 2018 Ashley Whetter + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the PyQT library.""" + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid import nodes +from astroid import parse + + +def _looks_like_signal(node, signal_name="pyqtSignal"): + if "__class__" in node.instance_attrs: + try: + cls = node.instance_attrs["__class__"][0] + return cls.name == signal_name + except AttributeError: + # return False if the cls does not have a name attribute + pass + return False + + +def transform_pyqt_signal(node): + module = parse( + """ + class pyqtSignal(object): + def connect(self, slot, type=None, no_receiver_check=False): + pass + def disconnect(self, slot): + pass + def emit(self, *args): + pass + """ + ) + signal_cls = module["pyqtSignal"] + node.instance_attrs["emit"] = signal_cls["emit"] + node.instance_attrs["disconnect"] = signal_cls["disconnect"] + node.instance_attrs["connect"] = signal_cls["connect"] + + +def transform_pyside_signal(node): + module = parse( + """ + class NotPySideSignal(object): + def connect(self, receiver, type=None): + pass + def disconnect(self, receiver): + pass + def emit(self, *args): + pass + """ + ) + signal_cls = module["NotPySideSignal"] + node.instance_attrs["connect"] = signal_cls["connect"] + node.instance_attrs["disconnect"] = signal_cls["disconnect"] + node.instance_attrs["emit"] = signal_cls["emit"] + + +def pyqt4_qtcore_transform(): + return AstroidBuilder(MANAGER).string_build( + """ + +def SIGNAL(signal_name): pass + +class QObject(object): + def emit(self, signal): pass +""" + ) + + +register_module_extender(MANAGER, "PyQt4.QtCore", pyqt4_qtcore_transform) +MANAGER.register_transform(nodes.FunctionDef, transform_pyqt_signal, _looks_like_signal) +MANAGER.register_transform( + nodes.ClassDef, + transform_pyside_signal, + lambda node: node.qname() == "PySide.QtCore.Signal", +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_random.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_random.py new file mode 100644 index 0000000..5ec858a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_random.py @@ -0,0 +1,75 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import random + +import astroid +from astroid import helpers +from astroid import MANAGER + + +ACCEPTED_ITERABLES_FOR_SAMPLE = (astroid.List, astroid.Set, astroid.Tuple) + + +def _clone_node_with_lineno(node, parent, lineno): + cls = node.__class__ + other_fields = node._other_fields + _astroid_fields = node._astroid_fields + init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent} + postinit_params = {param: getattr(node, param) for param in _astroid_fields} + if other_fields: + init_params.update({param: getattr(node, param) for param in other_fields}) + new_node = cls(**init_params) + if hasattr(node, "postinit") and _astroid_fields: + new_node.postinit(**postinit_params) + return new_node + + +def infer_random_sample(node, context=None): + if len(node.args) != 2: + raise astroid.UseInferenceDefault + + length = node.args[1] + if not isinstance(length, astroid.Const): + raise astroid.UseInferenceDefault + if not isinstance(length.value, int): + raise astroid.UseInferenceDefault + + inferred_sequence = helpers.safe_infer(node.args[0], context=context) + if not inferred_sequence: + raise astroid.UseInferenceDefault + + if not isinstance(inferred_sequence, ACCEPTED_ITERABLES_FOR_SAMPLE): + raise astroid.UseInferenceDefault + + if length.value > len(inferred_sequence.elts): + # In this case, this will raise a ValueError + raise astroid.UseInferenceDefault + + try: + elts = random.sample(inferred_sequence.elts, length.value) + except ValueError: + raise astroid.UseInferenceDefault + + new_node = astroid.List( + lineno=node.lineno, col_offset=node.col_offset, parent=node.scope() + ) + new_elts = [ + _clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno) + for elt in elts + ] + new_node.postinit(new_elts) + return iter((new_node,)) + + +def _looks_like_random_sample(node): + func = node.func + if isinstance(func, astroid.Attribute): + return func.attrname == "sample" + if isinstance(func, astroid.Name): + return func.name == "sample" + return False + + +MANAGER.register_transform( + astroid.Call, astroid.inference_tip(infer_random_sample), _looks_like_random_sample +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_re.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_re.py new file mode 100644 index 0000000..c7ee51a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_re.py @@ -0,0 +1,36 @@ +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import sys +import astroid + +PY36 = sys.version_info >= (3, 6) + +if PY36: + # Since Python 3.6 there is the RegexFlag enum + # where every entry will be exposed via updating globals() + + def _re_transform(): + return astroid.parse( + """ + import sre_compile + ASCII = sre_compile.SRE_FLAG_ASCII + IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE + LOCALE = sre_compile.SRE_FLAG_LOCALE + UNICODE = sre_compile.SRE_FLAG_UNICODE + MULTILINE = sre_compile.SRE_FLAG_MULTILINE + DOTALL = sre_compile.SRE_FLAG_DOTALL + VERBOSE = sre_compile.SRE_FLAG_VERBOSE + A = ASCII + I = IGNORECASE + L = LOCALE + U = UNICODE + M = MULTILINE + S = DOTALL + X = VERBOSE + TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE + T = TEMPLATE + DEBUG = sre_compile.SRE_FLAG_DEBUG + """ + ) + + astroid.register_module_extender(astroid.MANAGER, "re", _re_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_six.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_six.py new file mode 100644 index 0000000..b342fbf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_six.py @@ -0,0 +1,200 @@ +# Copyright (c) 2014-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +"""Astroid hooks for six module.""" + +from textwrap import dedent + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid.exceptions import ( + AstroidBuildingError, + InferenceError, + AttributeInferenceError, +) +from astroid import nodes + + +SIX_ADD_METACLASS = "six.add_metaclass" + + +def _indent(text, prefix, predicate=None): + """Adds 'prefix' to the beginning of selected lines in 'text'. + + If 'predicate' is provided, 'prefix' will only be added to the lines + where 'predicate(line)' is True. If 'predicate' is not provided, + it will default to adding 'prefix' to all non-empty lines that do not + consist solely of whitespace characters. + """ + if predicate is None: + predicate = lambda line: line.strip() + + def prefixed_lines(): + for line in text.splitlines(True): + yield prefix + line if predicate(line) else line + + return "".join(prefixed_lines()) + + +_IMPORTS = """ +import _io +cStringIO = _io.StringIO +filter = filter +from itertools import filterfalse +input = input +from sys import intern +map = map +range = range +from imp import reload as reload_module +from functools import reduce +from shlex import quote as shlex_quote +from io import StringIO +from collections import UserDict, UserList, UserString +xrange = range +zip = zip +from itertools import zip_longest +import builtins +import configparser +import copyreg +import _dummy_thread +import http.cookiejar as http_cookiejar +import http.cookies as http_cookies +import html.entities as html_entities +import html.parser as html_parser +import http.client as http_client +import http.server as http_server +BaseHTTPServer = CGIHTTPServer = SimpleHTTPServer = http.server +import pickle as cPickle +import queue +import reprlib +import socketserver +import _thread +import winreg +import xmlrpc.server as xmlrpc_server +import xmlrpc.client as xmlrpc_client +import urllib.robotparser as urllib_robotparser +import email.mime.multipart as email_mime_multipart +import email.mime.nonmultipart as email_mime_nonmultipart +import email.mime.text as email_mime_text +import email.mime.base as email_mime_base +import urllib.parse as urllib_parse +import urllib.error as urllib_error +import tkinter +import tkinter.dialog as tkinter_dialog +import tkinter.filedialog as tkinter_filedialog +import tkinter.scrolledtext as tkinter_scrolledtext +import tkinter.simpledialog as tkinder_simpledialog +import tkinter.tix as tkinter_tix +import tkinter.ttk as tkinter_ttk +import tkinter.constants as tkinter_constants +import tkinter.dnd as tkinter_dnd +import tkinter.colorchooser as tkinter_colorchooser +import tkinter.commondialog as tkinter_commondialog +import tkinter.filedialog as tkinter_tkfiledialog +import tkinter.font as tkinter_font +import tkinter.messagebox as tkinter_messagebox +import urllib +import urllib.request as urllib_request +import urllib.robotparser as urllib_robotparser +import urllib.parse as urllib_parse +import urllib.error as urllib_error +""" + + +def six_moves_transform(): + code = dedent( + """ + class Moves(object): + {} + moves = Moves() + """ + ).format(_indent(_IMPORTS, " ")) + module = AstroidBuilder(MANAGER).string_build(code) + module.name = "six.moves" + return module + + +def _six_fail_hook(modname): + """Fix six.moves imports due to the dynamic nature of this + class. + + Construct a pseudo-module which contains all the necessary imports + for six + + :param modname: Name of failed module + :type modname: str + + :return: An astroid module + :rtype: nodes.Module + """ + + attribute_of = modname != "six.moves" and modname.startswith("six.moves") + if modname != "six.moves" and not attribute_of: + raise AstroidBuildingError(modname=modname) + module = AstroidBuilder(MANAGER).string_build(_IMPORTS) + module.name = "six.moves" + if attribute_of: + # Facilitate import of submodules in Moves + start_index = len(module.name) + attribute = modname[start_index:].lstrip(".").replace(".", "_") + try: + import_attr = module.getattr(attribute)[0] + except AttributeInferenceError: + raise AstroidBuildingError(modname=modname) + if isinstance(import_attr, nodes.Import): + submodule = MANAGER.ast_from_module_name(import_attr.names[0][0]) + return submodule + # Let dummy submodule imports pass through + # This will cause an Uninferable result, which is okay + return module + + +def _looks_like_decorated_with_six_add_metaclass(node): + if not node.decorators: + return False + + for decorator in node.decorators.nodes: + if not isinstance(decorator, nodes.Call): + continue + if decorator.func.as_string() == SIX_ADD_METACLASS: + return True + return False + + +def transform_six_add_metaclass(node): + """Check if the given class node is decorated with *six.add_metaclass* + + If so, inject its argument as the metaclass of the underlying class. + """ + if not node.decorators: + return + + for decorator in node.decorators.nodes: + if not isinstance(decorator, nodes.Call): + continue + + try: + func = next(decorator.func.infer()) + except InferenceError: + continue + if func.qname() == SIX_ADD_METACLASS and decorator.args: + metaclass = decorator.args[0] + node._metaclass = metaclass + return node + + +register_module_extender(MANAGER, "six", six_moves_transform) +register_module_extender( + MANAGER, "requests.packages.urllib3.packages.six", six_moves_transform +) +MANAGER.register_failed_import_hook(_six_fail_hook) +MANAGER.register_transform( + nodes.ClassDef, + transform_six_add_metaclass, + _looks_like_decorated_with_six_add_metaclass, +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_ssl.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_ssl.py new file mode 100644 index 0000000..a42e04c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_ssl.py @@ -0,0 +1,73 @@ +# Copyright (c) 2016 Claudiu Popa +# Copyright (c) 2016 Ceridwen + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the ssl library.""" + +from astroid import MANAGER, register_module_extender +from astroid.builder import AstroidBuilder +from astroid import nodes +from astroid import parse + + +def ssl_transform(): + return parse( + """ + from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION + from _ssl import _SSLContext, MemoryBIO + from _ssl import ( + SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, + SSLSyscallError, SSLEOFError, + ) + from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED + from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj + from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes + try: + from _ssl import RAND_egd + except ImportError: + # LibreSSL does not provide RAND_egd + pass + from _ssl import (OP_ALL, OP_CIPHER_SERVER_PREFERENCE, + OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3, + OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2, + OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE) + + from _ssl import (ALERT_DESCRIPTION_ACCESS_DENIED, ALERT_DESCRIPTION_BAD_CERTIFICATE, + ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE, + ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE, + ALERT_DESCRIPTION_BAD_RECORD_MAC, + ALERT_DESCRIPTION_CERTIFICATE_EXPIRED, + ALERT_DESCRIPTION_CERTIFICATE_REVOKED, + ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN, + ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE, + ALERT_DESCRIPTION_CLOSE_NOTIFY, ALERT_DESCRIPTION_DECODE_ERROR, + ALERT_DESCRIPTION_DECOMPRESSION_FAILURE, + ALERT_DESCRIPTION_DECRYPT_ERROR, + ALERT_DESCRIPTION_HANDSHAKE_FAILURE, + ALERT_DESCRIPTION_ILLEGAL_PARAMETER, + ALERT_DESCRIPTION_INSUFFICIENT_SECURITY, + ALERT_DESCRIPTION_INTERNAL_ERROR, + ALERT_DESCRIPTION_NO_RENEGOTIATION, + ALERT_DESCRIPTION_PROTOCOL_VERSION, + ALERT_DESCRIPTION_RECORD_OVERFLOW, + ALERT_DESCRIPTION_UNEXPECTED_MESSAGE, + ALERT_DESCRIPTION_UNKNOWN_CA, + ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY, + ALERT_DESCRIPTION_UNRECOGNIZED_NAME, + ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE, + ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION, + ALERT_DESCRIPTION_USER_CANCELLED) + from _ssl import (SSL_ERROR_EOF, SSL_ERROR_INVALID_ERROR_CODE, SSL_ERROR_SSL, + SSL_ERROR_SYSCALL, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_READ, + SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_X509_LOOKUP, SSL_ERROR_ZERO_RETURN) + from _ssl import VERIFY_CRL_CHECK_CHAIN, VERIFY_CRL_CHECK_LEAF, VERIFY_DEFAULT, VERIFY_X509_STRICT + from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN + from _ssl import _OPENSSL_API_VERSION + from _ssl import PROTOCOL_SSLv23, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2 + """ + ) + + +register_module_extender(MANAGER, "ssl", ssl_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_subprocess.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_subprocess.py new file mode 100644 index 0000000..078b79f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_subprocess.py @@ -0,0 +1,107 @@ +# Copyright (c) 2016-2017 Claudiu Popa +# Copyright (c) 2017 Hugo +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import sys +import textwrap + +import six + +import astroid + + +PY34 = sys.version_info >= (3, 4) +PY36 = sys.version_info >= (3, 6) +PY33 = sys.version_info >= (3, 3) + + +def _subprocess_transform(): + if six.PY3: + communicate = (bytes("string", "ascii"), bytes("string", "ascii")) + communicate_signature = "def communicate(self, input=None, timeout=None)" + if PY36: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=(), *, + encoding=None, errors=None): + pass + """ + else: + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0, restore_signals=True, + start_new_session=False, pass_fds=()): + pass + """ + else: + communicate = ("string", "string") + communicate_signature = "def communicate(self, input=None)" + init = """ + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0): + pass + """ + if PY34: + wait_signature = "def wait(self, timeout=None)" + else: + wait_signature = "def wait(self)" + if six.PY3: + ctx_manager = """ + def __enter__(self): return self + def __exit__(self, *args): pass + """ + else: + ctx_manager = "" + py3_args = "" + if PY33: + py3_args = "args = []" + code = textwrap.dedent( + """ + class Popen(object): + returncode = pid = 0 + stdin = stdout = stderr = file() + %(py3_args)s + + %(communicate_signature)s: + return %(communicate)r + %(wait_signature)s: + return self.returncode + def poll(self): + return self.returncode + def send_signal(self, signal): + pass + def terminate(self): + pass + def kill(self): + pass + %(ctx_manager)s + """ + % { + "communicate": communicate, + "communicate_signature": communicate_signature, + "wait_signature": wait_signature, + "ctx_manager": ctx_manager, + "py3_args": py3_args, + } + ) + + init_lines = textwrap.dedent(init).splitlines() + indented_init = "\n".join(" " * 4 + line for line in init_lines) + code += indented_init + return astroid.parse(code) + + +astroid.register_module_extender(astroid.MANAGER, "subprocess", _subprocess_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_threading.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_threading.py new file mode 100644 index 0000000..77f5bde --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_threading.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 Claudiu Popa +# Copyright (c) 2017 Łukasz Rogalski + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +import astroid + + +def _thread_transform(): + return astroid.parse( + """ + class lock(object): + def acquire(self, blocking=True, timeout=-1): + pass + def release(self): + pass + def __enter__(self): + return True + def __exit__(self, *args): + pass + + def Lock(): + return lock() + """ + ) + + +astroid.register_module_extender(astroid.MANAGER, "threading", _thread_transform) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_typing.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_typing.py new file mode 100644 index 0000000..cd9a2f4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_typing.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017-2018 Claudiu Popa +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 David Euresti +# Copyright (c) 2018 Bryce Guinta + +"""Astroid hooks for typing.py support.""" +import typing + +from astroid import ( + MANAGER, + UseInferenceDefault, + extract_node, + inference_tip, + nodes, + InferenceError, +) + + +TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"} +TYPING_TYPEVARS = {"TypeVar", "NewType"} +TYPING_TYPEVARS_QUALIFIED = {"typing.TypeVar", "typing.NewType"} +TYPING_TYPE_TEMPLATE = """ +class Meta(type): + def __getitem__(self, item): + return self + +class {0}(metaclass=Meta): + pass +""" +TYPING_MEMBERS = set(typing.__all__) + + +def looks_like_typing_typevar_or_newtype(node): + func = node.func + if isinstance(func, nodes.Attribute): + return func.attrname in TYPING_TYPEVARS + if isinstance(func, nodes.Name): + return func.name in TYPING_TYPEVARS + return False + + +def infer_typing_typevar_or_newtype(node, context=None): + """Infer a typing.TypeVar(...) or typing.NewType(...) call""" + try: + func = next(node.func.infer(context=context)) + except InferenceError as exc: + raise UseInferenceDefault from exc + + if func.qname() not in TYPING_TYPEVARS_QUALIFIED: + raise UseInferenceDefault + if not node.args: + raise UseInferenceDefault + + typename = node.args[0].as_string().strip("'") + node = extract_node(TYPING_TYPE_TEMPLATE.format(typename)) + return node.infer(context=context) + + +def _looks_like_typing_subscript(node): + """Try to figure out if a Subscript node *might* be a typing-related subscript""" + if isinstance(node, nodes.Name): + return node.name in TYPING_MEMBERS + elif isinstance(node, nodes.Attribute): + return node.attrname in TYPING_MEMBERS + elif isinstance(node, nodes.Subscript): + return _looks_like_typing_subscript(node.value) + return False + + +def infer_typing_attr(node, context=None): + """Infer a typing.X[...] subscript""" + try: + value = next(node.value.infer()) + except InferenceError as exc: + raise UseInferenceDefault from exc + + if not value.qname().startswith("typing."): + raise UseInferenceDefault + + node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1])) + return node.infer(context=context) + + +MANAGER.register_transform( + nodes.Call, + inference_tip(infer_typing_typevar_or_newtype), + looks_like_typing_typevar_or_newtype, +) +MANAGER.register_transform( + nodes.Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_uuid.py b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_uuid.py new file mode 100644 index 0000000..8bda631 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/brain/brain_uuid.py @@ -0,0 +1,20 @@ +# Copyright (c) 2017 Claudiu Popa + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Astroid hooks for the UUID module.""" + + +from astroid import MANAGER +from astroid import nodes + + +def _patch_uuid_class(node): + # The .int member is patched using __dict__ + node.locals["int"] = [nodes.Const(0, parent=node)] + + +MANAGER.register_transform( + nodes.ClassDef, _patch_uuid_class, lambda node: node.qname() == "uuid.UUID" +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/builder.py b/basic python programmes/venv/Lib/site-packages/astroid/builder.py new file mode 100644 index 0000000..ac71093 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/builder.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013 Phil Schaf +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014-2015 Google, Inc. +# Copyright (c) 2014 Alexander Presnyakov +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""The AstroidBuilder makes astroid from living object and / or from _ast + +The builder is not thread safe and can't be used to parse different sources +at the same time. +""" + +import os +import textwrap +from tokenize import detect_encoding + +from astroid._ast import _parse +from astroid import bases +from astroid import exceptions +from astroid import manager +from astroid import modutils +from astroid import raw_building +from astroid import rebuilder +from astroid import nodes +from astroid import util + +# The name of the transient function that is used to +# wrap expressions to be extracted when calling +# extract_node. +_TRANSIENT_FUNCTION = "__" + +# The comment used to select a statement to be extracted +# when calling extract_node. +_STATEMENT_SELECTOR = "#@" + +MANAGER = manager.AstroidManager() + + +def open_source_file(filename): + with open(filename, "rb") as byte_stream: + encoding = detect_encoding(byte_stream.readline)[0] + stream = open(filename, "r", newline=None, encoding=encoding) + data = stream.read() + return stream, encoding, data + + +def _can_assign_attr(node, attrname): + try: + slots = node.slots() + except NotImplementedError: + pass + else: + if slots and attrname not in {slot.value for slot in slots}: + return False + return True + + +class AstroidBuilder(raw_building.InspectBuilder): + """Class for building an astroid tree from source code or from a live module. + + The param *manager* specifies the manager class which should be used. + If no manager is given, then the default one will be used. The + param *apply_transforms* determines if the transforms should be + applied after the tree was built from source or from a live object, + by default being True. + """ + + # pylint: disable=redefined-outer-name + def __init__(self, manager=None, apply_transforms=True): + super(AstroidBuilder, self).__init__() + self._manager = manager or MANAGER + self._apply_transforms = apply_transforms + + def module_build(self, module, modname=None): + """Build an astroid from a living module instance.""" + node = None + path = getattr(module, "__file__", None) + if path is not None: + path_, ext = os.path.splitext(modutils._path_from_filename(path)) + if ext in (".py", ".pyc", ".pyo") and os.path.exists(path_ + ".py"): + node = self.file_build(path_ + ".py", modname) + if node is None: + # this is a built-in module + # get a partial representation by introspection + node = self.inspect_build(module, modname=modname, path=path) + if self._apply_transforms: + # We have to handle transformation by ourselves since the + # rebuilder isn't called for builtin nodes + node = self._manager.visit_transforms(node) + return node + + def file_build(self, path, modname=None): + """Build astroid from a source code file (i.e. from an ast) + + *path* is expected to be a python source file + """ + try: + stream, encoding, data = open_source_file(path) + except IOError as exc: + raise exceptions.AstroidBuildingError( + "Unable to load file {path}:\n{error}", + modname=modname, + path=path, + error=exc, + ) from exc + except (SyntaxError, LookupError) as exc: + raise exceptions.AstroidSyntaxError( + "Python 3 encoding specification error or unknown encoding:\n" + "{error}", + modname=modname, + path=path, + error=exc, + ) from exc + except UnicodeError as exc: # wrong encoding + # detect_encoding returns utf-8 if no encoding specified + raise exceptions.AstroidBuildingError( + "Wrong or no encoding specified for {filename}.", filename=path + ) from exc + with stream: + # get module name if necessary + if modname is None: + try: + modname = ".".join(modutils.modpath_from_file(path)) + except ImportError: + modname = os.path.splitext(os.path.basename(path))[0] + # build astroid representation + module = self._data_build(data, modname, path) + return self._post_build(module, encoding) + + def string_build(self, data, modname="", path=None): + """Build astroid from source code string.""" + module = self._data_build(data, modname, path) + module.file_bytes = data.encode("utf-8") + return self._post_build(module, "utf-8") + + def _post_build(self, module, encoding): + """Handles encoding and delayed nodes after a module has been built""" + module.file_encoding = encoding + self._manager.cache_module(module) + # post tree building steps after we stored the module in the cache: + for from_node in module._import_from_nodes: + if from_node.modname == "__future__": + for symbol, _ in from_node.names: + module.future_imports.add(symbol) + self.add_from_names_to_locals(from_node) + # handle delayed assattr nodes + for delayed in module._delayed_assattr: + self.delayed_assattr(delayed) + + # Visit the transforms + if self._apply_transforms: + module = self._manager.visit_transforms(module) + return module + + def _data_build(self, data, modname, path): + """Build tree node from data and add some informations""" + try: + node = _parse(data + "\n") + except (TypeError, ValueError, SyntaxError) as exc: + raise exceptions.AstroidSyntaxError( + "Parsing Python code failed:\n{error}", + source=data, + modname=modname, + path=path, + error=exc, + ) from exc + if path is not None: + node_file = os.path.abspath(path) + else: + node_file = "" + if modname.endswith(".__init__"): + modname = modname[:-9] + package = True + else: + package = ( + path is not None + and os.path.splitext(os.path.basename(path))[0] == "__init__" + ) + builder = rebuilder.TreeRebuilder(self._manager) + module = builder.visit_module(node, modname, node_file, package) + module._import_from_nodes = builder._import_from_nodes + module._delayed_assattr = builder._delayed_assattr + return module + + def add_from_names_to_locals(self, node): + """Store imported names to the locals + + Resort the locals if coming from a delayed node + """ + _key_func = lambda node: node.fromlineno + + def sort_locals(my_list): + my_list.sort(key=_key_func) + + for (name, asname) in node.names: + if name == "*": + try: + imported = node.do_import_module() + except exceptions.AstroidBuildingError: + continue + for name in imported.public_names(): + node.parent.set_local(name, node) + sort_locals(node.parent.scope().locals[name]) + else: + node.parent.set_local(asname or name, node) + sort_locals(node.parent.scope().locals[asname or name]) + + def delayed_assattr(self, node): + """Visit a AssAttr node + + This adds name to locals and handle members definition. + """ + try: + frame = node.frame() + for inferred in node.expr.infer(): + if inferred is util.Uninferable: + continue + try: + if inferred.__class__ is bases.Instance: + inferred = inferred._proxied + iattrs = inferred.instance_attrs + if not _can_assign_attr(inferred, node.attrname): + continue + elif isinstance(inferred, bases.Instance): + # Const, Tuple, ... we may be wrong, may be not, but + # anyway we don't want to pollute builtin's namespace + continue + elif inferred.is_function: + iattrs = inferred.instance_attrs + else: + iattrs = inferred.locals + except AttributeError: + # XXX log error + continue + values = iattrs.setdefault(node.attrname, []) + if node in values: + continue + # get assign in __init__ first XXX useful ? + if ( + frame.name == "__init__" + and values + and values[0].frame().name != "__init__" + ): + values.insert(0, node) + else: + values.append(node) + except exceptions.InferenceError: + pass + + +def build_namespace_package_module(name, path): + return nodes.Module(name, doc="", path=path, package=True) + + +def parse(code, module_name="", path=None, apply_transforms=True): + """Parses a source string in order to obtain an astroid AST from it + + :param str code: The code for the module. + :param str module_name: The name for the module, if any + :param str path: The path for the module + :param bool apply_transforms: + Apply the transforms for the give code. Use it if you + don't want the default transforms to be applied. + """ + code = textwrap.dedent(code) + builder = AstroidBuilder(manager=MANAGER, apply_transforms=apply_transforms) + return builder.string_build(code, modname=module_name, path=path) + + +def _extract_expressions(node): + """Find expressions in a call to _TRANSIENT_FUNCTION and extract them. + + The function walks the AST recursively to search for expressions that + are wrapped into a call to _TRANSIENT_FUNCTION. If it finds such an + expression, it completely removes the function call node from the tree, + replacing it by the wrapped expression inside the parent. + + :param node: An astroid node. + :type node: astroid.bases.NodeNG + :yields: The sequence of wrapped expressions on the modified tree + expression can be found. + """ + if ( + isinstance(node, nodes.Call) + and isinstance(node.func, nodes.Name) + and node.func.name == _TRANSIENT_FUNCTION + ): + real_expr = node.args[0] + real_expr.parent = node.parent + # Search for node in all _astng_fields (the fields checked when + # get_children is called) of its parent. Some of those fields may + # be lists or tuples, in which case the elements need to be checked. + # When we find it, replace it by real_expr, so that the AST looks + # like no call to _TRANSIENT_FUNCTION ever took place. + for name in node.parent._astroid_fields: + child = getattr(node.parent, name) + if isinstance(child, (list, tuple)): + for idx, compound_child in enumerate(child): + if compound_child is node: + child[idx] = real_expr + elif child is node: + setattr(node.parent, name, real_expr) + yield real_expr + else: + for child in node.get_children(): + yield from _extract_expressions(child) + + +def _find_statement_by_line(node, line): + """Extracts the statement on a specific line from an AST. + + If the line number of node matches line, it will be returned; + otherwise its children are iterated and the function is called + recursively. + + :param node: An astroid node. + :type node: astroid.bases.NodeNG + :param line: The line number of the statement to extract. + :type line: int + :returns: The statement on the line, or None if no statement for the line + can be found. + :rtype: astroid.bases.NodeNG or None + """ + if isinstance(node, (nodes.ClassDef, nodes.FunctionDef)): + # This is an inaccuracy in the AST: the nodes that can be + # decorated do not carry explicit information on which line + # the actual definition (class/def), but .fromline seems to + # be close enough. + node_line = node.fromlineno + else: + node_line = node.lineno + + if node_line == line: + return node + + for child in node.get_children(): + result = _find_statement_by_line(child, line) + if result: + return result + + return None + + +def extract_node(code, module_name=""): + """Parses some Python code as a module and extracts a designated AST node. + + Statements: + To extract one or more statement nodes, append #@ to the end of the line + + Examples: + >>> def x(): + >>> def y(): + >>> return 1 #@ + + The return statement will be extracted. + + >>> class X(object): + >>> def meth(self): #@ + >>> pass + + The function object 'meth' will be extracted. + + Expressions: + To extract arbitrary expressions, surround them with the fake + function call __(...). After parsing, the surrounded expression + will be returned and the whole AST (accessible via the returned + node's parent attribute) will look like the function call was + never there in the first place. + + Examples: + >>> a = __(1) + + The const node will be extracted. + + >>> def x(d=__(foo.bar)): pass + + The node containing the default argument will be extracted. + + >>> def foo(a, b): + >>> return 0 < __(len(a)) < b + + The node containing the function call 'len' will be extracted. + + If no statements or expressions are selected, the last toplevel + statement will be returned. + + If the selected statement is a discard statement, (i.e. an expression + turned into a statement), the wrapped expression is returned instead. + + For convenience, singleton lists are unpacked. + + :param str code: A piece of Python code that is parsed as + a module. Will be passed through textwrap.dedent first. + :param str module_name: The name of the module. + :returns: The designated node from the parse tree, or a list of nodes. + :rtype: astroid.bases.NodeNG, or a list of nodes. + """ + + def _extract(node): + if isinstance(node, nodes.Expr): + return node.value + + return node + + requested_lines = [] + for idx, line in enumerate(code.splitlines()): + if line.strip().endswith(_STATEMENT_SELECTOR): + requested_lines.append(idx + 1) + + tree = parse(code, module_name=module_name) + if not tree.body: + raise ValueError("Empty tree, cannot extract from it") + + extracted = [] + if requested_lines: + extracted = [_find_statement_by_line(tree, line) for line in requested_lines] + + # Modifies the tree. + extracted.extend(_extract_expressions(tree)) + + if not extracted: + extracted.append(tree.body[-1]) + + extracted = [_extract(node) for node in extracted] + if len(extracted) == 1: + return extracted[0] + return extracted diff --git a/basic python programmes/venv/Lib/site-packages/astroid/context.py b/basic python programmes/venv/Lib/site-packages/astroid/context.py new file mode 100644 index 0000000..931bbf5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/context.py @@ -0,0 +1,173 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Various context related utilities, including inference and call contexts.""" + +import pprint +from typing import Optional + + +class InferenceContext: + """Provide context for inference + + Store already inferred nodes to save time + Account for already visited nodes to infinite stop infinite recursion + """ + + __slots__ = ( + "path", + "lookupname", + "callcontext", + "boundnode", + "inferred", + "extra_context", + ) + + def __init__(self, path=None, inferred=None): + self.path = path or set() + """ + :type: set(tuple(NodeNG, optional(str))) + + Path of visited nodes and their lookupname + + Currently this key is ``(node, context.lookupname)`` + """ + self.lookupname = None + """ + :type: optional[str] + + The original name of the node + + e.g. + foo = 1 + The inference of 'foo' is nodes.Const(1) but the lookup name is 'foo' + """ + self.callcontext = None + """ + :type: optional[CallContext] + + The call arguments and keywords for the given context + """ + self.boundnode = None + """ + :type: optional[NodeNG] + + The bound node of the given context + + e.g. the bound node of object.__new__(cls) is the object node + """ + self.inferred = inferred or {} + """ + :type: dict(seq, seq) + + Inferred node contexts to their mapped results + Currently the key is ``(node, lookupname, callcontext, boundnode)`` + and the value is tuple of the inferred results + """ + self.extra_context = {} + """ + :type: dict(NodeNG, Context) + + Context that needs to be passed down through call stacks + for call arguments + """ + + def push(self, node): + """Push node into inference path + + :return: True if node is already in context path else False + :rtype: bool + + Allows one to see if the given node has already + been looked at for this inference context""" + name = self.lookupname + if (node, name) in self.path: + return True + + self.path.add((node, name)) + return False + + def clone(self): + """Clone inference path + + For example, each side of a binary operation (BinOp) + starts with the same context but diverge as each side is inferred + so the InferenceContext will need be cloned""" + # XXX copy lookupname/callcontext ? + clone = InferenceContext(set(self.path), inferred=self.inferred) + clone.callcontext = self.callcontext + clone.boundnode = self.boundnode + clone.extra_context = self.extra_context + return clone + + def cache_generator(self, key, generator): + """Cache result of generator into dictionary + + Used to cache inference results""" + results = [] + for result in generator: + results.append(result) + yield result + + self.inferred[key] = tuple(results) + + def __str__(self): + state = ( + "%s=%s" + % (field, pprint.pformat(getattr(self, field), width=80 - len(field))) + for field in self.__slots__ + ) + return "%s(%s)" % (type(self).__name__, ",\n ".join(state)) + + +class CallContext: + """Holds information for a call site.""" + + __slots__ = ("args", "keywords") + + def __init__(self, args, keywords=None): + """ + :param List[NodeNG] args: Call positional arguments + :param Union[List[nodes.Keyword], None] keywords: Call keywords + """ + self.args = args + if keywords: + keywords = [(arg.arg, arg.value) for arg in keywords] + else: + keywords = [] + self.keywords = keywords + + +def copy_context(context: Optional[InferenceContext]) -> InferenceContext: + """Clone a context if given, or return a fresh contexxt""" + if context is not None: + return context.clone() + + return InferenceContext() + + +def bind_context_to_node(context, node): + """Give a context a boundnode + to retrieve the correct function name or attribute value + with from further inference. + + Do not use an existing context since the boundnode could then + be incorrectly propagated higher up in the call stack. + + :param context: Context to use + :type context: Optional(context) + + :param node: Node to do name lookups from + :type node NodeNG: + + :returns: A new context + :rtype: InferenceContext + """ + context = copy_context(context) + context.boundnode = node + return context diff --git a/basic python programmes/venv/Lib/site-packages/astroid/decorators.py b/basic python programmes/venv/Lib/site-packages/astroid/decorators.py new file mode 100644 index 0000000..433c230 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/decorators.py @@ -0,0 +1,138 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 HoverHell +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +""" A few useful function/method decorators.""" + +import functools + +import wrapt + +from astroid import context as contextmod +from astroid import exceptions +from astroid import util + + +@wrapt.decorator +def cached(func, instance, args, kwargs): + """Simple decorator to cache result of method calls without args.""" + cache = getattr(instance, "__cache", None) + if cache is None: + instance.__cache = cache = {} + try: + return cache[func] + except KeyError: + cache[func] = result = func(*args, **kwargs) + return result + + +class cachedproperty: + """ Provides a cached property equivalent to the stacking of + @cached and @property, but more efficient. + + After first usage, the becomes part of the object's + __dict__. Doing: + + del obj. empties the cache. + + Idea taken from the pyramid_ framework and the mercurial_ project. + + .. _pyramid: http://pypi.python.org/pypi/pyramid + .. _mercurial: http://pypi.python.org/pypi/Mercurial + """ + + __slots__ = ("wrapped",) + + def __init__(self, wrapped): + try: + wrapped.__name__ + except AttributeError as exc: + raise TypeError("%s must have a __name__ attribute" % wrapped) from exc + self.wrapped = wrapped + + @property + def __doc__(self): + doc = getattr(self.wrapped, "__doc__", None) + return "%s" % ( + "\n%s" % doc if doc else "" + ) + + def __get__(self, inst, objtype=None): + if inst is None: + return self + val = self.wrapped(inst) + setattr(inst, self.wrapped.__name__, val) + return val + + +def path_wrapper(func): + """return the given infer function wrapped to handle the path + + Used to stop inference if the node has already been looked + at for a given `InferenceContext` to prevent infinite recursion + """ + + @functools.wraps(func) + def wrapped(node, context=None, _func=func, **kwargs): + """wrapper function handling context""" + if context is None: + context = contextmod.InferenceContext() + if context.push(node): + return None + + yielded = set() + generator = _func(node, context, **kwargs) + try: + while True: + res = next(generator) + # unproxy only true instance, not const, tuple, dict... + if res.__class__.__name__ == "Instance": + ares = res._proxied + else: + ares = res + if ares not in yielded: + yield res + yielded.add(ares) + except StopIteration as error: + if error.args: + return error.args[0] + return None + + return wrapped + + +@wrapt.decorator +def yes_if_nothing_inferred(func, instance, args, kwargs): + inferred = False + for node in func(*args, **kwargs): + inferred = True + yield node + if not inferred: + yield util.Uninferable + + +@wrapt.decorator +def raise_if_nothing_inferred(func, instance, args, kwargs): + inferred = False + try: + generator = func(*args, **kwargs) + while True: + yield next(generator) + inferred = True + except StopIteration as error: + if not inferred: + if error.args: + # pylint: disable=not-a-mapping + raise exceptions.InferenceError(**error.args[0]) + else: + raise exceptions.InferenceError( + "StopIteration raised without any error information." + ) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/exceptions.py b/basic python programmes/venv/Lib/site-packages/astroid/exceptions.py new file mode 100644 index 0000000..7e9d655 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/exceptions.py @@ -0,0 +1,230 @@ +# Copyright (c) 2007, 2009-2010, 2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains exceptions used in the astroid library +""" +from astroid import util + + +class AstroidError(Exception): + """base exception class for all astroid related exceptions + + AstroidError and its subclasses are structured, intended to hold + objects representing state when the exception is thrown. Field + values are passed to the constructor as keyword-only arguments. + Each subclass has its own set of standard fields, but use your + best judgment to decide whether a specific exception instance + needs more or fewer fields for debugging. Field values may be + used to lazily generate the error message: self.message.format() + will be called with the field names and values supplied as keyword + arguments. + """ + + def __init__(self, message="", **kws): + super(AstroidError, self).__init__(message) + self.message = message + for key, value in kws.items(): + setattr(self, key, value) + + def __str__(self): + return self.message.format(**vars(self)) + + +class AstroidBuildingError(AstroidError): + """exception class when we are unable to build an astroid representation + + Standard attributes: + modname: Name of the module that AST construction failed for. + error: Exception raised during construction. + """ + + def __init__(self, message="Failed to import module {modname}.", **kws): + super(AstroidBuildingError, self).__init__(message, **kws) + + +class AstroidImportError(AstroidBuildingError): + """Exception class used when a module can't be imported by astroid.""" + + +class TooManyLevelsError(AstroidImportError): + """Exception class which is raised when a relative import was beyond the top-level. + + Standard attributes: + level: The level which was attempted. + name: the name of the module on which the relative import was attempted. + """ + + level = None + name = None + + def __init__( + self, + message="Relative import with too many levels " "({level}) for module {name!r}", + **kws + ): + super(TooManyLevelsError, self).__init__(message, **kws) + + +class AstroidSyntaxError(AstroidBuildingError): + """Exception class used when a module can't be parsed.""" + + +class NoDefault(AstroidError): + """raised by function's `default_value` method when an argument has + no default value + + Standard attributes: + func: Function node. + name: Name of argument without a default. + """ + + func = None + name = None + + def __init__(self, message="{func!r} has no default for {name!r}.", **kws): + super(NoDefault, self).__init__(message, **kws) + + +class ResolveError(AstroidError): + """Base class of astroid resolution/inference error. + + ResolveError is not intended to be raised. + + Standard attributes: + context: InferenceContext object. + """ + + context = None + + +class MroError(ResolveError): + """Error raised when there is a problem with method resolution of a class. + + Standard attributes: + mros: A sequence of sequences containing ClassDef nodes. + cls: ClassDef node whose MRO resolution failed. + context: InferenceContext object. + """ + + mros = () + cls = None + + def __str__(self): + mro_names = ", ".join( + "({})".format(", ".join(b.name for b in m)) for m in self.mros + ) + return self.message.format(mros=mro_names, cls=self.cls) + + +class DuplicateBasesError(MroError): + """Error raised when there are duplicate bases in the same class bases.""" + + +class InconsistentMroError(MroError): + """Error raised when a class's MRO is inconsistent.""" + + +class SuperError(ResolveError): + """Error raised when there is a problem with a *super* call. + + Standard attributes: + *super_*: The Super instance that raised the exception. + context: InferenceContext object. + """ + + super_ = None + + def __str__(self): + return self.message.format(**vars(self.super_)) + + +class InferenceError(ResolveError): + """raised when we are unable to infer a node + + Standard attributes: + node: The node inference was called on. + context: InferenceContext object. + """ + + node = None + context = None + + def __init__(self, message="Inference failed for {node!r}.", **kws): + super(InferenceError, self).__init__(message, **kws) + + +# Why does this inherit from InferenceError rather than ResolveError? +# Changing it causes some inference tests to fail. +class NameInferenceError(InferenceError): + """Raised when a name lookup fails, corresponds to NameError. + + Standard attributes: + name: The name for which lookup failed, as a string. + scope: The node representing the scope in which the lookup occurred. + context: InferenceContext object. + """ + + name = None + scope = None + + def __init__(self, message="{name!r} not found in {scope!r}.", **kws): + super(NameInferenceError, self).__init__(message, **kws) + + +class AttributeInferenceError(ResolveError): + """Raised when an attribute lookup fails, corresponds to AttributeError. + + Standard attributes: + target: The node for which lookup failed. + attribute: The attribute for which lookup failed, as a string. + context: InferenceContext object. + """ + + target = None + attribute = None + + def __init__(self, message="{attribute!r} not found on {target!r}.", **kws): + super(AttributeInferenceError, self).__init__(message, **kws) + + +class UseInferenceDefault(Exception): + """exception to be raised in custom inference function to indicate that it + should go back to the default behaviour + """ + + +class _NonDeducibleTypeHierarchy(Exception): + """Raised when is_subtype / is_supertype can't deduce the relation between two types.""" + + +class AstroidIndexError(AstroidError): + """Raised when an Indexable / Mapping does not have an index / key.""" + + +class AstroidTypeError(AstroidError): + """Raised when a TypeError would be expected in Python code.""" + + +class InferenceOverwriteError(AstroidError): + """Raised when an inference tip is overwritten + + Currently only used for debugging. + """ + + +# Backwards-compatibility aliases +OperationError = util.BadOperationMessage +UnaryOperationError = util.BadUnaryOperationMessage +BinaryOperationError = util.BadBinaryOperationMessage + +SuperArgumentTypeError = SuperError +UnresolvableName = NameInferenceError +NotFoundError = AttributeInferenceError +AstroidBuildingException = AstroidBuildingError diff --git a/basic python programmes/venv/Lib/site-packages/astroid/helpers.py b/basic python programmes/venv/Lib/site-packages/astroid/helpers.py new file mode 100644 index 0000000..e58d191 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/helpers.py @@ -0,0 +1,272 @@ +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +Various helper utilities. +""" + +import builtins as builtins_mod + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import manager +from astroid import nodes +from astroid import raw_building +from astroid import scoped_nodes +from astroid import util + + +BUILTINS = builtins_mod.__name__ + + +def _build_proxy_class(cls_name, builtins): + proxy = raw_building.build_class(cls_name) + proxy.parent = builtins + return proxy + + +def _function_type(function, builtins): + if isinstance(function, scoped_nodes.Lambda): + if function.root().name == BUILTINS: + cls_name = "builtin_function_or_method" + else: + cls_name = "function" + elif isinstance(function, bases.BoundMethod): + cls_name = "method" + elif isinstance(function, bases.UnboundMethod): + cls_name = "function" + return _build_proxy_class(cls_name, builtins) + + +def _object_type(node, context=None): + astroid_manager = manager.AstroidManager() + builtins = astroid_manager.astroid_cache[BUILTINS] + context = context or contextmod.InferenceContext() + + for inferred in node.infer(context=context): + if isinstance(inferred, scoped_nodes.ClassDef): + if inferred.newstyle: + metaclass = inferred.metaclass() + if metaclass: + yield metaclass + continue + yield builtins.getattr("type")[0] + elif isinstance(inferred, (scoped_nodes.Lambda, bases.UnboundMethod)): + yield _function_type(inferred, builtins) + elif isinstance(inferred, scoped_nodes.Module): + yield _build_proxy_class("module", builtins) + else: + yield inferred._proxied + + +def object_type(node, context=None): + """Obtain the type of the given node + + This is used to implement the ``type`` builtin, which means that it's + used for inferring type calls, as well as used in a couple of other places + in the inference. + The node will be inferred first, so this function can support all + sorts of objects, as long as they support inference. + """ + + try: + types = set(_object_type(node, context)) + except exceptions.InferenceError: + return util.Uninferable + if len(types) > 1 or not types: + return util.Uninferable + return list(types)[0] + + +def _object_type_is_subclass(obj_type, class_or_seq, context=None): + if not isinstance(class_or_seq, (tuple, list)): + class_seq = (class_or_seq,) + else: + class_seq = class_or_seq + + if obj_type is util.Uninferable: + return util.Uninferable + + # Instances are not types + class_seq = [ + item if not isinstance(item, bases.Instance) else util.Uninferable + for item in class_seq + ] + # strict compatibility with issubclass + # issubclass(type, (object, 1)) evaluates to true + # issubclass(object, (1, type)) raises TypeError + for klass in class_seq: + if klass is util.Uninferable: + raise exceptions.AstroidTypeError("arg 2 must be a type or tuple of types") + + for obj_subclass in obj_type.mro(): + if obj_subclass == klass: + return True + return False + + +def object_isinstance(node, class_or_seq, context=None): + """Check if a node 'isinstance' any node in class_or_seq + + :param node: A given node + :param class_or_seq: Union[nodes.NodeNG, Sequence[nodes.NodeNG]] + :rtype: bool + + :raises AstroidTypeError: if the given ``classes_or_seq`` are not types + """ + obj_type = object_type(node, context) + if obj_type is util.Uninferable: + return util.Uninferable + return _object_type_is_subclass(obj_type, class_or_seq, context=context) + + +def object_issubclass(node, class_or_seq, context=None): + """Check if a type is a subclass of any node in class_or_seq + + :param node: A given node + :param class_or_seq: Union[Nodes.NodeNG, Sequence[nodes.NodeNG]] + :rtype: bool + + :raises AstroidTypeError: if the given ``classes_or_seq`` are not types + :raises AstroidError: if the type of the given node cannot be inferred + or its type's mro doesn't work + """ + if not isinstance(node, nodes.ClassDef): + raise TypeError("{node} needs to be a ClassDef node".format(node=node)) + return _object_type_is_subclass(node, class_or_seq, context=context) + + +def safe_infer(node, context=None): + """Return the inferred value for the given node. + + Return None if inference failed or if there is some ambiguity (more than + one node has been inferred). + """ + try: + inferit = node.infer(context=context) + value = next(inferit) + except exceptions.InferenceError: + return None + try: + next(inferit) + return None # None if there is ambiguity on the inferred node + except exceptions.InferenceError: + return None # there is some kind of ambiguity + except StopIteration: + return value + + +def has_known_bases(klass, context=None): + """Return true if all base classes of a class could be inferred.""" + try: + return klass._all_bases_known + except AttributeError: + pass + for base in klass.bases: + result = safe_infer(base, context=context) + # TODO: check for A->B->A->B pattern in class structure too? + if ( + not isinstance(result, scoped_nodes.ClassDef) + or result is klass + or not has_known_bases(result, context=context) + ): + klass._all_bases_known = False + return False + klass._all_bases_known = True + return True + + +def _type_check(type1, type2): + if not all(map(has_known_bases, (type1, type2))): + raise exceptions._NonDeducibleTypeHierarchy + + if not all([type1.newstyle, type2.newstyle]): + return False + try: + return type1 in type2.mro()[:-1] + except exceptions.MroError: + # The MRO is invalid. + raise exceptions._NonDeducibleTypeHierarchy + + +def is_subtype(type1, type2): + """Check if *type1* is a subtype of *typ2*.""" + return _type_check(type2, type1) + + +def is_supertype(type1, type2): + """Check if *type2* is a supertype of *type1*.""" + return _type_check(type1, type2) + + +def class_instance_as_index(node): + """Get the value as an index for the given instance. + + If an instance provides an __index__ method, then it can + be used in some scenarios where an integer is expected, + for instance when multiplying or subscripting a list. + """ + context = contextmod.InferenceContext() + context.callcontext = contextmod.CallContext(args=[node]) + + try: + for inferred in node.igetattr("__index__", context=context): + if not isinstance(inferred, bases.BoundMethod): + continue + + for result in inferred.infer_call_result(node, context=context): + if isinstance(result, nodes.Const) and isinstance(result.value, int): + return result + except exceptions.InferenceError: + pass + return None + + +def object_len(node, context=None): + """Infer length of given node object + + :param Union[nodes.ClassDef, nodes.Instance] node: + :param node: Node to infer length of + + :raises AstroidTypeError: If an invalid node is returned + from __len__ method or no __len__ method exists + :raises InferenceError: If the given node cannot be inferred + or if multiple nodes are inferred + :rtype int: Integer length of node + """ + from astroid.objects import FrozenSet + + inferred_node = safe_infer(node, context=context) + if inferred_node is None or inferred_node is util.Uninferable: + raise exceptions.InferenceError(node=node) + if isinstance(inferred_node, nodes.Const) and isinstance( + inferred_node.value, (bytes, str) + ): + return len(inferred_node.value) + if isinstance(inferred_node, (nodes.List, nodes.Set, nodes.Tuple, FrozenSet)): + return len(inferred_node.elts) + if isinstance(inferred_node, nodes.Dict): + return len(inferred_node.items) + try: + node_type = object_type(inferred_node, context=context) + len_call = next(node_type.igetattr("__len__", context=context)) + except exceptions.AttributeInferenceError: + raise exceptions.AstroidTypeError( + "object of type '{}' has no len()".format(len_call.pytype()) + ) + + result_of_len = next(len_call.infer_call_result(node, context)) + if ( + isinstance(result_of_len, nodes.Const) + and result_of_len.pytype() == "builtins.int" + ): + return result_of_len.value + raise exceptions.AstroidTypeError( + "'{}' object cannot be interpreted as an integer".format(result_of_len) + ) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/inference.py b/basic python programmes/venv/Lib/site-packages/astroid/inference.py new file mode 100644 index 0000000..cb7b004 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/inference.py @@ -0,0 +1,917 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2017 Michał Masłowski +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Ashley Whetter +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to handle inference on astroid trees +""" + +import functools +import itertools +import operator + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators +from astroid import helpers +from astroid import manager +from astroid import nodes +from astroid.interpreter import dunder_lookup +from astroid import protocols +from astroid import util + + +MANAGER = manager.AstroidManager() + + +# .infer method ############################################################### + + +def infer_end(self, context=None): + """inference's end for node such as Module, ClassDef, FunctionDef, + Const... + + """ + yield self + + +nodes.Module._infer = infer_end +nodes.ClassDef._infer = infer_end +nodes.FunctionDef._infer = infer_end +nodes.Lambda._infer = infer_end +nodes.Const._infer = infer_end +nodes.Slice._infer = infer_end + + +def _infer_sequence_helper(node, context=None): + """Infer all values based on _BaseContainer.elts""" + values = [] + + for elt in node.elts: + if isinstance(elt, nodes.Starred): + starred = helpers.safe_infer(elt.value, context) + if not starred: + raise exceptions.InferenceError(node=node, context=context) + if not hasattr(starred, "elts"): + raise exceptions.InferenceError(node=node, context=context) + values.extend(_infer_sequence_helper(starred)) + else: + values.append(elt) + return values + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_sequence(self, context=None): + if not any(isinstance(e, nodes.Starred) for e in self.elts): + yield self + else: + values = _infer_sequence_helper(self, context) + new_seq = type(self)( + lineno=self.lineno, col_offset=self.col_offset, parent=self.parent + ) + new_seq.postinit(values) + + yield new_seq + + +nodes.List._infer = infer_sequence +nodes.Tuple._infer = infer_sequence +nodes.Set._infer = infer_sequence + + +def infer_map(self, context=None): + if not any(isinstance(k, nodes.DictUnpack) for k, _ in self.items): + yield self + else: + items = _infer_map(self, context) + new_seq = type(self)(self.lineno, self.col_offset, self.parent) + new_seq.postinit(list(items.items())) + yield new_seq + + +def _update_with_replacement(lhs_dict, rhs_dict): + """Delete nodes that equate to duplicate keys + + Since an astroid node doesn't 'equal' another node with the same value, + this function uses the as_string method to make sure duplicate keys + don't get through + + Note that both the key and the value are astroid nodes + + Fixes issue with DictUnpack causing duplicte keys + in inferred Dict items + + :param dict(nodes.NodeNG, nodes.NodeNG) lhs_dict: Dictionary to 'merge' nodes into + :param dict(nodes.NodeNG, nodes.NodeNG) rhs_dict: Dictionary with nodes to pull from + :return dict(nodes.NodeNG, nodes.NodeNG): merged dictionary of nodes + """ + combined_dict = itertools.chain(lhs_dict.items(), rhs_dict.items()) + # Overwrite keys which have the same string values + string_map = {key.as_string(): (key, value) for key, value in combined_dict} + # Return to dictionary + return dict(string_map.values()) + + +def _infer_map(node, context): + """Infer all values based on Dict.items""" + values = {} + for name, value in node.items: + if isinstance(name, nodes.DictUnpack): + double_starred = helpers.safe_infer(value, context) + if not double_starred: + raise exceptions.InferenceError + if not isinstance(double_starred, nodes.Dict): + raise exceptions.InferenceError(node=node, context=context) + unpack_items = _infer_map(double_starred, context) + values = _update_with_replacement(values, unpack_items) + else: + key = helpers.safe_infer(name, context=context) + value = helpers.safe_infer(value, context=context) + if any(not elem for elem in (key, value)): + raise exceptions.InferenceError(node=node, context=context) + values = _update_with_replacement(values, {key: value}) + return values + + +nodes.Dict._infer = infer_map + + +def _higher_function_scope(node): + """ Search for the first function which encloses the given + scope. This can be used for looking up in that function's + scope, in case looking up in a lower scope for a particular + name fails. + + :param node: A scope node. + :returns: + ``None``, if no parent function scope was found, + otherwise an instance of :class:`astroid.scoped_nodes.Function`, + which encloses the given node. + """ + current = node + while current.parent and not isinstance(current.parent, nodes.FunctionDef): + current = current.parent + if current and current.parent: + return current.parent + return None + + +def infer_name(self, context=None): + """infer a Name: use name lookup rules""" + frame, stmts = self.lookup(self.name) + if not stmts: + # Try to see if the name is enclosed in a nested function + # and use the higher (first function) scope for searching. + parent_function = _higher_function_scope(self.scope()) + if parent_function: + _, stmts = parent_function.lookup(self.name) + + if not stmts: + raise exceptions.NameInferenceError( + name=self.name, scope=self.scope(), context=context + ) + context = contextmod.copy_context(context) + context.lookupname = self.name + return bases._infer_stmts(stmts, context, frame) + + +# pylint: disable=no-value-for-parameter +nodes.Name._infer = decorators.raise_if_nothing_inferred( + decorators.path_wrapper(infer_name) +) +nodes.AssignName.infer_lhs = infer_name # won't work with a path wrapper + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_call(self, context=None): + """infer a Call node by trying to guess what the function returns""" + callcontext = contextmod.copy_context(context) + callcontext.callcontext = contextmod.CallContext( + args=self.args, keywords=self.keywords + ) + callcontext.boundnode = None + if context is not None: + callcontext.extra_context = _populate_context_lookup(self, context.clone()) + + for callee in self.func.infer(context): + if callee is util.Uninferable: + yield callee + continue + try: + if hasattr(callee, "infer_call_result"): + yield from callee.infer_call_result(caller=self, context=callcontext) + except exceptions.InferenceError: + continue + return dict(node=self, context=context) + + +nodes.Call._infer = infer_call + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_import(self, context=None, asname=True): + """infer an Import node: return the imported module/object""" + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + + try: + if asname: + yield self.do_import_module(self.real_name(name)) + else: + yield self.do_import_module(name) + except exceptions.AstroidBuildingError as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + +nodes.Import._infer = infer_import + + +def infer_name_module(self, name): + context = contextmod.InferenceContext() + context.lookupname = name + return self.infer(context, asname=False) + + +nodes.Import.infer_name_module = infer_name_module + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_import_from(self, context=None, asname=True): + """infer a ImportFrom node: return the imported module/object""" + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + if asname: + name = self.real_name(name) + + try: + module = self.do_import_module() + except exceptions.AstroidBuildingError as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + try: + context = contextmod.copy_context(context) + context.lookupname = name + stmts = module.getattr(name, ignore_locals=module is self.root()) + return bases._infer_stmts(stmts, context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + +nodes.ImportFrom._infer = infer_import_from + + +@decorators.raise_if_nothing_inferred +def infer_attribute(self, context=None): + """infer an Attribute node by using getattr on the associated object""" + for owner in self.expr.infer(context): + if owner is util.Uninferable: + yield owner + continue + + if context and context.boundnode: + # This handles the situation where the attribute is accessed through a subclass + # of a base class and the attribute is defined at the base class's level, + # by taking in consideration a redefinition in the subclass. + if isinstance(owner, bases.Instance) and isinstance( + context.boundnode, bases.Instance + ): + try: + if helpers.is_subtype( + helpers.object_type(context.boundnode), + helpers.object_type(owner), + ): + owner = context.boundnode + except exceptions._NonDeducibleTypeHierarchy: + # Can't determine anything useful. + pass + + try: + context.boundnode = owner + yield from owner.igetattr(self.attrname, context) + context.boundnode = None + except (exceptions.AttributeInferenceError, exceptions.InferenceError): + context.boundnode = None + except AttributeError: + # XXX method / function + context.boundnode = None + return dict(node=self, context=context) + + +nodes.Attribute._infer = decorators.path_wrapper(infer_attribute) +nodes.AssignAttr.infer_lhs = infer_attribute # # won't work with a path wrapper + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_global(self, context=None): + if context.lookupname is None: + raise exceptions.InferenceError(node=self, context=context) + try: + return bases._infer_stmts(self.root().getattr(context.lookupname), context) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=context.lookupname, context=context + ) from error + + +nodes.Global._infer = infer_global + + +_SUBSCRIPT_SENTINEL = object() + + +@decorators.raise_if_nothing_inferred +def infer_subscript(self, context=None): + """Inference for subscripts + + We're understanding if the index is a Const + or a slice, passing the result of inference + to the value's `getitem` method, which should + handle each supported index type accordingly. + """ + + found_one = False + for value in self.value.infer(context): + if value is util.Uninferable: + yield util.Uninferable + return None + for index in self.slice.infer(context): + if index is util.Uninferable: + yield util.Uninferable + return None + + # Try to deduce the index value. + index_value = _SUBSCRIPT_SENTINEL + if value.__class__ == bases.Instance: + index_value = index + else: + if index.__class__ == bases.Instance: + instance_as_index = helpers.class_instance_as_index(index) + if instance_as_index: + index_value = instance_as_index + else: + index_value = index + if index_value is _SUBSCRIPT_SENTINEL: + raise exceptions.InferenceError(node=self, context=context) + + try: + assigned = value.getitem(index_value, context) + except ( + exceptions.AstroidTypeError, + exceptions.AstroidIndexError, + exceptions.AttributeInferenceError, + AttributeError, + ) as exc: + raise exceptions.InferenceError(node=self, context=context) from exc + + # Prevent inferring if the inferred subscript + # is the same as the original subscripted object. + if self is assigned or assigned is util.Uninferable: + yield util.Uninferable + return None + yield from assigned.infer(context) + found_one = True + + if found_one: + return dict(node=self, context=context) + return None + + +nodes.Subscript._infer = decorators.path_wrapper(infer_subscript) +nodes.Subscript.infer_lhs = infer_subscript + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def _infer_boolop(self, context=None): + """Infer a boolean operation (and / or / not). + + The function will calculate the boolean operation + for all pairs generated through inference for each component + node. + """ + values = self.values + if self.op == "or": + predicate = operator.truth + else: + predicate = operator.not_ + + try: + values = [value.infer(context=context) for value in values] + except exceptions.InferenceError: + yield util.Uninferable + return None + + for pair in itertools.product(*values): + if any(item is util.Uninferable for item in pair): + # Can't infer the final result, just yield Uninferable. + yield util.Uninferable + continue + + bool_values = [item.bool_value() for item in pair] + if any(item is util.Uninferable for item in bool_values): + # Can't infer the final result, just yield Uninferable. + yield util.Uninferable + continue + + # Since the boolean operations are short circuited operations, + # this code yields the first value for which the predicate is True + # and if no value respected the predicate, then the last value will + # be returned (or Uninferable if there was no last value). + # This is conforming to the semantics of `and` and `or`: + # 1 and 0 -> 1 + # 0 and 1 -> 0 + # 1 or 0 -> 1 + # 0 or 1 -> 1 + value = util.Uninferable + for value, bool_value in zip(pair, bool_values): + if predicate(bool_value): + yield value + break + else: + yield value + + return dict(node=self, context=context) + + +nodes.BoolOp._infer = _infer_boolop + + +# UnaryOp, BinOp and AugAssign inferences + + +def _filter_operation_errors(self, infer_callable, context, error): + for result in infer_callable(self, context): + if isinstance(result, error): + # For the sake of .infer(), we don't care about operation + # errors, which is the job of pylint. So return something + # which shows that we can't infer the result. + yield util.Uninferable + else: + yield result + + +def _infer_unaryop(self, context=None): + """Infer what an UnaryOp should return when evaluated.""" + for operand in self.operand.infer(context): + try: + yield operand.infer_unary_op(self.op) + except TypeError as exc: + # The operand doesn't support this operation. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + except AttributeError as exc: + meth = protocols.UNARY_OP_METHOD[self.op] + if meth is None: + # `not node`. Determine node's boolean + # value and negate its result, unless it is + # Uninferable, which will be returned as is. + bool_value = operand.bool_value() + if bool_value is not util.Uninferable: + yield nodes.const_factory(not bool_value) + else: + yield util.Uninferable + else: + if not isinstance(operand, (bases.Instance, nodes.ClassDef)): + # The operation was used on something which + # doesn't support it. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + continue + + try: + try: + methods = dunder_lookup.lookup(operand, meth) + except exceptions.AttributeInferenceError: + yield util.BadUnaryOperationMessage(operand, self.op, exc) + continue + + meth = methods[0] + inferred = next(meth.infer(context=context)) + if inferred is util.Uninferable or not inferred.callable(): + continue + + context = contextmod.copy_context(context) + context.callcontext = contextmod.CallContext(args=[operand]) + call_results = inferred.infer_call_result(self, context=context) + result = next(call_results, None) + if result is None: + # Failed to infer, return the same type. + yield operand + else: + yield result + except exceptions.AttributeInferenceError as exc: + # The unary operation special method was not found. + yield util.BadUnaryOperationMessage(operand, self.op, exc) + except exceptions.InferenceError: + yield util.Uninferable + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_unaryop(self, context=None): + """Infer what an UnaryOp should return when evaluated.""" + yield from _filter_operation_errors( + self, _infer_unaryop, context, util.BadUnaryOperationMessage + ) + return dict(node=self, context=context) + + +nodes.UnaryOp._infer_unaryop = _infer_unaryop +nodes.UnaryOp._infer = infer_unaryop + + +def _is_not_implemented(const): + """Check if the given const node is NotImplemented.""" + return isinstance(const, nodes.Const) and const.value is NotImplemented + + +def _invoke_binop_inference(instance, opnode, op, other, context, method_name): + """Invoke binary operation inference on the given instance.""" + methods = dunder_lookup.lookup(instance, method_name) + context = contextmod.bind_context_to_node(context, instance) + method = methods[0] + inferred = next(method.infer(context=context)) + if inferred is util.Uninferable: + raise exceptions.InferenceError + return instance.infer_binary_op(opnode, op, other, context, inferred) + + +def _aug_op(instance, opnode, op, other, context, reverse=False): + """Get an inference callable for an augmented binary operation.""" + method_name = protocols.AUGMENTED_OP_METHOD[op] + return functools.partial( + _invoke_binop_inference, + instance=instance, + op=op, + opnode=opnode, + other=other, + context=context, + method_name=method_name, + ) + + +def _bin_op(instance, opnode, op, other, context, reverse=False): + """Get an inference callable for a normal binary operation. + + If *reverse* is True, then the reflected method will be used instead. + """ + if reverse: + method_name = protocols.REFLECTED_BIN_OP_METHOD[op] + else: + method_name = protocols.BIN_OP_METHOD[op] + return functools.partial( + _invoke_binop_inference, + instance=instance, + op=op, + opnode=opnode, + other=other, + context=context, + method_name=method_name, + ) + + +def _get_binop_contexts(context, left, right): + """Get contexts for binary operations. + + This will return two inference contexts, the first one + for x.__op__(y), the other one for y.__rop__(x), where + only the arguments are inversed. + """ + # The order is important, since the first one should be + # left.__op__(right). + for arg in (right, left): + new_context = context.clone() + new_context.callcontext = contextmod.CallContext(args=[arg]) + new_context.boundnode = None + yield new_context + + +def _same_type(type1, type2): + """Check if type1 is the same as type2.""" + return type1.qname() == type2.qname() + + +def _get_binop_flow( + left, left_type, binary_opnode, right, right_type, context, reverse_context +): + """Get the flow for binary operations. + + The rules are a bit messy: + + * if left and right have the same type, then only one + method will be called, left.__op__(right) + * if left and right are unrelated typewise, then first + left.__op__(right) is tried and if this does not exist + or returns NotImplemented, then right.__rop__(left) is tried. + * if left is a subtype of right, then only left.__op__(right) + is tried. + * if left is a supertype of right, then right.__rop__(left) + is first tried and then left.__op__(right) + """ + op = binary_opnode.op + if _same_type(left_type, right_type): + methods = [_bin_op(left, binary_opnode, op, right, context)] + elif helpers.is_subtype(left_type, right_type): + methods = [_bin_op(left, binary_opnode, op, right, context)] + elif helpers.is_supertype(left_type, right_type): + methods = [ + _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True), + _bin_op(left, binary_opnode, op, right, context), + ] + else: + methods = [ + _bin_op(left, binary_opnode, op, right, context), + _bin_op(right, binary_opnode, op, left, reverse_context, reverse=True), + ] + return methods + + +def _get_aug_flow( + left, left_type, aug_opnode, right, right_type, context, reverse_context +): + """Get the flow for augmented binary operations. + + The rules are a bit messy: + + * if left and right have the same type, then left.__augop__(right) + is first tried and then left.__op__(right). + * if left and right are unrelated typewise, then + left.__augop__(right) is tried, then left.__op__(right) + is tried and then right.__rop__(left) is tried. + * if left is a subtype of right, then left.__augop__(right) + is tried and then left.__op__(right). + * if left is a supertype of right, then left.__augop__(right) + is tried, then right.__rop__(left) and then + left.__op__(right) + """ + bin_op = aug_opnode.op.strip("=") + aug_op = aug_opnode.op + if _same_type(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + elif helpers.is_subtype(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + elif helpers.is_supertype(left_type, right_type): + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True), + _bin_op(left, aug_opnode, bin_op, right, context), + ] + else: + methods = [ + _aug_op(left, aug_opnode, aug_op, right, context), + _bin_op(left, aug_opnode, bin_op, right, context), + _bin_op(right, aug_opnode, bin_op, left, reverse_context, reverse=True), + ] + return methods + + +def _infer_binary_operation(left, right, binary_opnode, context, flow_factory): + """Infer a binary operation between a left operand and a right operand + + This is used by both normal binary operations and augmented binary + operations, the only difference is the flow factory used. + """ + + context, reverse_context = _get_binop_contexts(context, left, right) + left_type = helpers.object_type(left) + right_type = helpers.object_type(right) + methods = flow_factory( + left, left_type, binary_opnode, right, right_type, context, reverse_context + ) + for method in methods: + try: + results = list(method()) + except AttributeError: + continue + except exceptions.AttributeInferenceError: + continue + except exceptions.InferenceError: + yield util.Uninferable + return + else: + if any(result is util.Uninferable for result in results): + yield util.Uninferable + return + + if all(map(_is_not_implemented, results)): + continue + not_implemented = sum( + 1 for result in results if _is_not_implemented(result) + ) + if not_implemented and not_implemented != len(results): + # Can't infer yet what this is. + yield util.Uninferable + return + + yield from results + return + # The operation doesn't seem to be supported so let the caller know about it + yield util.BadBinaryOperationMessage(left_type, binary_opnode.op, right_type) + + +def _infer_binop(self, context): + """Binary operation inference logic.""" + left = self.left + right = self.right + + # we use two separate contexts for evaluating lhs and rhs because + # 1. evaluating lhs may leave some undesired entries in context.path + # which may not let us infer right value of rhs + context = context or contextmod.InferenceContext() + lhs_context = contextmod.copy_context(context) + rhs_context = contextmod.copy_context(context) + lhs_iter = left.infer(context=lhs_context) + rhs_iter = right.infer(context=rhs_context) + for lhs, rhs in itertools.product(lhs_iter, rhs_iter): + if any(value is util.Uninferable for value in (rhs, lhs)): + # Don't know how to process this. + yield util.Uninferable + return + + try: + yield from _infer_binary_operation(lhs, rhs, self, context, _get_binop_flow) + except exceptions._NonDeducibleTypeHierarchy: + yield util.Uninferable + + +@decorators.yes_if_nothing_inferred +@decorators.path_wrapper +def infer_binop(self, context=None): + return _filter_operation_errors( + self, _infer_binop, context, util.BadBinaryOperationMessage + ) + + +nodes.BinOp._infer_binop = _infer_binop +nodes.BinOp._infer = infer_binop + + +def _infer_augassign(self, context=None): + """Inference logic for augmented binary operations.""" + if context is None: + context = contextmod.InferenceContext() + + rhs_context = context.clone() + + lhs_iter = self.target.infer_lhs(context=context) + rhs_iter = self.value.infer(context=rhs_context) + for lhs, rhs in itertools.product(lhs_iter, rhs_iter): + if any(value is util.Uninferable for value in (rhs, lhs)): + # Don't know how to process this. + yield util.Uninferable + return + + try: + yield from _infer_binary_operation( + left=lhs, + right=rhs, + binary_opnode=self, + context=context, + flow_factory=_get_aug_flow, + ) + except exceptions._NonDeducibleTypeHierarchy: + yield util.Uninferable + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_augassign(self, context=None): + return _filter_operation_errors( + self, _infer_augassign, context, util.BadBinaryOperationMessage + ) + + +nodes.AugAssign._infer_augassign = _infer_augassign +nodes.AugAssign._infer = infer_augassign + +# End of binary operation inference. + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_arguments(self, context=None): + name = context.lookupname + if name is None: + raise exceptions.InferenceError(node=self, context=context) + return protocols._arguments_infer_argname(self, name, context) + + +nodes.Arguments._infer = infer_arguments + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_assign(self, context=None): + """infer a AssignName/AssignAttr: need to inspect the RHS part of the + assign node + """ + stmt = self.statement() + if isinstance(stmt, nodes.AugAssign): + return stmt.infer(context) + + stmts = list(self.assigned_stmts(context=context)) + return bases._infer_stmts(stmts, context) + + +nodes.AssignName._infer = infer_assign +nodes.AssignAttr._infer = infer_assign + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_empty_node(self, context=None): + if not self.has_underlying_object(): + yield util.Uninferable + else: + try: + yield from MANAGER.infer_ast_from_something(self.object, context=context) + except exceptions.AstroidError: + yield util.Uninferable + + +nodes.EmptyNode._infer = infer_empty_node + + +@decorators.raise_if_nothing_inferred +@decorators.path_wrapper +def infer_index(self, context=None): + return self.value.infer(context) + + +nodes.Index._infer = infer_index + +# TODO: move directly into bases.Instance when the dependency hell +# will be solved. +def instance_getitem(self, index, context=None): + # Rewrap index to Const for this case + new_context = contextmod.bind_context_to_node(context, self) + if not context: + context = new_context + + # Create a new callcontext for providing index as an argument. + new_context.callcontext = contextmod.CallContext(args=[index]) + + method = next(self.igetattr("__getitem__", context=context), None) + if not isinstance(method, bases.BoundMethod): + raise exceptions.InferenceError( + "Could not find __getitem__ for {node!r}.", node=self, context=context + ) + + try: + return next(method.infer_call_result(self, new_context)) + except StopIteration as exc: + raise exceptions.InferenceError( + message="Inference for {node!r}[{index!s}] failed.", + node=self, + index=index, + context=context, + ) from exc + + +bases.Instance.getitem = instance_getitem + + +def _populate_context_lookup(call, context): + # Allows context to be saved for later + # for inference inside a function + context_lookup = {} + if context is None: + return context_lookup + for arg in call.args: + if isinstance(arg, nodes.Starred): + context_lookup[arg.value] = context + else: + context_lookup[arg] = context + keywords = call.keywords if call.keywords is not None else [] + for keyword in keywords: + context_lookup[keyword.value] = context + return context_lookup diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__init__.py b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..09092e8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc new file mode 100644 index 0000000..2ec807d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/dunder_lookup.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-37.pyc new file mode 100644 index 0000000..478c820 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/__pycache__/objectmodel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__init__.py b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..a7a1bea Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc new file mode 100644 index 0000000..097e2b7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/spec.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000..11cec29 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/__pycache__/util.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/spec.py b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/spec.py new file mode 100644 index 0000000..982f9b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/spec.py @@ -0,0 +1,337 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Chris Philip +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 ioanatia +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Nick Drozd + +import abc +import collections +import enum +import imp +import os +import sys +import zipimport + +try: + import importlib.machinery + + _HAS_MACHINERY = True +except ImportError: + _HAS_MACHINERY = False + +try: + from functools import lru_cache +except ImportError: + from backports.functools_lru_cache import lru_cache + +from . import util + +ModuleType = enum.Enum( + "ModuleType", + "C_BUILTIN C_EXTENSION PKG_DIRECTORY " + "PY_CODERESOURCE PY_COMPILED PY_FROZEN PY_RESOURCE " + "PY_SOURCE PY_ZIPMODULE PY_NAMESPACE", +) +_ImpTypes = { + imp.C_BUILTIN: ModuleType.C_BUILTIN, + imp.C_EXTENSION: ModuleType.C_EXTENSION, + imp.PKG_DIRECTORY: ModuleType.PKG_DIRECTORY, + imp.PY_COMPILED: ModuleType.PY_COMPILED, + imp.PY_FROZEN: ModuleType.PY_FROZEN, + imp.PY_SOURCE: ModuleType.PY_SOURCE, +} +if hasattr(imp, "PY_RESOURCE"): + _ImpTypes[imp.PY_RESOURCE] = ModuleType.PY_RESOURCE +if hasattr(imp, "PY_CODERESOURCE"): + _ImpTypes[imp.PY_CODERESOURCE] = ModuleType.PY_CODERESOURCE + + +def _imp_type_to_module_type(imp_type): + return _ImpTypes[imp_type] + + +_ModuleSpec = collections.namedtuple( + "_ModuleSpec", "name type location " "origin submodule_search_locations" +) + + +class ModuleSpec(_ModuleSpec): + """Defines a class similar to PEP 420's ModuleSpec + + A module spec defines a name of a module, its type, location + and where submodules can be found, if the module is a package. + """ + + def __new__( + cls, + name, + module_type, + location=None, + origin=None, + submodule_search_locations=None, + ): + return _ModuleSpec.__new__( + cls, + name=name, + type=module_type, + location=location, + origin=origin, + submodule_search_locations=submodule_search_locations, + ) + + +class Finder: + """A finder is a class which knows how to find a particular module.""" + + def __init__(self, path=None): + self._path = path or sys.path + + @abc.abstractmethod + def find_module(self, modname, module_parts, processed, submodule_path): + """Find the given module + + Each finder is responsible for each protocol of finding, as long as + they all return a ModuleSpec. + + :param str modname: The module which needs to be searched. + :param list module_parts: It should be a list of strings, + where each part contributes to the module's + namespace. + :param list processed: What parts from the module parts were processed + so far. + :param list submodule_path: A list of paths where the module + can be looked into. + :returns: A ModuleSpec, describing how and where the module was found, + None, otherwise. + """ + + def contribute_to_path(self, spec, processed): + """Get a list of extra paths where this finder can search.""" + + +class ImpFinder(Finder): + """A finder based on the imp module.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + if submodule_path is not None: + submodule_path = list(submodule_path) + try: + stream, mp_filename, mp_desc = imp.find_module(modname, submodule_path) + except ImportError: + return None + + # Close resources. + if stream: + stream.close() + + return ModuleSpec( + name=modname, + location=mp_filename, + module_type=_imp_type_to_module_type(mp_desc[2]), + ) + + def contribute_to_path(self, spec, processed): + if spec.location is None: + # Builtin. + return None + + if _is_setuptools_namespace(spec.location): + # extend_path is called, search sys.path for module/packages + # of this name see pkgutil.extend_path documentation + path = [ + os.path.join(p, *processed) + for p in sys.path + if os.path.isdir(os.path.join(p, *processed)) + ] + else: + path = [spec.location] + return path + + +class ExplicitNamespacePackageFinder(ImpFinder): + """A finder for the explicit namespace packages, generated through pkg_resources.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + if processed: + modname = ".".join(processed + [modname]) + if util.is_namespace(modname) and modname in sys.modules: + submodule_path = sys.modules[modname].__path__ + return ModuleSpec( + name=modname, + location="", + origin="namespace", + module_type=ModuleType.PY_NAMESPACE, + submodule_search_locations=submodule_path, + ) + return None + + def contribute_to_path(self, spec, processed): + return spec.submodule_search_locations + + +class ZipFinder(Finder): + """Finder that knows how to find a module inside zip files.""" + + def __init__(self, path): + super(ZipFinder, self).__init__(path) + self._zipimporters = _precache_zipimporters(path) + + def find_module(self, modname, module_parts, processed, submodule_path): + try: + file_type, filename, path = _search_zip(module_parts, self._zipimporters) + except ImportError: + return None + + return ModuleSpec( + name=modname, + location=filename, + origin="egg", + module_type=file_type, + submodule_search_locations=path, + ) + + +class PathSpecFinder(Finder): + """Finder based on importlib.machinery.PathFinder.""" + + def find_module(self, modname, module_parts, processed, submodule_path): + spec = importlib.machinery.PathFinder.find_spec(modname, path=submodule_path) + if spec: + # origin can be either a string on older Python versions + # or None in case it is a namespace package: + # https://github.com/python/cpython/pull/5481 + is_namespace_pkg = spec.origin in ("namespace", None) + location = spec.origin if not is_namespace_pkg else None + module_type = ModuleType.PY_NAMESPACE if is_namespace_pkg else None + spec = ModuleSpec( + name=spec.name, + location=location, + origin=spec.origin, + module_type=module_type, + submodule_search_locations=list(spec.submodule_search_locations or []), + ) + return spec + + def contribute_to_path(self, spec, processed): + if spec.type == ModuleType.PY_NAMESPACE: + return spec.submodule_search_locations + return None + + +_SPEC_FINDERS = (ImpFinder, ZipFinder) +if _HAS_MACHINERY and sys.version_info[:2] >= (3, 4): + _SPEC_FINDERS += (PathSpecFinder,) +_SPEC_FINDERS += (ExplicitNamespacePackageFinder,) + + +def _is_setuptools_namespace(location): + try: + with open(os.path.join(location, "__init__.py"), "rb") as stream: + data = stream.read(4096) + except IOError: + pass + else: + extend_path = b"pkgutil" in data and b"extend_path" in data + declare_namespace = ( + b"pkg_resources" in data and b"declare_namespace(__name__)" in data + ) + return extend_path or declare_namespace + + +@lru_cache() +def _cached_set_diff(left, right): + result = set(left) + result.difference_update(right) + return result + + +def _precache_zipimporters(path=None): + pic = sys.path_importer_cache + + # When measured, despite having the same complexity (O(n)), + # converting to tuples and then caching the conversion to sets + # and the set difference is faster than converting to sets + # and then only caching the set difference. + + req_paths = tuple(path or sys.path) + cached_paths = tuple(pic) + new_paths = _cached_set_diff(req_paths, cached_paths) + for entry_path in new_paths: + try: + pic[entry_path] = zipimport.zipimporter(entry_path) + except zipimport.ZipImportError: + continue + return pic + + +def _search_zip(modpath, pic): + for filepath, importer in list(pic.items()): + if importer is not None: + found = importer.find_module(modpath[0]) + if found: + if not importer.find_module(os.path.sep.join(modpath)): + raise ImportError( + "No module named %s in %s/%s" + % (".".join(modpath[1:]), filepath, modpath) + ) + # import code; code.interact(local=locals()) + return ( + ModuleType.PY_ZIPMODULE, + os.path.abspath(filepath) + os.path.sep + os.path.sep.join(modpath), + filepath, + ) + raise ImportError("No module named %s" % ".".join(modpath)) + + +def _find_spec_with_path(search_path, modname, module_parts, processed, submodule_path): + finders = [finder(search_path) for finder in _SPEC_FINDERS] + for finder in finders: + spec = finder.find_module(modname, module_parts, processed, submodule_path) + if spec is None: + continue + return finder, spec + + raise ImportError("No module named %s" % ".".join(module_parts)) + + +def find_spec(modpath, path=None): + """Find a spec for the given module. + + :type modpath: list or tuple + :param modpath: + split module's name (i.e name of a module or package split + on '.'), with leading empty strings for explicit relative import + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :rtype: ModuleSpec + :return: A module spec, which describes how the module was + found and where. + """ + _path = path or sys.path + + # Need a copy for not mutating the argument. + modpath = modpath[:] + + submodule_path = None + module_parts = modpath[:] + processed = [] + + while modpath: + modname = modpath.pop(0) + finder, spec = _find_spec_with_path( + _path, modname, module_parts, processed, submodule_path or path + ) + processed.append(modname) + if modpath: + submodule_path = finder.contribute_to_path(spec, processed) + + if spec.type == ModuleType.PKG_DIRECTORY: + spec = spec._replace(submodule_search_locations=submodule_path) + + return spec diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/util.py b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/util.py new file mode 100644 index 0000000..a917bd3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/_import/util.py @@ -0,0 +1,10 @@ +# Copyright (c) 2016, 2018 Claudiu Popa + +try: + import pkg_resources +except ImportError: + pkg_resources = None + + +def is_namespace(modname): + return pkg_resources is not None and modname in pkg_resources._namespace_packages diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/dunder_lookup.py b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/dunder_lookup.py new file mode 100644 index 0000000..0ae9bc9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/dunder_lookup.py @@ -0,0 +1,66 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Contains logic for retrieving special methods. + +This implementation does not rely on the dot attribute access +logic, found in ``.getattr()``. The difference between these two +is that the dunder methods are looked with the type slots +(you can find more about these here +http://lucumr.pocoo.org/2014/8/16/the-python-i-would-like-to-see/) +As such, the lookup for the special methods is actually simpler than +the dot attribute access. +""" +import itertools + +import astroid +from astroid import exceptions + + +def _lookup_in_mro(node, name): + attrs = node.locals.get(name, []) + + nodes = itertools.chain.from_iterable( + ancestor.locals.get(name, []) for ancestor in node.ancestors(recurs=True) + ) + values = list(itertools.chain(attrs, nodes)) + if not values: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return values + + +def lookup(node, name): + """Lookup the given special method name in the given *node* + + If the special method was found, then a list of attributes + will be returned. Otherwise, `astroid.AttributeInferenceError` + is going to be raised. + """ + if isinstance( + node, (astroid.List, astroid.Tuple, astroid.Const, astroid.Dict, astroid.Set) + ): + return _builtin_lookup(node, name) + if isinstance(node, astroid.Instance): + return _lookup_in_mro(node, name) + if isinstance(node, astroid.ClassDef): + return _class_lookup(node, name) + + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + +def _class_lookup(node, name): + metaclass = node.metaclass() + if metaclass is None: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return _lookup_in_mro(metaclass, name) + + +def _builtin_lookup(node, name): + values = node.locals.get(name, []) + if not values: + raise exceptions.AttributeInferenceError(attribute=name, target=node) + + return values diff --git a/basic python programmes/venv/Lib/site-packages/astroid/interpreter/objectmodel.py b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/objectmodel.py new file mode 100644 index 0000000..65e9c64 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/interpreter/objectmodel.py @@ -0,0 +1,673 @@ +# Copyright (c) 2016-2018 Claudiu Popa +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017-2018 Bryce Guinta +# Copyright (c) 2017 Ceridwen +# Copyright (c) 2017 Calen Pennington +# Copyright (c) 2018 Nick Drozd +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER +""" +Data object model, as per https://docs.python.org/3/reference/datamodel.html. + +This module describes, at least partially, a data object model for some +of astroid's nodes. The model contains special attributes that nodes such +as functions, classes, modules etc have, such as __doc__, __class__, +__module__ etc, being used when doing attribute lookups over nodes. + +For instance, inferring `obj.__class__` will first trigger an inference +of the `obj` variable. If it was successfully inferred, then an attribute +`__class__ will be looked for in the inferred object. This is the part +where the data model occurs. The model is attached to those nodes +and the lookup mechanism will try to see if attributes such as +`__class__` are defined by the model or not. If they are defined, +the model will be requested to return the corresponding value of that +attribute. Thus the model can be viewed as a special part of the lookup +mechanism. +""" + +import builtins +import itertools +import pprint +import os +import types +from functools import lru_cache + +import astroid +from astroid import context as contextmod +from astroid import exceptions +from astroid import node_classes + + +def _dunder_dict(instance, attributes): + obj = node_classes.Dict(parent=instance) + + # Convert the keys to node strings + keys = [ + node_classes.Const(value=value, parent=obj) for value in list(attributes.keys()) + ] + + # The original attribute has a list of elements for each key, + # but that is not useful for retrieving the special attribute's value. + # In this case, we're picking the last value from each list. + values = [elem[-1] for elem in attributes.values()] + + obj.postinit(list(zip(keys, values))) + return obj + + +class ObjectModel: + def __init__(self): + self._instance = None + + def __repr__(self): + result = [] + cname = type(self).__name__ + string = "%(cname)s(%(fields)s)" + alignment = len(cname) + 1 + for field in sorted(self.attributes()): + width = 80 - len(field) - alignment + lines = pprint.pformat(field, indent=2, width=width).splitlines(True) + + inner = [lines[0]] + for line in lines[1:]: + inner.append(" " * alignment + line) + result.append(field) + + return string % { + "cname": cname, + "fields": (",\n" + " " * alignment).join(result), + } + + def __call__(self, instance): + self._instance = instance + return self + + def __get__(self, instance, cls=None): + # ObjectModel needs to be a descriptor so that just doing + # `special_attributes = SomeObjectModel` should be enough in the body of a node. + # But at the same time, node.special_attributes should return an object + # which can be used for manipulating the special attributes. That's the reason + # we pass the instance through which it got accessed to ObjectModel.__call__, + # returning itself afterwards, so we can still have access to the + # underlying data model and to the instance for which it got accessed. + return self(instance) + + def __contains__(self, name): + return name in self.attributes() + + @lru_cache(maxsize=None) + def attributes(self): + """Get the attributes which are exported by this object model.""" + return [obj[2:] for obj in dir(self) if obj.startswith("py")] + + def lookup(self, name): + """Look up the given *name* in the current model + + It should return an AST or an interpreter object, + but if the name is not found, then an AttributeInferenceError will be raised. + """ + + if name in self.attributes(): + return getattr(self, "py" + name) + raise exceptions.AttributeInferenceError(target=self._instance, attribute=name) + + +class ModuleModel(ObjectModel): + def _builtins(self): + builtins_ast_module = astroid.MANAGER.astroid_cache[builtins.__name__] + return builtins_ast_module.special_attributes.lookup("__dict__") + + @property + def pybuiltins(self): + return self._builtins() + + # __path__ is a standard attribute on *packages* not + # non-package modules. The only mention of it in the + # official 2.7 documentation I can find is in the + # tutorial. + + @property + def py__path__(self): + if not self._instance.package: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__path__" + ) + + path_objs = [ + node_classes.Const( + value=path + if not path.endswith("__init__.py") + else os.path.dirname(path), + parent=self._instance, + ) + for path in self._instance.path + ] + + container = node_classes.List(parent=self._instance) + container.postinit(path_objs) + + return container + + @property + def py__name__(self): + return node_classes.Const(value=self._instance.name, parent=self._instance) + + @property + def py__doc__(self): + return node_classes.Const(value=self._instance.doc, parent=self._instance) + + @property + def py__file__(self): + return node_classes.Const(value=self._instance.file, parent=self._instance) + + @property + def py__dict__(self): + return _dunder_dict(self._instance, self._instance.globals) + + # __package__ isn't mentioned anywhere outside a PEP: + # https://www.python.org/dev/peps/pep-0366/ + @property + def py__package__(self): + if not self._instance.package: + value = "" + else: + value = self._instance.name + + return node_classes.Const(value=value, parent=self._instance) + + # These are related to the Python 3 implementation of the + # import system, + # https://docs.python.org/3/reference/import.html#import-related-module-attributes + + @property + def py__spec__(self): + # No handling for now. + return node_classes.Unknown() + + @property + def py__loader__(self): + # No handling for now. + return node_classes.Unknown() + + @property + def py__cached__(self): + # No handling for now. + return node_classes.Unknown() + + +class FunctionModel(ObjectModel): + @property + def py__name__(self): + return node_classes.Const(value=self._instance.name, parent=self._instance) + + @property + def py__doc__(self): + return node_classes.Const(value=self._instance.doc, parent=self._instance) + + @property + def py__qualname__(self): + return node_classes.Const(value=self._instance.qname(), parent=self._instance) + + @property + def py__defaults__(self): + func = self._instance + if not func.args.defaults: + return node_classes.Const(value=None, parent=func) + + defaults_obj = node_classes.Tuple(parent=func) + defaults_obj.postinit(func.args.defaults) + return defaults_obj + + @property + def py__annotations__(self): + obj = node_classes.Dict(parent=self._instance) + + if not self._instance.returns: + returns = None + else: + returns = self._instance.returns + + args = self._instance.args + pair_annotations = itertools.chain( + zip(args.args or [], args.annotations), + zip(args.kwonlyargs, args.kwonlyargs_annotations), + ) + + annotations = { + arg.name: annotation for (arg, annotation) in pair_annotations if annotation + } + if args.varargannotation: + annotations[args.vararg] = args.varargannotation + if args.kwargannotation: + annotations[args.kwarg] = args.kwargannotation + if returns: + annotations["return"] = returns + + items = [ + (node_classes.Const(key, parent=obj), value) + for (key, value) in annotations.items() + ] + + obj.postinit(items) + return obj + + @property + def py__dict__(self): + return node_classes.Dict(parent=self._instance) + + py__globals__ = py__dict__ + + @property + def py__kwdefaults__(self): + def _default_args(args, parent): + for arg in args.kwonlyargs: + try: + default = args.default_value(arg.name) + except exceptions.NoDefault: + continue + + name = node_classes.Const(arg.name, parent=parent) + yield name, default + + args = self._instance.args + obj = node_classes.Dict(parent=self._instance) + defaults = dict(_default_args(args, obj)) + + obj.postinit(list(defaults.items())) + return obj + + @property + def py__module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def py__get__(self): + from astroid import bases + + func = self._instance + + class DescriptorBoundMethod(bases.BoundMethod): + """Bound method which knows how to understand calling descriptor binding.""" + + def implicit_parameters(self): + # Different than BoundMethod since the signature + # is different. + return 0 + + def infer_call_result(self, caller, context=None): + if len(caller.args) != 2: + raise exceptions.InferenceError( + "Invalid arguments for descriptor binding", + target=self, + context=context, + ) + + context = contextmod.copy_context(context) + cls = next(caller.args[0].infer(context=context)) + + if cls is astroid.Uninferable: + raise exceptions.InferenceError( + "Invalid class inferred", target=self, context=context + ) + + # For some reason func is a Node that the below + # code is not expecting + if isinstance(func, bases.BoundMethod): + yield func + return + + # Rebuild the original value, but with the parent set as the + # class where it will be bound. + new_func = func.__class__( + name=func.name, + doc=func.doc, + lineno=func.lineno, + col_offset=func.col_offset, + parent=cls, + ) + # pylint: disable=no-member + new_func.postinit(func.args, func.body, func.decorators, func.returns) + + # Build a proper bound method that points to our newly built function. + proxy = bases.UnboundMethod(new_func) + yield bases.BoundMethod(proxy=proxy, bound=cls) + + @property + def args(self): + """Overwrite the underlying args to match those of the underlying func + + Usually the underlying *func* is a function/method, as in: + + def test(self): + pass + + This has only the *self* parameter but when we access test.__get__ + we get a new object which has two parameters, *self* and *type*. + """ + nonlocal func + params = func.args.args.copy() + params.append(astroid.AssignName(name="type")) + arguments = astroid.Arguments(parent=func.args.parent) + arguments.postinit( + args=params, + defaults=[], + kwonlyargs=[], + kw_defaults=[], + annotations=[], + ) + return arguments + + return DescriptorBoundMethod(proxy=self._instance, bound=self._instance) + + # These are here just for completion. + @property + def py__ne__(self): + return node_classes.Unknown() + + py__subclasshook__ = py__ne__ + py__str__ = py__ne__ + py__sizeof__ = py__ne__ + py__setattr__ = py__ne__ + py__repr__ = py__ne__ + py__reduce__ = py__ne__ + py__reduce_ex__ = py__ne__ + py__new__ = py__ne__ + py__lt__ = py__ne__ + py__eq__ = py__ne__ + py__gt__ = py__ne__ + py__format__ = py__ne__ + py__delattr__ = py__ne__ + py__getattribute__ = py__ne__ + py__hash__ = py__ne__ + py__init__ = py__ne__ + py__dir__ = py__ne__ + py__call__ = py__ne__ + py__class__ = py__ne__ + py__closure__ = py__ne__ + py__code__ = py__ne__ + + +class ClassModel(ObjectModel): + @property + def py__module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def py__name__(self): + return node_classes.Const(self._instance.name) + + @property + def py__qualname__(self): + return node_classes.Const(self._instance.qname()) + + @property + def py__doc__(self): + return node_classes.Const(self._instance.doc) + + @property + def py__mro__(self): + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__mro__" + ) + + mro = self._instance.mro() + obj = node_classes.Tuple(parent=self._instance) + obj.postinit(mro) + return obj + + @property + def pymro(self): + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="mro" + ) + + from astroid import bases + + other_self = self + + # Cls.mro is a method and we need to return one in order to have a proper inference. + # The method we're returning is capable of inferring the underlying MRO though. + class MroBoundMethod(bases.BoundMethod): + def infer_call_result(self, caller, context=None): + yield other_self.py__mro__ + + implicit_metaclass = self._instance.implicit_metaclass() + mro_method = implicit_metaclass.locals["mro"][0] + return MroBoundMethod(proxy=mro_method, bound=implicit_metaclass) + + @property + def py__bases__(self): + obj = node_classes.Tuple() + context = contextmod.InferenceContext() + elts = list(self._instance._inferred_bases(context)) + obj.postinit(elts=elts) + return obj + + @property + def py__class__(self): + from astroid import helpers + + return helpers.object_type(self._instance) + + @property + def py__subclasses__(self): + """Get the subclasses of the underlying class + + This looks only in the current module for retrieving the subclasses, + thus it might miss a couple of them. + """ + from astroid import bases + from astroid import scoped_nodes + + if not self._instance.newstyle: + raise exceptions.AttributeInferenceError( + target=self._instance, attribute="__subclasses__" + ) + + qname = self._instance.qname() + root = self._instance.root() + classes = [ + cls + for cls in root.nodes_of_class(scoped_nodes.ClassDef) + if cls != self._instance and cls.is_subtype_of(qname) + ] + + obj = node_classes.List(parent=self._instance) + obj.postinit(classes) + + class SubclassesBoundMethod(bases.BoundMethod): + def infer_call_result(self, caller, context=None): + yield obj + + implicit_metaclass = self._instance.implicit_metaclass() + subclasses_method = implicit_metaclass.locals["__subclasses__"][0] + return SubclassesBoundMethod(proxy=subclasses_method, bound=implicit_metaclass) + + @property + def py__dict__(self): + return node_classes.Dict(parent=self._instance) + + +class SuperModel(ObjectModel): + @property + def py__thisclass__(self): + return self._instance.mro_pointer + + @property + def py__self_class__(self): + return self._instance._self_class + + @property + def py__self__(self): + return self._instance.type + + @property + def py__class__(self): + return self._instance._proxied + + +class UnboundMethodModel(ObjectModel): + @property + def py__class__(self): + from astroid import helpers + + return helpers.object_type(self._instance) + + @property + def py__func__(self): + return self._instance._proxied + + @property + def py__self__(self): + return node_classes.Const(value=None, parent=self._instance) + + pyim_func = py__func__ + pyim_class = py__class__ + pyim_self = py__self__ + + +class BoundMethodModel(FunctionModel): + @property + def py__func__(self): + return self._instance._proxied._proxied + + @property + def py__self__(self): + return self._instance.bound + + +class GeneratorModel(FunctionModel): + def __new__(cls, *args, **kwargs): + # Append the values from the GeneratorType unto this object. + ret = super(GeneratorModel, cls).__new__(cls, *args, **kwargs) + generator = astroid.MANAGER.astroid_cache[builtins.__name__]["generator"] + for name, values in generator.locals.items(): + method = values[0] + patched = lambda cls, meth=method: meth + + setattr(type(ret), "py" + name, property(patched)) + + return ret + + @property + def py__name__(self): + return node_classes.Const( + value=self._instance.parent.name, parent=self._instance + ) + + @property + def py__doc__(self): + return node_classes.Const( + value=self._instance.parent.doc, parent=self._instance + ) + + +class AsyncGeneratorModel(GeneratorModel): + def __new__(cls, *args, **kwargs): + # Append the values from the AGeneratorType unto this object. + ret = super().__new__(cls, *args, **kwargs) + astroid_builtins = astroid.MANAGER.astroid_cache[builtins.__name__] + generator = astroid_builtins.get("async_generator") + if generator is None: + # Make it backward compatible. + generator = astroid_builtins.get("generator") + + for name, values in generator.locals.items(): + method = values[0] + patched = lambda cls, meth=method: meth + + setattr(type(ret), "py" + name, property(patched)) + + return ret + + +class InstanceModel(ObjectModel): + @property + def py__class__(self): + return self._instance._proxied + + @property + def py__module__(self): + return node_classes.Const(self._instance.root().qname()) + + @property + def py__doc__(self): + return node_classes.Const(self._instance.doc) + + @property + def py__dict__(self): + return _dunder_dict(self._instance, self._instance.instance_attrs) + + +class ExceptionInstanceModel(InstanceModel): + @property + def pyargs(self): + message = node_classes.Const("") + args = node_classes.Tuple(parent=self._instance) + args.postinit((message,)) + return args + + @property + def py__traceback__(self): + builtins_ast_module = astroid.MANAGER.astroid_cache[builtins.__name__] + traceback_type = builtins_ast_module[types.TracebackType.__name__] + return traceback_type.instantiate_class() + + +class DictModel(ObjectModel): + @property + def py__class__(self): + return self._instance._proxied + + def _generic_dict_attribute(self, obj, name): + """Generate a bound method that can infer the given *obj*.""" + + class DictMethodBoundMethod(astroid.BoundMethod): + def infer_call_result(self, caller, context=None): + yield obj + + meth = next(self._instance._proxied.igetattr(name)) + return DictMethodBoundMethod(proxy=meth, bound=self._instance) + + @property + def pyitems(self): + elems = [] + obj = node_classes.List(parent=self._instance) + for key, value in self._instance.items: + elem = node_classes.Tuple(parent=obj) + elem.postinit((key, value)) + elems.append(elem) + obj.postinit(elts=elems) + + from astroid import objects + + obj = objects.DictItems(obj) + + return self._generic_dict_attribute(obj, "items") + + @property + def pykeys(self): + keys = [key for (key, _) in self._instance.items] + obj = node_classes.List(parent=self._instance) + obj.postinit(elts=keys) + + from astroid import objects + + obj = objects.DictKeys(obj) + + return self._generic_dict_attribute(obj, "keys") + + @property + def pyvalues(self): + + values = [value for (_, value) in self._instance.items] + obj = node_classes.List(parent=self._instance) + obj.postinit(values) + + from astroid import objects + + obj = objects.DictValues(obj) + + return self._generic_dict_attribute(obj, "values") diff --git a/basic python programmes/venv/Lib/site-packages/astroid/manager.py b/basic python programmes/venv/Lib/site-packages/astroid/manager.py new file mode 100644 index 0000000..f05588a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/manager.py @@ -0,0 +1,319 @@ +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 BioGeek +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017 Iva Miholic +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""astroid manager: avoid multiple astroid build of a same module when +possible by providing a class responsible to get astroid representation +from various source and using a cache of built modules) +""" + +import os +import zipimport + +from astroid import exceptions +from astroid.interpreter._import import spec +from astroid import modutils +from astroid import transforms + + +def safe_repr(obj): + try: + return repr(obj) + except Exception: # pylint: disable=broad-except + return "???" + + +class AstroidManager: + """the astroid manager, responsible to build astroid from files + or modules. + + Use the Borg pattern. + """ + + name = "astroid loader" + brain = {} + + def __init__(self): + self.__dict__ = AstroidManager.brain + if not self.__dict__: + # NOTE: cache entries are added by the [re]builder + self.astroid_cache = {} + self._mod_file_cache = {} + self._failed_import_hooks = [] + self.always_load_extensions = False + self.optimize_ast = False + self.extension_package_whitelist = set() + self._transform = transforms.TransformVisitor() + + # Export these APIs for convenience + self.register_transform = self._transform.register_transform + self.unregister_transform = self._transform.unregister_transform + self.max_inferable_values = 100 + + def visit_transforms(self, node): + """Visit the transforms and apply them to the given *node*.""" + return self._transform.visit(node) + + def ast_from_file(self, filepath, modname=None, fallback=True, source=False): + """given a module name, return the astroid object""" + try: + filepath = modutils.get_source_file(filepath, include_no_ext=True) + source = True + except modutils.NoSourceFile: + pass + if modname is None: + try: + modname = ".".join(modutils.modpath_from_file(filepath)) + except ImportError: + modname = filepath + if ( + modname in self.astroid_cache + and self.astroid_cache[modname].file == filepath + ): + return self.astroid_cache[modname] + if source: + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).file_build(filepath, modname) + if fallback and modname: + return self.ast_from_module_name(modname) + raise exceptions.AstroidBuildingError( + "Unable to build an AST for {path}.", path=filepath + ) + + def _build_stub_module(self, modname): + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).string_build("", modname) + + def _build_namespace_module(self, modname, path): + from astroid.builder import build_namespace_package_module + + return build_namespace_package_module(modname, path) + + def _can_load_extension(self, modname): + if self.always_load_extensions: + return True + if modutils.is_standard_module(modname): + return True + parts = modname.split(".") + return any( + ".".join(parts[:x]) in self.extension_package_whitelist + for x in range(1, len(parts) + 1) + ) + + def ast_from_module_name(self, modname, context_file=None): + """given a module name, return the astroid object""" + if modname in self.astroid_cache: + return self.astroid_cache[modname] + if modname == "__main__": + return self._build_stub_module(modname) + old_cwd = os.getcwd() + if context_file: + os.chdir(os.path.dirname(context_file)) + try: + found_spec = self.file_from_module_name(modname, context_file) + if found_spec.type == spec.ModuleType.PY_ZIPMODULE: + module = self.zip_import_data(found_spec.location) + if module is not None: + return module + + elif found_spec.type in ( + spec.ModuleType.C_BUILTIN, + spec.ModuleType.C_EXTENSION, + ): + if ( + found_spec.type == spec.ModuleType.C_EXTENSION + and not self._can_load_extension(modname) + ): + return self._build_stub_module(modname) + try: + module = modutils.load_module_from_name(modname) + except Exception as ex: + raise exceptions.AstroidImportError( + "Loading {modname} failed with:\n{error}", + modname=modname, + path=found_spec.location, + ) from ex + return self.ast_from_module(module, modname) + + elif found_spec.type == spec.ModuleType.PY_COMPILED: + raise exceptions.AstroidImportError( + "Unable to load compiled module {modname}.", + modname=modname, + path=found_spec.location, + ) + + elif found_spec.type == spec.ModuleType.PY_NAMESPACE: + return self._build_namespace_module( + modname, found_spec.submodule_search_locations + ) + + if found_spec.location is None: + raise exceptions.AstroidImportError( + "Can't find a file for module {modname}.", modname=modname + ) + + return self.ast_from_file(found_spec.location, modname, fallback=False) + except exceptions.AstroidBuildingError as e: + for hook in self._failed_import_hooks: + try: + return hook(modname) + except exceptions.AstroidBuildingError: + pass + raise e + finally: + os.chdir(old_cwd) + + def zip_import_data(self, filepath): + if zipimport is None: + return None + from astroid.builder import AstroidBuilder + + builder = AstroidBuilder(self) + for ext in (".zip", ".egg"): + try: + eggpath, resource = filepath.rsplit(ext + os.path.sep, 1) + except ValueError: + continue + try: + importer = zipimport.zipimporter(eggpath + ext) + zmodname = resource.replace(os.path.sep, ".") + if importer.is_package(resource): + zmodname = zmodname + ".__init__" + module = builder.string_build( + importer.get_source(resource), zmodname, filepath + ) + return module + except Exception: # pylint: disable=broad-except + continue + return None + + def file_from_module_name(self, modname, contextfile): + try: + value = self._mod_file_cache[(modname, contextfile)] + except KeyError: + try: + value = modutils.file_info_from_modpath( + modname.split("."), context_file=contextfile + ) + except ImportError as ex: + value = exceptions.AstroidImportError( + "Failed to import module {modname} with error:\n{error}.", + modname=modname, + error=ex, + ) + self._mod_file_cache[(modname, contextfile)] = value + if isinstance(value, exceptions.AstroidBuildingError): + raise value + return value + + def ast_from_module(self, module, modname=None): + """given an imported module, return the astroid object""" + modname = modname or module.__name__ + if modname in self.astroid_cache: + return self.astroid_cache[modname] + try: + # some builtin modules don't have __file__ attribute + filepath = module.__file__ + if modutils.is_python_source(filepath): + return self.ast_from_file(filepath, modname) + except AttributeError: + pass + from astroid.builder import AstroidBuilder + + return AstroidBuilder(self).module_build(module, modname) + + def ast_from_class(self, klass, modname=None): + """get astroid for the given class""" + if modname is None: + try: + modname = klass.__module__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get module for class {class_name}.", + cls=klass, + class_repr=safe_repr(klass), + modname=modname, + ) from exc + modastroid = self.ast_from_module_name(modname) + return modastroid.getattr(klass.__name__)[0] # XXX + + def infer_ast_from_something(self, obj, context=None): + """infer astroid for the given class""" + if hasattr(obj, "__class__") and not isinstance(obj, type): + klass = obj.__class__ + else: + klass = obj + try: + modname = klass.__module__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get module for {class_repr}.", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + except Exception as exc: + raise exceptions.AstroidImportError( + "Unexpected error while retrieving module for {class_repr}:\n" + "{error}", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + try: + name = klass.__name__ + except AttributeError as exc: + raise exceptions.AstroidBuildingError( + "Unable to get name for {class_repr}:\n", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + except Exception as exc: + raise exceptions.AstroidImportError( + "Unexpected error while retrieving name for {class_repr}:\n" "{error}", + cls=klass, + class_repr=safe_repr(klass), + ) from exc + # take care, on living object __module__ is regularly wrong :( + modastroid = self.ast_from_module_name(modname) + if klass is obj: + for inferred in modastroid.igetattr(name, context): + yield inferred + else: + for inferred in modastroid.igetattr(name, context): + yield inferred.instantiate_class() + + def register_failed_import_hook(self, hook): + """Registers a hook to resolve imports that cannot be found otherwise. + + `hook` must be a function that accepts a single argument `modname` which + contains the name of the module or package that could not be imported. + If `hook` can resolve the import, must return a node of type `astroid.Module`, + otherwise, it must raise `AstroidBuildingError`. + """ + self._failed_import_hooks.append(hook) + + def cache_module(self, module): + """Cache a module if no module with the same name is known yet.""" + self.astroid_cache.setdefault(module.name, module) + + def clear_cache(self, astroid_builtin=None): + # XXX clear transforms + self.astroid_cache.clear() + # force bootstrap again, else we may ends up with cache inconsistency + # between the manager and CONST_PROXY, making + # unittest_lookup.LookupTC.test_builtin_lookup fail depending on the + # test order + import astroid.raw_building + + astroid.raw_building._astroid_bootstrapping(astroid_builtin=astroid_builtin) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/mixins.py b/basic python programmes/venv/Lib/site-packages/astroid/mixins.py new file mode 100644 index 0000000..497a840 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/mixins.py @@ -0,0 +1,160 @@ +# Copyright (c) 2010-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2016, 2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""This module contains some mixins for the different nodes. +""" +import itertools + +from astroid import decorators +from astroid import exceptions + + +class BlockRangeMixIn: + """override block range """ + + @decorators.cachedproperty + def blockstart_tolineno(self): + return self.lineno + + def _elsed_block_range(self, lineno, orelse, last=None): + """handle block line numbers range for try/finally, for, if and while + statements + """ + if lineno == self.fromlineno: + return lineno, lineno + if orelse: + if lineno >= orelse[0].fromlineno: + return lineno, orelse[-1].tolineno + return lineno, orelse[0].fromlineno - 1 + return lineno, last or self.tolineno + + +class FilterStmtsMixin: + """Mixin for statement filtering and assignment type""" + + def _get_filtered_stmts(self, _, node, _stmts, mystmt): + """method used in _filter_stmts to get statements and trigger break""" + if self.statement() is mystmt: + # original node's statement is the assignment, only keep + # current node (gen exp, list comp) + return [node], True + return _stmts, False + + def assign_type(self): + return self + + +class AssignTypeMixin: + def assign_type(self): + return self + + def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt): + """method used in filter_stmts""" + if self is mystmt: + return _stmts, True + if self.statement() is mystmt: + # original node's statement is the assignment, only keep + # current node (gen exp, list comp) + return [node], True + return _stmts, False + + +class ParentAssignTypeMixin(AssignTypeMixin): + def assign_type(self): + return self.parent.assign_type() + + +class ImportFromMixin(FilterStmtsMixin): + """MixIn for From and Import Nodes""" + + def _infer_name(self, frame, name): + return name + + def do_import_module(self, modname=None): + """return the ast for a module whose name is imported by + """ + # handle special case where we are on a package node importing a module + # using the same name as the package, which may end in an infinite loop + # on relative imports + # XXX: no more needed ? + mymodule = self.root() + level = getattr(self, "level", None) # Import as no level + if modname is None: + modname = self.modname + # XXX we should investigate deeper if we really want to check + # importing itself: modname and mymodule.name be relative or absolute + if mymodule.relative_to_absolute_name(modname, level) == mymodule.name: + # FIXME: we used to raise InferenceError here, but why ? + return mymodule + + return mymodule.import_module( + modname, level=level, relative_only=level and level >= 1 + ) + + def real_name(self, asname): + """get name from 'as' name""" + for name, _asname in self.names: + if name == "*": + return asname + if not _asname: + name = name.split(".", 1)[0] + _asname = name + if asname == _asname: + return name + raise exceptions.AttributeInferenceError( + "Could not find original name for {attribute} in {target!r}", + target=self, + attribute=asname, + ) + + +class MultiLineBlockMixin: + """Mixin for nodes with multi-line blocks, e.g. For and FunctionDef. + Note that this does not apply to every node with a `body` field. + For instance, an If node has a multi-line body, but the body of an + IfExpr is not multi-line, and hence cannot contain Return nodes, + Assign nodes, etc. + """ + + @decorators.cachedproperty + def _multi_line_blocks(self): + return tuple(getattr(self, field) for field in self._multi_line_block_fields) + + def _get_return_nodes_skip_functions(self): + for block in self._multi_line_blocks: + for child_node in block: + if child_node.is_function: + continue + yield from child_node._get_return_nodes_skip_functions() + + def _get_yield_nodes_skip_lambdas(self): + for block in self._multi_line_blocks: + for child_node in block: + if child_node.is_lambda: + continue + yield from child_node._get_yield_nodes_skip_lambdas() + + @decorators.cached + def _get_assign_nodes(self): + children_assign_nodes = ( + child_node._get_assign_nodes() + for block in self._multi_line_blocks + for child_node in block + ) + return list(itertools.chain.from_iterable(children_assign_nodes)) + + +class NoChildrenMixin: + """Mixin for nodes with no children, e.g. Pass.""" + + def get_children(self): + yield from () diff --git a/basic python programmes/venv/Lib/site-packages/astroid/modutils.py b/basic python programmes/venv/Lib/site-packages/astroid/modutils.py new file mode 100644 index 0000000..4e6f918 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/modutils.py @@ -0,0 +1,704 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Denis Laxalde +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Radosław Ganczarek +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2018 Mario Corchero +# Copyright (c) 2018 Mario Corchero +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Python modules manipulation utility functions. + +:type PY_SOURCE_EXTS: tuple(str) +:var PY_SOURCE_EXTS: list of possible python source file extension + +:type STD_LIB_DIRS: set of str +:var STD_LIB_DIRS: directories where standard modules are located + +:type BUILTIN_MODULES: dict +:var BUILTIN_MODULES: dictionary with builtin module names has key +""" +import imp +import os +import platform +import sys +import itertools +from distutils.sysconfig import get_python_lib # pylint: disable=import-error + +# pylint: disable=import-error, no-name-in-module +from distutils.errors import DistutilsPlatformError + +# distutils is replaced by virtualenv with a module that does +# weird path manipulations in order to get to the +# real distutils module. + +from .interpreter._import import spec +from .interpreter._import import util + +if sys.platform.startswith("win"): + PY_SOURCE_EXTS = ("py", "pyw") + PY_COMPILED_EXTS = ("dll", "pyd") +else: + PY_SOURCE_EXTS = ("py",) + PY_COMPILED_EXTS = ("so",) + + +try: + # The explicit sys.prefix is to work around a patch in virtualenv that + # replaces the 'real' sys.prefix (i.e. the location of the binary) + # with the prefix from which the virtualenv was created. This throws + # off the detection logic for standard library modules, thus the + # workaround. + STD_LIB_DIRS = { + get_python_lib(standard_lib=True, prefix=sys.prefix), + # Take care of installations where exec_prefix != prefix. + get_python_lib(standard_lib=True, prefix=sys.exec_prefix), + get_python_lib(standard_lib=True), + } +# get_python_lib(standard_lib=1) is not available on pypy, set STD_LIB_DIR to +# non-valid path, see https://bugs.pypy.org/issue1164 +except DistutilsPlatformError: + STD_LIB_DIRS = set() + +if os.name == "nt": + STD_LIB_DIRS.add(os.path.join(sys.prefix, "dlls")) + try: + # real_prefix is defined when running inside virtual environments, + # created with the **virtualenv** library. + STD_LIB_DIRS.add(os.path.join(sys.real_prefix, "dlls")) + except AttributeError: + # sys.base_exec_prefix is always defined, but in a virtual environment + # created with the stdlib **venv** module, it points to the original + # installation, if the virtual env is activated. + try: + STD_LIB_DIRS.add(os.path.join(sys.base_exec_prefix, "dlls")) + except AttributeError: + pass + +if platform.python_implementation() == "PyPy": + _root = os.path.join(sys.prefix, "lib_pypy") + STD_LIB_DIRS.add(_root) + try: + # real_prefix is defined when running inside virtualenv. + STD_LIB_DIRS.add(os.path.join(sys.real_prefix, "lib_pypy")) + except AttributeError: + pass + del _root +if os.name == "posix": + # Need the real prefix is we're under a virtualenv, otherwise + # the usual one will do. + try: + prefix = sys.real_prefix + except AttributeError: + prefix = sys.prefix + + def _posix_path(path): + base_python = "python%d.%d" % sys.version_info[:2] + return os.path.join(prefix, path, base_python) + + STD_LIB_DIRS.add(_posix_path("lib")) + if sys.maxsize > 2 ** 32: + # This tries to fix a problem with /usr/lib64 builds, + # where systems are running both 32-bit and 64-bit code + # on the same machine, which reflects into the places where + # standard library could be found. More details can be found + # here http://bugs.python.org/issue1294959. + # An easy reproducing case would be + # https://github.com/PyCQA/pylint/issues/712#issuecomment-163178753 + STD_LIB_DIRS.add(_posix_path("lib64")) + +EXT_LIB_DIR = get_python_lib() +IS_JYTHON = platform.python_implementation() == "Jython" +BUILTIN_MODULES = dict.fromkeys(sys.builtin_module_names, True) + + +class NoSourceFile(Exception): + """exception raised when we are not able to get a python + source file for a precompiled file + """ + + +def _normalize_path(path): + return os.path.normcase(os.path.abspath(path)) + + +def _canonicalize_path(path): + return os.path.realpath(os.path.expanduser(path)) + + +def _path_from_filename(filename, is_jython=IS_JYTHON): + if not is_jython: + if sys.version_info > (3, 0): + return filename + if filename.endswith(".pyc"): + return filename[:-1] + return filename + head, has_pyclass, _ = filename.partition("$py.class") + if has_pyclass: + return head + ".py" + return filename + + +def _handle_blacklist(blacklist, dirnames, filenames): + """remove files/directories in the black list + + dirnames/filenames are usually from os.walk + """ + for norecurs in blacklist: + if norecurs in dirnames: + dirnames.remove(norecurs) + elif norecurs in filenames: + filenames.remove(norecurs) + + +_NORM_PATH_CACHE = {} + + +def _cache_normalize_path(path): + """abspath with caching""" + # _module_file calls abspath on every path in sys.path every time it's + # called; on a larger codebase this easily adds up to half a second just + # assembling path components. This cache alleviates that. + try: + return _NORM_PATH_CACHE[path] + except KeyError: + if not path: # don't cache result for '' + return _normalize_path(path) + result = _NORM_PATH_CACHE[path] = _normalize_path(path) + return result + + +def load_module_from_name(dotted_name, path=None, use_sys=True): + """Load a Python module from its name. + + :type dotted_name: str + :param dotted_name: python name of a module or package + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be + used or not + + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + return load_module_from_modpath(dotted_name.split("."), path, use_sys) + + +def load_module_from_modpath(parts, path=None, use_sys=1): + """Load a python module from its split name. + + :type parts: list(str) or tuple(str) + :param parts: + python name of a module or package split on '.' + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be used or not + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + if use_sys: + try: + return sys.modules[".".join(parts)] + except KeyError: + pass + modpath = [] + prevmodule = None + for part in parts: + modpath.append(part) + curname = ".".join(modpath) + module = None + if len(modpath) != len(parts): + # even with use_sys=False, should try to get outer packages from sys.modules + module = sys.modules.get(curname) + elif use_sys: + # because it may have been indirectly loaded through a parent + module = sys.modules.get(curname) + if module is None: + mp_file, mp_filename, mp_desc = imp.find_module(part, path) + module = imp.load_module(curname, mp_file, mp_filename, mp_desc) + # mp_file still needs to be closed. + if mp_file: + mp_file.close() + if prevmodule: + setattr(prevmodule, part, module) + _file = getattr(module, "__file__", "") + prevmodule = module + if not _file and util.is_namespace(curname): + continue + if not _file and len(modpath) != len(parts): + raise ImportError("no module in %s" % ".".join(parts[len(modpath) :])) + path = [os.path.dirname(_file)] + return module + + +def load_module_from_file(filepath, path=None, use_sys=True, extrapath=None): + """Load a Python module from it's path. + + :type filepath: str + :param filepath: path to the python module or package + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type use_sys: bool + :param use_sys: + boolean indicating whether the sys.modules dictionary should be + used or not + + + :raise ImportError: if the module or package is not found + + :rtype: module + :return: the loaded module + """ + modpath = modpath_from_file(filepath, extrapath) + return load_module_from_modpath(modpath, path, use_sys) + + +def check_modpath_has_init(path, mod_path): + """check there are some __init__.py all along the way""" + modpath = [] + for part in mod_path: + modpath.append(part) + path = os.path.join(path, part) + if not _has_init(path): + old_namespace = util.is_namespace(".".join(modpath)) + if not old_namespace: + return False + return True + + +def _get_relative_base_path(filename, path_to_check): + """Extracts the relative mod path of the file to import from + + Check if a file is within the passed in path and if so, returns the + relative mod path from the one passed in. + + If the filename is no in path_to_check, returns None + + Note this function will look for both abs and realpath of the file, + this allows to find the relative base path even if the file is a + symlink of a file in the passed in path + + Examples: + _get_relative_base_path("/a/b/c/d.py", "/a/b") -> ["c","d"] + _get_relative_base_path("/a/b/c/d.py", "/dev") -> None + """ + importable_path = None + path_to_check = os.path.normcase(path_to_check) + abs_filename = os.path.abspath(filename) + if os.path.normcase(abs_filename).startswith(path_to_check): + importable_path = abs_filename + + real_filename = os.path.realpath(filename) + if os.path.normcase(real_filename).startswith(path_to_check): + importable_path = real_filename + + if importable_path: + base_path = os.path.splitext(importable_path)[0] + relative_base_path = base_path[len(path_to_check) :] + return [pkg for pkg in relative_base_path.split(os.sep) if pkg] + + return None + + +def modpath_from_file_with_callback(filename, extrapath=None, is_package_cb=None): + filename = os.path.expanduser(_path_from_filename(filename)) + + if extrapath is not None: + for path_ in itertools.chain(map(_canonicalize_path, extrapath), extrapath): + path = os.path.abspath(path_) + if not path: + continue + submodpath = _get_relative_base_path(filename, path) + if not submodpath: + continue + if is_package_cb(path, submodpath[:-1]): + return extrapath[path_].split(".") + submodpath + + for path in itertools.chain(map(_canonicalize_path, sys.path), sys.path): + path = _cache_normalize_path(path) + if not path: + continue + modpath = _get_relative_base_path(filename, path) + if not modpath: + continue + if is_package_cb(path, modpath[:-1]): + return modpath + + raise ImportError( + "Unable to find module for %s in %s" % (filename, ", \n".join(sys.path)) + ) + + +def modpath_from_file(filename, extrapath=None): + """given a file path return the corresponding split module's name + (i.e name of a module or package split on '.') + + :type filename: str + :param filename: file's path for which we want the module's name + + :type extrapath: dict + :param extrapath: + optional extra search path, with path as key and package name for the path + as value. This is usually useful to handle package split in multiple + directories using __path__ trick. + + + :raise ImportError: + if the corresponding module's name has not been found + + :rtype: list(str) + :return: the corresponding split module's name + """ + return modpath_from_file_with_callback(filename, extrapath, check_modpath_has_init) + + +def file_from_modpath(modpath, path=None, context_file=None): + return file_info_from_modpath(modpath, path, context_file).location + + +def file_info_from_modpath(modpath, path=None, context_file=None): + """given a mod path (i.e. split module / package name), return the + corresponding file, giving priority to source file over precompiled + file if it exists + + :type modpath: list or tuple + :param modpath: + split module's name (i.e name of a module or package split + on '.') + (this means explicit relative imports that start with dots have + empty strings in this list!) + + :type path: list or None + :param path: + optional list of path where the module or package should be + searched (use sys.path if nothing or None is given) + + :type context_file: str or None + :param context_file: + context file to consider, necessary if the identifier has been + introduced using a relative import unresolvable in the actual + context (i.e. modutils) + + :raise ImportError: if there is no such module in the directory + + :rtype: (str or None, import type) + :return: + the path to the module's file or None if it's an integrated + builtin module such as 'sys' + """ + if context_file is not None: + context = os.path.dirname(context_file) + else: + context = context_file + if modpath[0] == "xml": + # handle _xmlplus + try: + return _spec_from_modpath(["_xmlplus"] + modpath[1:], path, context) + except ImportError: + return _spec_from_modpath(modpath, path, context) + elif modpath == ["os", "path"]: + # FIXME: currently ignoring search_path... + return spec.ModuleSpec( + name="os.path", location=os.path.__file__, module_type=imp.PY_SOURCE + ) + return _spec_from_modpath(modpath, path, context) + + +def get_module_part(dotted_name, context_file=None): + """given a dotted name return the module part of the name : + + >>> get_module_part('astroid.as_string.dump') + 'astroid.as_string' + + :type dotted_name: str + :param dotted_name: full name of the identifier we are interested in + + :type context_file: str or None + :param context_file: + context file to consider, necessary if the identifier has been + introduced using a relative import unresolvable in the actual + context (i.e. modutils) + + + :raise ImportError: if there is no such module in the directory + + :rtype: str or None + :return: + the module part of the name or None if we have not been able at + all to import the given name + + XXX: deprecated, since it doesn't handle package precedence over module + (see #10066) + """ + # os.path trick + if dotted_name.startswith("os.path"): + return "os.path" + parts = dotted_name.split(".") + if context_file is not None: + # first check for builtin module which won't be considered latter + # in that case (path != None) + if parts[0] in BUILTIN_MODULES: + if len(parts) > 2: + raise ImportError(dotted_name) + return parts[0] + # don't use += or insert, we want a new list to be created ! + path = None + starti = 0 + if parts[0] == "": + assert ( + context_file is not None + ), "explicit relative import, but no context_file?" + path = [] # prevent resolving the import non-relatively + starti = 1 + while parts[starti] == "": # for all further dots: change context + starti += 1 + context_file = os.path.dirname(context_file) + for i in range(starti, len(parts)): + try: + file_from_modpath( + parts[starti : i + 1], path=path, context_file=context_file + ) + except ImportError: + if i < max(1, len(parts) - 2): + raise + return ".".join(parts[:i]) + return dotted_name + + +def get_module_files(src_directory, blacklist, list_all=False): + """given a package directory return a list of all available python + module's files in the package and its subpackages + + :type src_directory: str + :param src_directory: + path of the directory corresponding to the package + + :type blacklist: list or tuple + :param blacklist: iterable + list of files or directories to ignore. + + :type list_all: bool + :param list_all: + get files from all paths, including ones without __init__.py + + :rtype: list + :return: + the list of all available python module's files in the package and + its subpackages + """ + files = [] + for directory, dirnames, filenames in os.walk(src_directory): + if directory in blacklist: + continue + _handle_blacklist(blacklist, dirnames, filenames) + # check for __init__.py + if not list_all and "__init__.py" not in filenames: + dirnames[:] = () + continue + for filename in filenames: + if _is_python_file(filename): + src = os.path.join(directory, filename) + files.append(src) + return files + + +def get_source_file(filename, include_no_ext=False): + """given a python module's file name return the matching source file + name (the filename will be returned identically if it's already an + absolute path to a python source file...) + + :type filename: str + :param filename: python module's file name + + + :raise NoSourceFile: if no source file exists on the file system + + :rtype: str + :return: the absolute path of the source file if it exists + """ + filename = os.path.abspath(_path_from_filename(filename)) + base, orig_ext = os.path.splitext(filename) + for ext in PY_SOURCE_EXTS: + source_path = "%s.%s" % (base, ext) + if os.path.exists(source_path): + return source_path + if include_no_ext and not orig_ext and os.path.exists(base): + return base + raise NoSourceFile(filename) + + +def is_python_source(filename): + """ + rtype: bool + return: True if the filename is a python source file + """ + return os.path.splitext(filename)[1][1:] in PY_SOURCE_EXTS + + +def is_standard_module(modname, std_path=None): + """try to guess if a module is a standard python module (by default, + see `std_path` parameter's description) + + :type modname: str + :param modname: name of the module we are interested in + + :type std_path: list(str) or tuple(str) + :param std_path: list of path considered has standard + + + :rtype: bool + :return: + true if the module: + - is located on the path listed in one of the directory in `std_path` + - is a built-in module + """ + modname = modname.split(".")[0] + try: + filename = file_from_modpath([modname]) + except ImportError: + # import failed, i'm probably not so wrong by supposing it's + # not standard... + return False + # modules which are not living in a file are considered standard + # (sys and __builtin__ for instance) + if filename is None: + # we assume there are no namespaces in stdlib + return not util.is_namespace(modname) + filename = _normalize_path(filename) + if filename.startswith(_cache_normalize_path(EXT_LIB_DIR)): + return False + if std_path is None: + std_path = STD_LIB_DIRS + for path in std_path: + if filename.startswith(_cache_normalize_path(path)): + return True + return False + + +def is_relative(modname, from_file): + """return true if the given module name is relative to the given + file name + + :type modname: str + :param modname: name of the module we are interested in + + :type from_file: str + :param from_file: + path of the module from which modname has been imported + + :rtype: bool + :return: + true if the module has been imported relatively to `from_file` + """ + if not os.path.isdir(from_file): + from_file = os.path.dirname(from_file) + if from_file in sys.path: + return False + try: + stream, _, _ = imp.find_module(modname.split(".")[0], [from_file]) + + # Close the stream to avoid ResourceWarnings. + if stream: + stream.close() + return True + except ImportError: + return False + + +# internal only functions ##################################################### + + +def _spec_from_modpath(modpath, path=None, context=None): + """given a mod path (i.e. split module / package name), return the + corresponding spec + + this function is used internally, see `file_from_modpath`'s + documentation for more information + """ + assert modpath + location = None + if context is not None: + try: + found_spec = spec.find_spec(modpath, [context]) + location = found_spec.location + except ImportError: + found_spec = spec.find_spec(modpath, path) + location = found_spec.location + else: + found_spec = spec.find_spec(modpath, path) + if found_spec.type == spec.ModuleType.PY_COMPILED: + try: + location = get_source_file(found_spec.location) + return found_spec._replace( + location=location, type=spec.ModuleType.PY_SOURCE + ) + except NoSourceFile: + return found_spec._replace(location=location) + elif found_spec.type == spec.ModuleType.C_BUILTIN: + # integrated builtin module + return found_spec._replace(location=None) + elif found_spec.type == spec.ModuleType.PKG_DIRECTORY: + location = _has_init(found_spec.location) + return found_spec._replace(location=location, type=spec.ModuleType.PY_SOURCE) + return found_spec + + +def _is_python_file(filename): + """return true if the given filename should be considered as a python file + + .pyc and .pyo are ignored + """ + for ext in (".py", ".so", ".pyd", ".pyw"): + if filename.endswith(ext): + return True + return False + + +def _has_init(directory): + """if the given directory has a valid __init__ file, return its path, + else return None + """ + mod_or_pack = os.path.join(directory, "__init__") + for ext in PY_SOURCE_EXTS + ("pyc", "pyo"): + if os.path.exists(mod_or_pack + "." + ext): + return mod_or_pack + "." + ext + return None + + +def is_namespace(specobj): + return specobj.type == spec.ModuleType.PY_NAMESPACE + + +def is_directory(specobj): + return specobj.type == spec.ModuleType.PKG_DIRECTORY diff --git a/basic python programmes/venv/Lib/site-packages/astroid/node_classes.py b/basic python programmes/venv/Lib/site-packages/astroid/node_classes.py new file mode 100644 index 0000000..7ef6b0a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/node_classes.py @@ -0,0 +1,4676 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2016 Dave Baum +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 brendanator +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +# pylint: disable=too-many-lines; https://github.com/PyCQA/astroid/issues/465 + +"""Module for some node classes. More nodes in scoped_nodes.py +""" + +import abc +import builtins as builtins_mod +import itertools +import pprint +from functools import lru_cache +from functools import singledispatch as _singledispatch + +from astroid import as_string +from astroid import bases +from astroid import context as contextmod +from astroid import decorators +from astroid import exceptions +from astroid import manager +from astroid import mixins +from astroid import util + + +BUILTINS = builtins_mod.__name__ +MANAGER = manager.AstroidManager() + + +@decorators.raise_if_nothing_inferred +def unpack_infer(stmt, context=None): + """recursively generate nodes inferred by the given statement. + If the inferred value is a list or a tuple, recurse on the elements + """ + if isinstance(stmt, (List, Tuple)): + for elt in stmt.elts: + if elt is util.Uninferable: + yield elt + continue + yield from unpack_infer(elt, context) + return dict(node=stmt, context=context) + # if inferred is a final node, return it and stop + inferred = next(stmt.infer(context)) + if inferred is stmt: + yield inferred + return dict(node=stmt, context=context) + # else, infer recursively, except Uninferable object that should be returned as is + for inferred in stmt.infer(context): + if inferred is util.Uninferable: + yield inferred + else: + yield from unpack_infer(inferred, context) + + return dict(node=stmt, context=context) + + +def are_exclusive( + stmt1, stmt2, exceptions=None +): # pylint: disable=redefined-outer-name + """return true if the two given statements are mutually exclusive + + `exceptions` may be a list of exception names. If specified, discard If + branches and check one of the statement is in an exception handler catching + one of the given exceptions. + + algorithm : + 1) index stmt1's parents + 2) climb among stmt2's parents until we find a common parent + 3) if the common parent is a If or TryExcept statement, look if nodes are + in exclusive branches + """ + # index stmt1's parents + stmt1_parents = {} + children = {} + node = stmt1.parent + previous = stmt1 + while node: + stmt1_parents[node] = 1 + children[node] = previous + previous = node + node = node.parent + # climb among stmt2's parents until we find a common parent + node = stmt2.parent + previous = stmt2 + while node: + if node in stmt1_parents: + # if the common parent is a If or TryExcept statement, look if + # nodes are in exclusive branches + if isinstance(node, If) and exceptions is None: + if ( + node.locate_child(previous)[1] + is not node.locate_child(children[node])[1] + ): + return True + elif isinstance(node, TryExcept): + c2attr, c2node = node.locate_child(previous) + c1attr, c1node = node.locate_child(children[node]) + if c1node is not c2node: + first_in_body_caught_by_handlers = ( + c2attr == "handlers" + and c1attr == "body" + and previous.catch(exceptions) + ) + second_in_body_caught_by_handlers = ( + c2attr == "body" + and c1attr == "handlers" + and children[node].catch(exceptions) + ) + first_in_else_other_in_handlers = ( + c2attr == "handlers" and c1attr == "orelse" + ) + second_in_else_other_in_handlers = ( + c2attr == "orelse" and c1attr == "handlers" + ) + if any( + ( + first_in_body_caught_by_handlers, + second_in_body_caught_by_handlers, + first_in_else_other_in_handlers, + second_in_else_other_in_handlers, + ) + ): + return True + elif c2attr == "handlers" and c1attr == "handlers": + return previous is not children[node] + return False + previous = node + node = node.parent + return False + + +# getitem() helpers. + +_SLICE_SENTINEL = object() + + +def _slice_value(index, context=None): + """Get the value of the given slice index.""" + + if isinstance(index, Const): + if isinstance(index.value, (int, type(None))): + return index.value + elif index is None: + return None + else: + # Try to infer what the index actually is. + # Since we can't return all the possible values, + # we'll stop at the first possible value. + try: + inferred = next(index.infer(context=context)) + except exceptions.InferenceError: + pass + else: + if isinstance(inferred, Const): + if isinstance(inferred.value, (int, type(None))): + return inferred.value + + # Use a sentinel, because None can be a valid + # value that this function can return, + # as it is the case for unspecified bounds. + return _SLICE_SENTINEL + + +def _infer_slice(node, context=None): + lower = _slice_value(node.lower, context) + upper = _slice_value(node.upper, context) + step = _slice_value(node.step, context) + if all(elem is not _SLICE_SENTINEL for elem in (lower, upper, step)): + return slice(lower, upper, step) + + raise exceptions.AstroidTypeError( + message="Could not infer slice used in subscript", + node=node, + index=node.parent, + context=context, + ) + + +def _container_getitem(instance, elts, index, context=None): + """Get a slice or an item, using the given *index*, for the given sequence.""" + try: + if isinstance(index, Slice): + index_slice = _infer_slice(index, context=context) + new_cls = instance.__class__() + new_cls.elts = elts[index_slice] + new_cls.parent = instance.parent + return new_cls + if isinstance(index, Const): + return elts[index.value] + except IndexError as exc: + raise exceptions.AstroidIndexError( + message="Index {index!s} out of range", + node=instance, + index=index, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.AstroidTypeError( + message="Type error {error!r}", node=instance, index=index, context=context + ) from exc + + raise exceptions.AstroidTypeError("Could not use %s as subscript index" % index) + + +OP_PRECEDENCE = { + op: precedence + for precedence, ops in enumerate( + [ + ["Lambda"], # lambda x: x + 1 + ["IfExp"], # 1 if True else 2 + ["or"], + ["and"], + ["not"], + ["Compare"], # in, not in, is, is not, <, <=, >, >=, !=, == + ["|"], + ["^"], + ["&"], + ["<<", ">>"], + ["+", "-"], + ["*", "@", "/", "//", "%"], + ["UnaryOp"], # +, -, ~ + ["**"], + ["Await"], + ] + ) + for op in ops +} + + +class NodeNG: + """ A node of the new Abstract Syntax Tree (AST). + + This is the base class for all Astroid node classes. + """ + + is_statement = False + """Whether this node indicates a statement. + + :type: bool + """ + optional_assign = False # True for For (and for Comprehension if py <3.0) + """Whether this node optionally assigns a variable. + + This is for loop assignments because loop won't necessarily perform an + assignment if the loop has no iterations. + This is also the case from comprehensions in Python 2. + + :type: bool + """ + is_function = False # True for FunctionDef nodes + """Whether this node indicates a function. + + :type: bool + """ + is_lambda = False + # Attributes below are set by the builder module or by raw factories + lineno = None + """The line that this node appears on in the source code. + + :type: int or None + """ + col_offset = None + """The column that this node appears on in the source code. + + :type: int or None + """ + parent = None + """The parent node in the syntax tree. + + :type: NodeNG or None + """ + _astroid_fields = () + """Node attributes that contain child nodes. + + This is redefined in most concrete classes. + + :type: tuple(str) + """ + _other_fields = () + """Node attributes that do not contain child nodes. + + :type: tuple(str) + """ + _other_other_fields = () + """Attributes that contain AST-dependent fields. + + :type: tuple(str) + """ + # instance specific inference function infer(node, context) + _explicit_inference = None + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.lineno = lineno + self.col_offset = col_offset + self.parent = parent + + def infer(self, context=None, **kwargs): + """Get a generator of the inferred values. + + This is the main entry point to the inference system. + + .. seealso:: :ref:`inference` + + If the instance has some explicit inference function set, it will be + called instead of the default interface. + + :returns: The inferred values. + :rtype: iterable + """ + if context is not None: + context = context.extra_context.get(self, context) + if self._explicit_inference is not None: + # explicit_inference is not bound, give it self explicitly + try: + # pylint: disable=not-callable + return self._explicit_inference(self, context, **kwargs) + except exceptions.UseInferenceDefault: + pass + + if not context: + return self._infer(context, **kwargs) + + key = (self, context.lookupname, context.callcontext, context.boundnode) + if key in context.inferred: + return iter(context.inferred[key]) + + gen = context.cache_generator(key, self._infer(context, **kwargs)) + return util.limit_inference(gen, MANAGER.max_inferable_values) + + def _repr_name(self): + """Get a name for nice representation. + + This is either :attr:`name`, :attr:`attrname`, or the empty string. + + :returns: The nice name. + :rtype: str + """ + names = {"name", "attrname"} + if all(name not in self._astroid_fields for name in names): + return getattr(self, "name", getattr(self, "attrname", "")) + return "" + + def __str__(self): + rname = self._repr_name() + cname = type(self).__name__ + if rname: + string = "%(cname)s.%(rname)s(%(fields)s)" + alignment = len(cname) + len(rname) + 2 + else: + string = "%(cname)s(%(fields)s)" + alignment = len(cname) + 1 + result = [] + for field in self._other_fields + self._astroid_fields: + value = getattr(self, field) + width = 80 - len(field) - alignment + lines = pprint.pformat(value, indent=2, width=width).splitlines(True) + + inner = [lines[0]] + for line in lines[1:]: + inner.append(" " * alignment + line) + result.append("%s=%s" % (field, "".join(inner))) + + return string % { + "cname": cname, + "rname": rname, + "fields": (",\n" + " " * alignment).join(result), + } + + def __repr__(self): + rname = self._repr_name() + if rname: + string = "<%(cname)s.%(rname)s l.%(lineno)s at 0x%(id)x>" + else: + string = "<%(cname)s l.%(lineno)s at 0x%(id)x>" + return string % { + "cname": type(self).__name__, + "rname": rname, + "lineno": self.fromlineno, + "id": id(self), + } + + def accept(self, visitor): + """Visit this node using the given visitor.""" + func = getattr(visitor, "visit_" + self.__class__.__name__.lower()) + return func(self) + + def get_children(self): + """Get the child nodes below this node. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for field in self._astroid_fields: + attr = getattr(self, field) + if attr is None: + continue + if isinstance(attr, (list, tuple)): + yield from attr + else: + yield attr + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child, or None if no children exist. + :rtype: NodeNG or None + """ + for field in self._astroid_fields[::-1]: + attr = getattr(self, field) + if not attr: # None or empty listy / tuple + continue + if isinstance(attr, (list, tuple)): + return attr[-1] + + return attr + return None + + def parent_of(self, node): + """Check if this node is the parent of the given node. + + :param node: The node to check if it is the child. + :type node: NodeNG + + :returns: True if this node is the parent of the given node, + False otherwise. + :rtype: bool + """ + parent = node.parent + while parent is not None: + if self is parent: + return True + parent = parent.parent + return False + + def statement(self): + """The first parent node, including self, marked as statement node. + + :returns: The first parent statement. + :rtype: NodeNG + """ + if self.is_statement: + return self + return self.parent.statement() + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self.parent.frame() + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + return self.parent.scope() + + def root(self): + """Return the root node of the syntax tree. + + :returns: The root node. + :rtype: Module + """ + if self.parent: + return self.parent.root() + return self + + def child_sequence(self, child): + """Search for the sequence that contains this child. + + :param child: The child node to search sequences for. + :type child: NodeNG + + :returns: The sequence containing the given child node. + :rtype: iterable(NodeNG) + + :raises AstroidError: If no sequence could be found that contains + the given child. + """ + for field in self._astroid_fields: + node_or_sequence = getattr(self, field) + if node_or_sequence is child: + return [node_or_sequence] + # /!\ compiler.ast Nodes have an __iter__ walking over child nodes + if ( + isinstance(node_or_sequence, (tuple, list)) + and child in node_or_sequence + ): + return node_or_sequence + + msg = "Could not find %s in %s's children" + raise exceptions.AstroidError(msg % (repr(child), repr(self))) + + def locate_child(self, child): + """Find the field of this node that contains the given child. + + :param child: The child node to search fields for. + :type child: NodeNG + + :returns: A tuple of the name of the field that contains the child, + and the sequence or node that contains the child node. + :rtype: tuple(str, iterable(NodeNG) or NodeNG) + + :raises AstroidError: If no field could be found that contains + the given child. + """ + for field in self._astroid_fields: + node_or_sequence = getattr(self, field) + # /!\ compiler.ast Nodes have an __iter__ walking over child nodes + if child is node_or_sequence: + return field, child + if ( + isinstance(node_or_sequence, (tuple, list)) + and child in node_or_sequence + ): + return field, node_or_sequence + msg = "Could not find %s in %s's children" + raise exceptions.AstroidError(msg % (repr(child), repr(self))) + + # FIXME : should we merge child_sequence and locate_child ? locate_child + # is only used in are_exclusive, child_sequence one time in pylint. + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + return self.parent.next_sibling() + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + return self.parent.previous_sibling() + + def nearest(self, nodes): + """Get the node closest to this one from the given list of nodes. + + :param nodes: The list of nodes to search. All of these nodes must + belong to the same module as this one. The list should be + sorted by the line number of the nodes, smallest first. + :type nodes: iterable(NodeNG) + + :returns: The node closest to this one in the source code, + or None if one could not be found. + :rtype: NodeNG or None + """ + myroot = self.root() + mylineno = self.fromlineno + nearest = None, 0 + for node in nodes: + assert node.root() is myroot, ( + "nodes %s and %s are not from the same module" % (self, node) + ) + lineno = node.fromlineno + if node.fromlineno > mylineno: + break + if lineno > nearest[1]: + nearest = node, lineno + # FIXME: raise an exception if nearest is None ? + return nearest[0] + + # these are lazy because they're relatively expensive to compute for every + # single node, and they rarely get looked at + + @decorators.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + if self.lineno is None: + return self._fixed_source_line() + + return self.lineno + + @decorators.cachedproperty + def tolineno(self): + """The last line that this node appears on in the source code. + + :type: int or None + """ + if not self._astroid_fields: + # can't have children + lastchild = None + else: + lastchild = self.last_child() + if lastchild is None: + return self.fromlineno + + return lastchild.tolineno + + def _fixed_source_line(self): + """Attempt to find the line that this node appears on. + + We need this method since not all nodes have :attr:`lineno` set. + + :returns: The line number of this node, + or None if this could not be determined. + :rtype: int or None + """ + line = self.lineno + _node = self + try: + while line is None: + _node = next(_node.get_children()) + line = _node.lineno + except StopIteration: + _node = self.parent + while _node and line is None: + line = _node.lineno + _node = _node.parent + return line + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int or None) + """ + return lineno, self.tolineno + + def set_local(self, name, stmt): + """Define that the given name is declared in the given statement node. + + This definition is stored on the parent scope node. + + .. seealso:: :meth:`scope` + + :param name: The name that is being defined. + :type name: str + + :param stmt: The statement that defines the given name. + :type stmt: NodeNG + """ + self.parent.set_local(name, stmt) + + def nodes_of_class(self, klass, skip_klass=None): + """Get the nodes (including this one or below) of the given type. + + :param klass: The type of node to search for. + :type klass: builtins.type + + :param skip_klass: A type of node to ignore. This is useful to ignore + subclasses of :attr:`klass`. + :type skip_klass: builtins.type + + :returns: The node of the given type. + :rtype: iterable(NodeNG) + """ + if isinstance(self, klass): + yield self + + if skip_klass is None: + for child_node in self.get_children(): + yield from child_node.nodes_of_class(klass, skip_klass) + + return + + for child_node in self.get_children(): + if isinstance(child_node, skip_klass): + continue + yield from child_node.nodes_of_class(klass, skip_klass) + + @decorators.cached + def _get_assign_nodes(self): + return [] + + def _get_name_nodes(self): + for child_node in self.get_children(): + yield from child_node._get_name_nodes() + + def _get_return_nodes_skip_functions(self): + yield from () + + def _get_yield_nodes_skip_lambdas(self): + yield from () + + def _infer_name(self, frame, name): + # overridden for ImportFrom, Import, Global, TryExcept and Arguments + pass + + def _infer(self, context=None): + """we don't know how to resolve a statement by default""" + # this method is overridden by most concrete classes + raise exceptions.InferenceError( + "No inference function for {node!r}.", node=self, context=context + ) + + def inferred(self): + """Get a list of the inferred values. + + .. seealso:: :ref:`inference` + + :returns: The inferred values. + :rtype: list + """ + return list(self.infer()) + + def instantiate_class(self): + """Instantiate an instance of the defined class. + + .. note:: + + On anything other than a :class:`ClassDef` this will return self. + + :returns: An instance of the defined class. + :rtype: object + """ + return self + + def has_base(self, node): + """Check if this node inherits from the given type. + + :param node: The node defining the base to look for. + Usually this is a :class:`Name` node. + :type node: NodeNG + """ + return False + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + :rtype: bool + """ + return False + + def eq(self, value): + return False + + def as_string(self): + """Get the source code that this node represents. + + :returns: The source code. + :rtype: str + """ + return as_string.to_code(self) + + def repr_tree( + self, + ids=False, + include_linenos=False, + ast_state=False, + indent=" ", + max_depth=0, + max_width=80, + ): + """Get a string representation of the AST from this node. + + :param ids: If true, includes the ids with the node type names. + :type ids: bool + + :param include_linenos: If true, includes the line numbers and + column offsets. + :type include_linenos: bool + + :param ast_state: If true, includes information derived from + the whole AST like local and global variables. + :type ast_state: bool + + :param indent: A string to use to indent the output string. + :type indent: str + + :param max_depth: If set to a positive integer, won't return + nodes deeper than max_depth in the string. + :type max_depth: int + + :param max_width: Attempt to format the output string to stay + within this number of characters, but can exceed it under some + circumstances. Only positive integer values are valid, the default is 80. + :type max_width: int + + :returns: The string representation of the AST. + :rtype: str + """ + # pylint: disable=too-many-statements + @_singledispatch + def _repr_tree(node, result, done, cur_indent="", depth=1): + """Outputs a representation of a non-tuple/list, non-node that's + contained within an AST, including strings. + """ + lines = pprint.pformat( + node, width=max(max_width - len(cur_indent), 1) + ).splitlines(True) + result.append(lines[0]) + result.extend([cur_indent + line for line in lines[1:]]) + return len(lines) != 1 + + # pylint: disable=unused-variable; doesn't understand singledispatch + @_repr_tree.register(tuple) + @_repr_tree.register(list) + def _repr_seq(node, result, done, cur_indent="", depth=1): + """Outputs a representation of a sequence that's contained within an AST.""" + cur_indent += indent + result.append("[") + if not node: + broken = False + elif len(node) == 1: + broken = _repr_tree(node[0], result, done, cur_indent, depth) + elif len(node) == 2: + broken = _repr_tree(node[0], result, done, cur_indent, depth) + if not broken: + result.append(", ") + else: + result.append(",\n") + result.append(cur_indent) + broken = _repr_tree(node[1], result, done, cur_indent, depth) or broken + else: + result.append("\n") + result.append(cur_indent) + for child in node[:-1]: + _repr_tree(child, result, done, cur_indent, depth) + result.append(",\n") + result.append(cur_indent) + _repr_tree(node[-1], result, done, cur_indent, depth) + broken = True + result.append("]") + return broken + + # pylint: disable=unused-variable; doesn't understand singledispatch + @_repr_tree.register(NodeNG) + def _repr_node(node, result, done, cur_indent="", depth=1): + """Outputs a strings representation of an astroid node.""" + if node in done: + result.append( + indent + + " max_depth: + result.append("...") + return False + depth += 1 + cur_indent += indent + if ids: + result.append("%s<0x%x>(\n" % (type(node).__name__, id(node))) + else: + result.append("%s(" % type(node).__name__) + fields = [] + if include_linenos: + fields.extend(("lineno", "col_offset")) + fields.extend(node._other_fields) + fields.extend(node._astroid_fields) + if ast_state: + fields.extend(node._other_other_fields) + if not fields: + broken = False + elif len(fields) == 1: + result.append("%s=" % fields[0]) + broken = _repr_tree( + getattr(node, fields[0]), result, done, cur_indent, depth + ) + else: + result.append("\n") + result.append(cur_indent) + for field in fields[:-1]: + result.append("%s=" % field) + _repr_tree(getattr(node, field), result, done, cur_indent, depth) + result.append(",\n") + result.append(cur_indent) + result.append("%s=" % fields[-1]) + _repr_tree(getattr(node, fields[-1]), result, done, cur_indent, depth) + broken = True + result.append(")") + return broken + + result = [] + _repr_tree(self, result, set()) + return "".join(result) + + def bool_value(self): + """Determine the boolean value of this node. + + The boolean value of a node can have three + possible values: + + * False: For instance, empty data structures, + False, empty strings, instances which return + explicitly False from the __nonzero__ / __bool__ + method. + * True: Most of constructs are True by default: + classes, functions, modules etc + * Uninferable: The inference engine is uncertain of the + node's value. + + :returns: The boolean value of this node. + :rtype: bool or Uninferable + """ + return util.Uninferable + + def op_precedence(self): + # Look up by class name or default to highest precedence + return OP_PRECEDENCE.get(self.__class__.__name__, len(OP_PRECEDENCE)) + + def op_left_associative(self): + # Everything is left associative except `**` and IfExp + return True + + +class Statement(NodeNG): + """Statement node adding a few attributes""" + + is_statement = True + """Whether this node indicates a statement. + + :type: bool + """ + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + stmts = self.parent.child_sequence(self) + index = stmts.index(self) + try: + return stmts[index + 1] + except IndexError: + pass + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + stmts = self.parent.child_sequence(self) + index = stmts.index(self) + if index >= 1: + return stmts[index - 1] + return None + + +class _BaseContainer( + mixins.ParentAssignTypeMixin, NodeNG, bases.Instance, metaclass=abc.ABCMeta +): + """Base class for Set, FrozenSet, Tuple and List.""" + + _astroid_fields = ("elts",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.elts = [] + """The elements in the node. + + :type: list(NodeNG) + """ + + super(_BaseContainer, self).__init__(lineno, col_offset, parent) + + def postinit(self, elts): + """Do some setup after initialisation. + + :param elts: The list of elements the that node contains. + :type elts: list(NodeNG) + """ + self.elts = elts + + @classmethod + def from_constants(cls, elts=None): + """Create a node of this type from the given list of elements. + + :param elts: The list of elements that the node should contain. + :type elts: list(NodeNG) + + :returns: A new node containing the given elements. + :rtype: NodeNG + """ + node = cls() + if elts is None: + node.elts = [] + else: + node.elts = [const_factory(e) for e in elts] + return node + + def itered(self): + """An iterator over the elements this node contains. + + :returns: The contents of this node. + :rtype: iterable(NodeNG) + """ + return self.elts + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool or Uninferable + """ + return bool(self.elts) + + @abc.abstractmethod + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + + def get_children(self): + yield from self.elts + + +class LookupMixIn: + """Mixin to look up a name in the right scope.""" + + @lru_cache(maxsize=None) + def lookup(self, name): + """Lookup where the given variable is assigned. + + The lookup starts from self's scope. If self is not a frame itself + and the name is found in the inner frame locals, statements will be + filtered to remove ignorable statements according to self's location. + + :param name: The name of the variable to find assignments for. + :type name: str + + :returns: The scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + return self.scope().scope_lookup(self, name) + + def ilookup(self, name): + """Lookup the inferred values of the given variable. + + :param name: The variable name to find values for. + :type name: str + + :returns: The inferred values of the statements returned from + :meth:`lookup`. + :rtype: iterable + """ + frame, stmts = self.lookup(name) + context = contextmod.InferenceContext() + return bases._infer_stmts(stmts, context, frame) + + def _filter_stmts(self, stmts, frame, offset): + """Filter the given list of statements to remove ignorable statements. + + If self is not a frame itself and the name is found in the inner + frame locals, statements will be filtered to remove ignorable + statements according to self's location. + + :param stmts: The statements to filter. + :type stmts: list(NodeNG) + + :param frame: The frame that all of the given statements belong to. + :type frame: NodeNG + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: The filtered statements. + :rtype: list(NodeNG) + """ + # if offset == -1, my actual frame is not the inner frame but its parent + # + # class A(B): pass + # + # we need this to resolve B correctly + if offset == -1: + myframe = self.frame().parent.frame() + else: + myframe = self.frame() + # If the frame of this node is the same as the statement + # of this node, then the node is part of a class or + # a function definition and the frame of this node should be the + # the upper frame, not the frame of the definition. + # For more information why this is important, + # see Pylint issue #295. + # For example, for 'b', the statement is the same + # as the frame / scope: + # + # def test(b=1): + # ... + + if self.statement() is myframe and myframe.parent: + myframe = myframe.parent.frame() + mystmt = self.statement() + # line filtering if we are in the same frame + # + # take care node may be missing lineno information (this is the case for + # nodes inserted for living objects) + if myframe is frame and mystmt.fromlineno is not None: + assert mystmt.fromlineno is not None, mystmt + mylineno = mystmt.fromlineno + offset + else: + # disabling lineno filtering + mylineno = 0 + _stmts = [] + _stmt_parents = [] + for node in stmts: + stmt = node.statement() + # line filtering is on and we have reached our location, break + if stmt.fromlineno > mylineno > 0: + break + # Ignore decorators with the same name as the + # decorated function + # Fixes issue #375 + if mystmt is stmt and is_from_decorator(self): + continue + assert hasattr(node, "assign_type"), ( + node, + node.scope(), + node.scope().locals, + ) + assign_type = node.assign_type() + if node.has_base(self): + break + + _stmts, done = assign_type._get_filtered_stmts(self, node, _stmts, mystmt) + if done: + break + + optional_assign = assign_type.optional_assign + if optional_assign and assign_type.parent_of(self): + # we are inside a loop, loop var assignment is hiding previous + # assignment + _stmts = [node] + _stmt_parents = [stmt.parent] + continue + + # XXX comment various branches below!!! + try: + pindex = _stmt_parents.index(stmt.parent) + except ValueError: + pass + else: + # we got a parent index, this means the currently visited node + # is at the same block level as a previously visited node + if _stmts[pindex].assign_type().parent_of(assign_type): + # both statements are not at the same block level + continue + # if currently visited node is following previously considered + # assignment and both are not exclusive, we can drop the + # previous one. For instance in the following code :: + # + # if a: + # x = 1 + # else: + # x = 2 + # print x + # + # we can't remove neither x = 1 nor x = 2 when looking for 'x' + # of 'print x'; while in the following :: + # + # x = 1 + # x = 2 + # print x + # + # we can remove x = 1 when we see x = 2 + # + # moreover, on loop assignment types, assignment won't + # necessarily be done if the loop has no iteration, so we don't + # want to clear previous assignments if any (hence the test on + # optional_assign) + if not (optional_assign or are_exclusive(_stmts[pindex], node)): + del _stmt_parents[pindex] + del _stmts[pindex] + if isinstance(node, AssignName): + if not optional_assign and stmt.parent is mystmt.parent: + _stmts = [] + _stmt_parents = [] + elif isinstance(node, DelName): + _stmts = [] + _stmt_parents = [] + continue + if not are_exclusive(self, node): + _stmts.append(node) + _stmt_parents.append(stmt.parent) + return _stmts + + +# Name classes + + +class AssignName( + mixins.NoChildrenMixin, LookupMixIn, mixins.ParentAssignTypeMixin, NodeNG +): + """Variation of :class:`ast.Assign` representing assignment to a name. + + An :class:`AssignName` is the name of something that is assigned to. + This includes variables defined in a function signature or in a loop. + + >>> node = astroid.extract_node('variable = range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'variable' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that is assigned to. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that is assigned to. + + :type: str or None + """ + + super(AssignName, self).__init__(lineno, col_offset, parent) + + +class DelName( + mixins.NoChildrenMixin, LookupMixIn, mixins.ParentAssignTypeMixin, NodeNG +): + """Variation of :class:`ast.Delete` representing deletion of a name. + + A :class:`DelName` is the name of something that is deleted. + + >>> node = astroid.extract_node("del variable #@") + >>> list(node.get_children()) + [] + >>> list(node.get_children())[0].as_string() + 'variable' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that is being deleted. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that is being deleted. + + :type: str or None + """ + + super(DelName, self).__init__(lineno, col_offset, parent) + + +class Name(mixins.NoChildrenMixin, LookupMixIn, NodeNG): + """Class representing an :class:`ast.Name` node. + + A :class:`Name` node is something that is named, but not covered by + :class:`AssignName` or :class:`DelName`. + + >>> node = astroid.extract_node('range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'range' + """ + + _other_fields = ("name",) + + def __init__(self, name=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name that this node refers to. + :type name: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name that this node refers to. + + :type: str or None + """ + + super(Name, self).__init__(lineno, col_offset, parent) + + def _get_name_nodes(self): + yield self + + for child_node in self.get_children(): + yield from child_node._get_name_nodes() + + +class Arguments(mixins.AssignTypeMixin, NodeNG): + """Class representing an :class:`ast.arguments` node. + + An :class:`Arguments` node represents that arguments in a + function definition. + + >>> node = astroid.extract_node('def foo(bar): pass') + >>> node + + >>> node.args + + """ + + # Python 3.4+ uses a different approach regarding annotations, + # each argument is a new class, _ast.arg, which exposes an + # 'annotation' attribute. In astroid though, arguments are exposed + # as is in the Arguments node and the only way to expose annotations + # is by using something similar with Python 3.3: + # - we expose 'varargannotation' and 'kwargannotation' of annotations + # of varargs and kwargs. + # - we expose 'annotation', a list with annotations for + # for each normal argument. If an argument doesn't have an + # annotation, its value will be None. + + _astroid_fields = ( + "args", + "defaults", + "kwonlyargs", + "kw_defaults", + "annotations", + "varargannotation", + "kwargannotation", + "kwonlyargs_annotations", + ) + varargannotation = None + """The type annotation for the variable length arguments. + + :type: NodeNG + """ + kwargannotation = None + """The type annotation for the variable length keyword arguments. + + :type: NodeNG + """ + + _other_fields = ("vararg", "kwarg") + + def __init__(self, vararg=None, kwarg=None, parent=None): + """ + :param vararg: The name of the variable length arguments. + :type vararg: str or None + + :param kwarg: The name of the variable length keyword arguments. + :type kwarg: str or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + super(Arguments, self).__init__(parent=parent) + self.vararg = vararg + """The name of the variable length arguments. + + :type: str or None + """ + + self.kwarg = kwarg + """The name of the variable length keyword arguments. + + :type: str or None + """ + + self.args = [] + """The names of the required arguments. + + :type: list(AssignName) + """ + + self.defaults = [] + """The default values for arguments that can be passed positionally. + + :type: list(NodeNG) + """ + + self.kwonlyargs = [] + """The keyword arguments that cannot be passed positionally. + + :type: list(AssignName) + """ + + self.kw_defaults = [] + """The default values for keyword arguments that cannot be passed positionally. + + :type: list(NodeNG) + """ + + self.annotations = [] + """The type annotations of arguments that can be passed positionally. + + :type: list(NodeNG) + """ + + self.kwonlyargs_annotations = [] + """The type annotations of arguments that cannot be passed positionally. + + :type: list(NodeNG) + """ + + def postinit( + self, + args, + defaults, + kwonlyargs, + kw_defaults, + annotations, + kwonlyargs_annotations=None, + varargannotation=None, + kwargannotation=None, + ): + """Do some setup after initialisation. + + :param args: The names of the required arguments. + :type args: list(AssignName) + + :param defaults: The default values for arguments that can be passed + positionally. + :type defaults: list(NodeNG) + + :param kwonlyargs: The keyword arguments that cannot be passed + positionally. + :type kwonlyargs: list(AssignName) + + :param kw_defaults: The default values for keyword arguments that + cannot be passed positionally. + :type kw_defaults: list(NodeNG) + + :param annotations: The type annotations of arguments that can be + passed positionally. + :type annotations: list(NodeNG) + + :param kwonlyargs_annotations: The type annotations of arguments that + cannot be passed positionally. This should always be passed in + Python 3. + :type kwonlyargs_annotations: list(NodeNG) + + :param varargannotation: The type annotation for the variable length + arguments. + :type varargannotation: NodeNG + + :param kwargannotation: The type annotation for the variable length + keyword arguments. + :type kwargannotation: NodeNG + """ + self.args = args + self.defaults = defaults + self.kwonlyargs = kwonlyargs + self.kw_defaults = kw_defaults + self.annotations = annotations + self.kwonlyargs_annotations = kwonlyargs_annotations + self.varargannotation = varargannotation + self.kwargannotation = kwargannotation + + def _infer_name(self, frame, name): + if self.parent is frame: + return name + return None + + @decorators.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + lineno = super(Arguments, self).fromlineno + return max(lineno, self.parent.fromlineno or 0) + + def format_args(self): + """Get the arguments formatted as string. + + :returns: The formatted arguments. + :rtype: str + """ + result = [] + if self.args: + result.append( + _format_args( + self.args, self.defaults, getattr(self, "annotations", None) + ) + ) + if self.vararg: + result.append("*%s" % self.vararg) + if self.kwonlyargs: + if not self.vararg: + result.append("*") + result.append( + _format_args( + self.kwonlyargs, self.kw_defaults, self.kwonlyargs_annotations + ) + ) + if self.kwarg: + result.append("**%s" % self.kwarg) + return ", ".join(result) + + def default_value(self, argname): + """Get the default value for an argument. + + :param argname: The name of the argument to get the default value for. + :type argname: str + + :raises NoDefault: If there is no default value defined for the + given argument. + """ + i = _find_arg(argname, self.args)[0] + if i is not None: + idx = i - (len(self.args) - len(self.defaults)) + if idx >= 0: + return self.defaults[idx] + i = _find_arg(argname, self.kwonlyargs)[0] + if i is not None and self.kw_defaults[i] is not None: + return self.kw_defaults[i] + raise exceptions.NoDefault(func=self.parent, name=argname) + + def is_argument(self, name): + """Check if the given name is defined in the arguments. + + :param name: The name to check for. + :type name: str + + :returns: True if the given name is defined in the arguments, + False otherwise. + :rtype: bool + """ + if name == self.vararg: + return True + if name == self.kwarg: + return True + return ( + self.find_argname(name, True)[1] is not None + or self.kwonlyargs + and _find_arg(name, self.kwonlyargs, True)[1] is not None + ) + + def find_argname(self, argname, rec=False): + """Get the index and :class:`AssignName` node for given name. + + :param argname: The name of the argument to search for. + :type argname: str + + :param rec: Whether or not to include arguments in unpacked tuples + in the search. + :type rec: bool + + :returns: The index and node for the argument. + :rtype: tuple(str or None, AssignName or None) + """ + if self.args: # self.args may be None in some cases (builtin function) + return _find_arg(argname, self.args, rec) + return None, None + + def get_children(self): + yield from self.args or () + + yield from self.defaults + yield from self.kwonlyargs + + for elt in self.kw_defaults: + if elt is not None: + yield elt + + for elt in self.annotations: + if elt is not None: + yield elt + + if self.varargannotation is not None: + yield self.varargannotation + + if self.kwargannotation is not None: + yield self.kwargannotation + + for elt in self.kwonlyargs_annotations: + if elt is not None: + yield elt + + +def _find_arg(argname, args, rec=False): + for i, arg in enumerate(args): + if isinstance(arg, Tuple): + if rec: + found = _find_arg(argname, arg.elts) + if found[0] is not None: + return found + elif arg.name == argname: + return i, arg + return None, None + + +def _format_args(args, defaults=None, annotations=None): + values = [] + if args is None: + return "" + if annotations is None: + annotations = [] + if defaults is not None: + default_offset = len(args) - len(defaults) + packed = itertools.zip_longest(args, annotations) + for i, (arg, annotation) in enumerate(packed): + if isinstance(arg, Tuple): + values.append("(%s)" % _format_args(arg.elts)) + else: + argname = arg.name + if annotation is not None: + argname += ":" + annotation.as_string() + values.append(argname) + + if defaults is not None and i >= default_offset: + if defaults[i - default_offset] is not None: + values[-1] += "=" + defaults[i - default_offset].as_string() + return ", ".join(values) + + +class AssignAttr(mixins.ParentAssignTypeMixin, NodeNG): + """Variation of :class:`ast.Assign` representing assignment to an attribute. + + >>> node = astroid.extract_node('self.attribute = range(10)') + >>> node + + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[0].as_string() + 'self.attribute' + """ + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """What has the attribute that is being assigned to. + + :type: NodeNG or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute being assigned to. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute being assigned to. + + :type: str or None + """ + + super(AssignAttr, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: What has the attribute that is being assigned to. + :type expr: NodeNG or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Assert(Statement): + """Class representing an :class:`ast.Assert` node. + + An :class:`Assert` node represents an assert statement. + + >>> node = astroid.extract_node('assert len(things) == 10, "Not enough things"') + >>> node + + """ + + _astroid_fields = ("test", "fail") + test = None + """The test that passes or fails the assertion. + + :type: NodeNG or None + """ + fail = None + """The message shown when the assertion fails. + + :type: NodeNG or None + """ + + def postinit(self, test=None, fail=None): + """Do some setup after initialisation. + + :param test: The test that passes or fails the assertion. + :type test: NodeNG or None + + :param fail: The message shown when the assertion fails. + :type fail: NodeNG or None + """ + self.fail = fail + self.test = test + + def get_children(self): + yield self.test + + if self.fail is not None: + yield self.fail + + +class Assign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.Assign` node. + + An :class:`Assign` is a statement where something is explicitly + asssigned to. + + >>> node = astroid.extract_node('variable = range(10)') + >>> node + + """ + + _astroid_fields = ("targets", "value") + _other_other_fields = ("type_annotation",) + targets = None + """What is being assigned to. + + :type: list(NodeNG) or None + """ + value = None + """The value being assigned to the variables. + + :type: NodeNG or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + def postinit(self, targets=None, value=None, type_annotation=None): + """Do some setup after initialisation. + + :param targets: What is being assigned to. + :type targets: list(NodeNG) or None + + :param value: The value being assigned to the variables. + :type: NodeNG or None + """ + self.targets = targets + self.value = value + self.type_annotation = type_annotation + + def get_children(self): + yield from self.targets + + yield self.value + + @decorators.cached + def _get_assign_nodes(self): + return [self] + list(self.value._get_assign_nodes()) + + def _get_yield_nodes_skip_lambdas(self): + yield from self.value._get_yield_nodes_skip_lambdas() + + +class AnnAssign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.AnnAssign` node. + + An :class:`AnnAssign` is an assignment with a type annotation. + + >>> node = astroid.extract_node('variable: List[int] = range(10)') + >>> node + + """ + + _astroid_fields = ("target", "annotation", "value") + _other_fields = ("simple",) + target = None + """What is being assigned to. + + :type: NodeNG or None + """ + annotation = None + """The type annotation of what is being assigned to. + + :type: NodeNG + """ + value = None + """The value being assigned to the variables. + + :type: NodeNG or None + """ + simple = None + """Whether :attr:`target` is a pure name or a complex statement. + + :type: int + """ + + def postinit(self, target, annotation, simple, value=None): + """Do some setup after initialisation. + + :param target: What is being assigned to. + :type target: NodeNG + + :param annotation: The type annotation of what is being assigned to. + :type: NodeNG + + :param simple: Whether :attr:`target` is a pure name + or a complex statement. + :type simple: int + + :param value: The value being assigned to the variables. + :type: NodeNG or None + """ + self.target = target + self.annotation = annotation + self.value = value + self.simple = simple + + def get_children(self): + yield self.target + yield self.annotation + + if self.value is not None: + yield self.value + + +class AugAssign(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.AugAssign` node. + + An :class:`AugAssign` is an assignment paired with an operator. + + >>> node = astroid.extract_node('variable += 1') + >>> node + + """ + + _astroid_fields = ("target", "value") + _other_fields = ("op",) + target = None + """What is being assigned to. + + :type: NodeNG or None + """ + value = None + """The value being assigned to the variable. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator that is being combined with the assignment. + This includes the equals sign. + :type op: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator that is being combined with the assignment. + + This includes the equals sign. + + :type: str or None + """ + + super(AugAssign, self).__init__(lineno, col_offset, parent) + + def postinit(self, target=None, value=None): + """Do some setup after initialisation. + + :param target: What is being assigned to. + :type target: NodeNG or None + + :param value: The value being assigned to the variable. + :type: NodeNG or None + """ + self.target = target + self.value = value + + # This is set by inference.py + def _infer_augassign(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage` , + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_augassign(context=context) + return [ + result + for result in results + if isinstance(result, util.BadBinaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.target + yield self.value + + +class Repr(NodeNG): + """Class representing an :class:`ast.Repr` node. + + A :class:`Repr` node represents the backtick syntax, + which is a deprecated alias for :func:`repr` removed in Python 3. + + >>> node = astroid.extract_node('`variable`') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """What is having :func:`repr` called on it. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What is having :func:`repr` called on it. + :type value: NodeNG or None + """ + self.value = value + + +class BinOp(NodeNG): + """Class representing an :class:`ast.BinOp` node. + + A :class:`BinOp` node is an application of a binary operator. + + >>> node = astroid.extract_node('a + b') + >>> node + + """ + + _astroid_fields = ("left", "right") + _other_fields = ("op",) + left = None + """What is being applied to the operator on the left side. + + :type: NodeNG or None + """ + right = None + """What is being applied to the operator on the right side. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(BinOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, left=None, right=None): + """Do some setup after initialisation. + + :param left: What is being applied to the operator on the left side. + :type left: NodeNG or None + + :param right: What is being applied to the operator on the right side. + :type right: NodeNG or None + """ + self.left = left + self.right = right + + # This is set by inference.py + def _infer_binop(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage`, + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_binop(context=context) + return [ + result + for result in results + if isinstance(result, util.BadBinaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.left + yield self.right + + def op_precedence(self): + return OP_PRECEDENCE[self.op] + + def op_left_associative(self): + # 2**3**4 == 2**(3**4) + return self.op != "**" + + +class BoolOp(NodeNG): + """Class representing an :class:`ast.BoolOp` node. + + A :class:`BoolOp` is an application of a boolean operator. + + >>> node = astroid.extract_node('a and b') + >>> node + + """ + + _astroid_fields = ("values",) + _other_fields = ("op",) + values = None + """The values being applied to the operator. + + :type: list(NodeNG) or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(BoolOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, values=None): + """Do some setup after initialisation. + + :param values: The values being applied to the operator. + :type values: list(NodeNG) or None + """ + self.values = values + + def get_children(self): + yield from self.values + + def op_precedence(self): + return OP_PRECEDENCE[self.op] + + +class Break(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Break` node. + + >>> node = astroid.extract_node('break') + >>> node + + """ + + +class Call(NodeNG): + """Class representing an :class:`ast.Call` node. + + A :class:`Call` node is a call to a function, method, etc. + + >>> node = astroid.extract_node('function()') + >>> node + + """ + + _astroid_fields = ("func", "args", "keywords") + func = None + """What is being called. + + :type: NodeNG or None + """ + args = None + """The positional arguments being given to the call. + + :type: list(NodeNG) or None + """ + keywords = None + """The keyword arguments being given to the call. + + :type: list(NodeNG) or None + """ + + def postinit(self, func=None, args=None, keywords=None): + """Do some setup after initialisation. + + :param func: What is being called. + :type func: NodeNG or None + + :param args: The positional arguments being given to the call. + :type args: list(NodeNG) or None + + :param keywords: The keyword arguments being given to the call. + :type keywords: list(NodeNG) or None + """ + self.func = func + self.args = args + self.keywords = keywords + + @property + def starargs(self): + """The positional arguments that unpack something. + + :type: list(Starred) + """ + args = self.args or [] + return [arg for arg in args if isinstance(arg, Starred)] + + @property + def kwargs(self): + """The keyword arguments that unpack something. + + :type: list(Keyword) + """ + keywords = self.keywords or [] + return [keyword for keyword in keywords if keyword.arg is None] + + def get_children(self): + yield self.func + + yield from self.args + + yield from self.keywords or () + + +class Compare(NodeNG): + """Class representing an :class:`ast.Compare` node. + + A :class:`Compare` node indicates a comparison. + + >>> node = astroid.extract_node('a <= b <= c') + >>> node + + >>> node.ops + [('<=', ), ('<=', )] + """ + + _astroid_fields = ("left", "ops") + left = None + """The value at the left being applied to a comparison operator. + + :type: NodeNG or None + """ + ops = None + """The remainder of the operators and their relevant right hand value. + + :type: list(tuple(str, NodeNG)) or None + """ + + def postinit(self, left=None, ops=None): + """Do some setup after initialisation. + + :param left: The value at the left being applied to a comparison + operator. + :type left: NodeNG or None + + :param ops: The remainder of the operators + and their relevant right hand value. + :type ops: list(tuple(str, NodeNG)) or None + """ + self.left = left + self.ops = ops + + def get_children(self): + """Get the child nodes below this node. + + Overridden to handle the tuple fields and skip returning the operator + strings. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + yield self.left + for _, comparator in self.ops: + yield comparator # we don't want the 'op' + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child. + :rtype: NodeNG + """ + # XXX maybe if self.ops: + return self.ops[-1][1] + # return self.left + + +class Comprehension(NodeNG): + """Class representing an :class:`ast.comprehension` node. + + A :class:`Comprehension` indicates the loop inside any type of + comprehension including generator expressions. + + >>> node = astroid.extract_node('[x for x in some_values]') + >>> list(node.get_children()) + [, ] + >>> list(node.get_children())[1].as_string() + 'for x in some_values' + """ + + _astroid_fields = ("target", "iter", "ifs") + _other_fields = ("is_async",) + target = None + """What is assigned to by the comprehension. + + :type: NodeNG or None + """ + iter = None + """What is iterated over by the comprehension. + + :type: NodeNG or None + """ + ifs = None + """The contents of any if statements that filter the comprehension. + + :type: list(NodeNG) or None + """ + is_async = None + """Whether this is an asynchronous comprehension or not. + + :type: bool or None + """ + + def __init__(self, parent=None): + """ + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + super(Comprehension, self).__init__() + self.parent = parent + + # pylint: disable=redefined-builtin; same name as builtin ast module. + def postinit(self, target=None, iter=None, ifs=None, is_async=None): + """Do some setup after initialisation. + + :param target: What is assigned to by the comprehension. + :type target: NodeNG or None + + :param iter: What is iterated over by the comprehension. + :type iter: NodeNG or None + + :param ifs: The contents of any if statements that filter + the comprehension. + :type ifs: list(NodeNG) or None + + :param is_async: Whether this is an asynchronous comprehension or not. + :type: bool or None + """ + self.target = target + self.iter = iter + self.ifs = ifs + self.is_async = is_async + + optional_assign = True + """Whether this node optionally assigns a variable. + + :type: bool + """ + + def assign_type(self): + """The type of assignment that this node performs. + + :returns: The assignment type. + :rtype: NodeNG + """ + return self + + def _get_filtered_stmts(self, lookup_node, node, stmts, mystmt): + """method used in filter_stmts""" + if self is mystmt: + if isinstance(lookup_node, (Const, Name)): + return [lookup_node], True + + elif self.statement() is mystmt: + # original node's statement is the assignment, only keeps + # current node (gen exp, list comp) + + return [node], True + + return stmts, False + + def get_children(self): + yield self.target + yield self.iter + + yield from self.ifs + + +class Const(mixins.NoChildrenMixin, NodeNG, bases.Instance): + """Class representing any constant including num, str, bool, None, bytes. + + >>> node = astroid.extract_node('(5, "This is a string.", True, None, b"bytes")') + >>> node + + >>> list(node.get_children()) + [, + , + , + , + ] + """ + + _other_fields = ("value",) + + def __init__(self, value, lineno=None, col_offset=None, parent=None): + """ + :param value: The value that the constant represents. + :type value: object + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.value = value + """The value that the constant represents. + + :type: object + """ + + super(Const, self).__init__(lineno, col_offset, parent) + + def __getattr__(self, name): + # This is needed because of Proxy's __getattr__ method. + # Calling object.__new__ on this class without calling + # __init__ would result in an infinite loop otherwise + # since __getattr__ is called when an attribute doesn't + # exist and self._proxied indirectly calls self.value + # and Proxy __getattr__ calls self.value + if name == "value": + raise AttributeError + return super().__getattr__(name) + + def getitem(self, index, context=None): + """Get an item from this node if subscriptable. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + + :raises AstroidTypeError: When the given index cannot be used as a + subscript index, or if this node is not subscriptable. + """ + if isinstance(index, Const): + index_value = index.value + elif isinstance(index, Slice): + index_value = _infer_slice(index, context=context) + + else: + raise exceptions.AstroidTypeError( + "Could not use type {} as subscript index".format(type(index)) + ) + + try: + if isinstance(self.value, (str, bytes)): + return Const(self.value[index_value]) + except IndexError as exc: + raise exceptions.AstroidIndexError( + message="Index {index!r} out of range", + node=self, + index=index, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.AstroidTypeError( + message="Type error {error!r}", node=self, index=index, context=context + ) from exc + + raise exceptions.AstroidTypeError("%r (value=%s)" % (self, self.value)) + + def has_dynamic_getattr(self): + """Check if the node has a custom __getattr__ or __getattribute__. + + :returns: True if the class has a custom + __getattr__ or __getattribute__, False otherwise. + For a :class:`Const` this is always ``False``. + :rtype: bool + """ + return False + + def itered(self): + """An iterator over the elements this node contains. + + :returns: The contents of this node. + :rtype: iterable(str) + + :raises TypeError: If this node does not represent something that is iterable. + """ + if isinstance(self.value, str): + return self.value + raise TypeError() + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return self._proxied.qname() + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool + """ + return bool(self.value) + + +class Continue(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Continue` node. + + >>> node = astroid.extract_node('continue') + >>> node + + """ + + +class Decorators(NodeNG): + """A node representing a list of decorators. + + A :class:`Decorators` is the decorators that are applied to + a method or function. + + >>> node = astroid.extract_node(''' + @property + def my_property(self): + return 3 + ''') + >>> node + + >>> list(node.get_children())[0] + + """ + + _astroid_fields = ("nodes",) + nodes = None + """The decorators that this node contains. + + :type: list(Name or Call) or None + """ + + def postinit(self, nodes): + """Do some setup after initialisation. + + :param nodes: The decorators that this node contains. + :type nodes: list(Name or Call) + """ + self.nodes = nodes + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + # skip the function node to go directly to the upper level scope + return self.parent.parent.scope() + + def get_children(self): + yield from self.nodes + + +class DelAttr(mixins.ParentAssignTypeMixin, NodeNG): + """Variation of :class:`ast.Delete` representing deletion of an attribute. + + >>> node = astroid.extract_node('del self.attr') + >>> node + + >>> list(node.get_children())[0] + + """ + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """The name that this node represents. + + :type: Name or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute that is being deleted. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute that is being deleted. + + :type: str or None + """ + + super(DelAttr, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: The name that this node represents. + :type expr: Name or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Delete(mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.Delete` node. + + A :class:`Delete` is a ``del`` statement this is deleting something. + + >>> node = astroid.extract_node('del self.attr') + >>> node + + """ + + _astroid_fields = ("targets",) + targets = None + """What is being deleted. + + :type: list(NodeNG) or None + """ + + def postinit(self, targets=None): + """Do some setup after initialisation. + + :param targets: What is being deleted. + :type targets: list(NodeNG) or None + """ + self.targets = targets + + def get_children(self): + yield from self.targets + + +class Dict(NodeNG, bases.Instance): + """Class representing an :class:`ast.Dict` node. + + A :class:`Dict` is a dictionary that is created with ``{}`` syntax. + + >>> node = astroid.extract_node('{1: "1"}') + >>> node + + """ + + _astroid_fields = ("items",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.items = [] + """The key-value pairs contained in the dictionary. + + :type: list(tuple(NodeNG, NodeNG)) + """ + + super(Dict, self).__init__(lineno, col_offset, parent) + + def postinit(self, items): + """Do some setup after initialisation. + + :param items: The key-value pairs contained in the dictionary. + :type items: list(tuple(NodeNG, NodeNG)) + """ + self.items = items + + @classmethod + def from_constants(cls, items=None): + """Create a :class:`Dict` of constants from a live dictionary. + + :param items: The items to store in the node. + :type items: dict + + :returns: The created dictionary node. + :rtype: Dict + """ + node = cls() + if items is None: + node.items = [] + else: + node.items = [ + (const_factory(k), const_factory(v)) for k, v in items.items() + ] + return node + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.dict" % BUILTINS + + def get_children(self): + """Get the key and value nodes below this node. + + Children are returned in the order that they are defined in the source + code, key first then the value. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for key, value in self.items: + yield key + yield value + + def last_child(self): + """An optimized version of list(get_children())[-1] + + :returns: The last child, or None if no children exist. + :rtype: NodeNG or None + """ + if self.items: + return self.items[-1][1] + return None + + def itered(self): + """An iterator over the keys this node contains. + + :returns: The keys of this node. + :rtype: iterable(NodeNG) + """ + return [key for (key, _) in self.items] + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + + :raises AstroidTypeError: When the given index cannot be used as a + subscript index, or if this node is not subscriptable. + :raises AstroidIndexError: If the given index does not exist in the + dictionary. + """ + for key, value in self.items: + # TODO(cpopa): no support for overriding yet, {1:2, **{1: 3}}. + if isinstance(key, DictUnpack): + try: + return value.getitem(index, context) + except (exceptions.AstroidTypeError, exceptions.AstroidIndexError): + continue + for inferredkey in key.infer(context): + if inferredkey is util.Uninferable: + continue + if isinstance(inferredkey, Const) and isinstance(index, Const): + if inferredkey.value == index.value: + return value + + raise exceptions.AstroidIndexError(index) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + :rtype: bool + """ + return bool(self.items) + + +class Expr(Statement): + """Class representing an :class:`ast.Expr` node. + + An :class:`Expr` is any expression that does not have its value used or + stored. + + >>> node = astroid.extract_node('method()') + >>> node + + >>> node.parent + + """ + + _astroid_fields = ("value",) + value = None + """What the expression does. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What the expression does. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + def _get_yield_nodes_skip_lambdas(self): + if not self.value.is_lambda: + yield from self.value._get_yield_nodes_skip_lambdas() + + +class Ellipsis(mixins.NoChildrenMixin, NodeNG): # pylint: disable=redefined-builtin + """Class representing an :class:`ast.Ellipsis` node. + + An :class:`Ellipsis` is the ``...`` syntax. + + >>> node = astroid.extract_node('...') + >>> node + + """ + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For an :class:`Ellipsis` this is always ``True``. + :rtype: bool + """ + return True + + +class EmptyNode(mixins.NoChildrenMixin, NodeNG): + """Holds an arbitrary object in the :attr:`LocalsDictNodeNG.locals`.""" + + object = None + + +class ExceptHandler(mixins.MultiLineBlockMixin, mixins.AssignTypeMixin, Statement): + """Class representing an :class:`ast.ExceptHandler`. node. + + An :class:`ExceptHandler` is an ``except`` block on a try-except. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + ''') + >>> node + + >>> >>> node.handlers + [] + """ + + _astroid_fields = ("type", "name", "body") + _multi_line_block_fields = ("body",) + type = None + """The types that the block handles. + + :type: Tuple or NodeNG or None + """ + name = None + """The name that the caught exception is assigned to. + + :type: AssignName or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + + def get_children(self): + if self.type is not None: + yield self.type + + if self.name is not None: + yield self.name + + yield from self.body + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, type=None, name=None, body=None): + """Do some setup after initialisation. + + :param type: The types that the block handles. + :type type: Tuple or NodeNG or None + + :param name: The name that the caught exception is assigned to. + :type name: AssignName or None + + :param body:The contents of the block. + :type body: list(NodeNG) or None + """ + self.type = type + self.name = name + self.body = body + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + if self.name: + return self.name.tolineno + if self.type: + return self.type.tolineno + return self.lineno + + def catch(self, exceptions): # pylint: disable=redefined-outer-name + """Check if this node handles any of the given exceptions. + + If ``exceptions`` is empty, this will default to ``True``. + + :param exceptions: The name of the exceptions to check for. + :type exceptions: list(str) + """ + if self.type is None or exceptions is None: + return True + for node in self.type._get_name_nodes(): + if node.name in exceptions: + return True + return False + + +class Exec(Statement): + """Class representing the ``exec`` statement. + + >>> node = astroid.extract_node('exec "True"') + >>> node + + """ + + _astroid_fields = ("expr", "globals", "locals") + expr = None + """The expression to be executed. + + :type: NodeNG or None + """ + globals = None + """The globals dictionary to execute with. + + :type: NodeNG or None + """ + locals = None + """The locals dictionary to execute with. + + :type: NodeNG or None + """ + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, expr=None, globals=None, locals=None): + """Do some setup after initialisation. + + :param expr: The expression to be executed. + :type expr: NodeNG or None + + :param globals:The globals dictionary to execute with. + :type globals: NodeNG or None + + :param locals: The locals dictionary to execute with. + :type locals: NodeNG or None + """ + self.expr = expr + self.globals = globals + self.locals = locals + + +class ExtSlice(NodeNG): + """Class representing an :class:`ast.ExtSlice` node. + + An :class:`ExtSlice` is a complex slice expression. + + >>> node = astroid.extract_node('l[1:3, 5]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("dims",) + dims = None + """The simple dimensions that form the complete slice. + + :type: list(NodeNG) or None + """ + + def postinit(self, dims=None): + """Do some setup after initialisation. + + :param dims: The simple dimensions that form the complete slice. + :type dims: list(NodeNG) or None + """ + self.dims = dims + + +class For( + mixins.MultiLineBlockMixin, + mixins.BlockRangeMixIn, + mixins.AssignTypeMixin, + Statement, +): + """Class representing an :class:`ast.For` node. + + >>> node = astroid.extract_node('for thing in things: print(thing)') + >>> node + + """ + + _astroid_fields = ("target", "iter", "body", "orelse") + _other_other_fields = ("type_annotation",) + _multi_line_block_fields = ("body", "orelse") + target = None + """What the loop assigns to. + + :type: NodeNG or None + """ + iter = None + """What the loop iterates over. + + :type: NodeNG or None + """ + body = None + """The contents of the body of the loop. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block of the loop. + + :type: list(NodeNG) or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit( + self, target=None, iter=None, body=None, orelse=None, type_annotation=None + ): + """Do some setup after initialisation. + + :param target: What the loop assigns to. + :type target: NodeNG or None + + :param iter: What the loop iterates over. + :type iter: NodeNG or None + + :param body: The contents of the body of the loop. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block of the loop. + :type orelse: list(NodeNG) or None + """ + self.target = target + self.iter = iter + self.body = body + self.orelse = orelse + self.type_annotation = type_annotation + + optional_assign = True + """Whether this node optionally assigns a variable. + + This is always ``True`` for :class:`For` nodes. + + :type: bool + """ + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.iter.tolineno + + def get_children(self): + yield self.target + yield self.iter + + yield from self.body + yield from self.orelse + + +class AsyncFor(For): + """Class representing an :class:`ast.AsyncFor` node. + + An :class:`AsyncFor` is an asynchronous :class:`For` built with + the ``async`` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + async for thing in things: + print(thing) + ''') + >>> node + + >>> node.body[0] + + """ + + +class Await(NodeNG): + """Class representing an :class:`ast.Await` node. + + An :class:`Await` is the ``await`` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + await other_func() + ''') + >>> node + + >>> node.body[0] + + >>> list(node.body[0].get_children())[0] + + """ + + _astroid_fields = ("value",) + value = None + """What to wait for. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What to wait for. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class ImportFrom(mixins.NoChildrenMixin, mixins.ImportFromMixin, Statement): + """Class representing an :class:`ast.ImportFrom` node. + + >>> node = astroid.extract_node('from my_package import my_module') + >>> node + + """ + + _other_fields = ("modname", "names", "level") + + def __init__( + self, fromname, names, level=0, lineno=None, col_offset=None, parent=None + ): + """ + :param fromname: The module that is being imported from. + :type fromname: str or None + + :param names: What is being imported from the module. + :type names: list(tuple(str, str or None)) + + :param level: The level of relative import. + :type level: int + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.modname = fromname + """The module that is being imported from. + + This is ``None`` for relative imports. + + :type: str or None + """ + + self.names = names + """What is being imported from the module. + + Each entry is a :class:`tuple` of the name being imported, + and the alias that the name is assigned to (if any). + + :type: list(tuple(str, str or None)) + """ + + self.level = level + """The level of relative import. + + Essentially this is the number of dots in the import. + This is always 0 for absolute imports. + + :type: int + """ + + super(ImportFrom, self).__init__(lineno, col_offset, parent) + + +class Attribute(NodeNG): + """Class representing an :class:`ast.Attribute` node.""" + + _astroid_fields = ("expr",) + _other_fields = ("attrname",) + expr = None + """The name that this node represents. + + :type: Name or None + """ + + def __init__(self, attrname=None, lineno=None, col_offset=None, parent=None): + """ + :param attrname: The name of the attribute. + :type attrname: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.attrname = attrname + """The name of the attribute. + + :type: str or None + """ + + super(Attribute, self).__init__(lineno, col_offset, parent) + + def postinit(self, expr=None): + """Do some setup after initialisation. + + :param expr: The name that this node represents. + :type expr: Name or None + """ + self.expr = expr + + def get_children(self): + yield self.expr + + +class Global(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Global` node. + + >>> node = astroid.extract_node('global a_global') + >>> node + + """ + + _other_fields = ("names",) + + def __init__(self, names, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being declared as global. + :type names: list(str) + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being declared as global. + + :type: list(str) + """ + + super(Global, self).__init__(lineno, col_offset, parent) + + def _infer_name(self, frame, name): + return name + + +class If(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.If` node. + + >>> node = astroid.extract_node('if condition: print(True)') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + _multi_line_block_fields = ("body", "orelse") + test = None + """The condition that the statement tests. + + :type: NodeNG or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the statement tests. + :type test: NodeNG or None + + :param body: The contents of the block. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.test.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + if lineno == self.body[0].fromlineno: + return lineno, lineno + if lineno <= self.body[-1].tolineno: + return lineno, self.body[-1].tolineno + return self._elsed_block_range(lineno, self.orelse, self.body[0].fromlineno - 1) + + def get_children(self): + yield self.test + + yield from self.body + yield from self.orelse + + def has_elif_block(self): + return len(self.orelse) == 1 and isinstance(self.orelse[0], If) + + +class IfExp(NodeNG): + """Class representing an :class:`ast.IfExp` node. + + >>> node = astroid.extract_node('value if condition else other') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + test = None + """The condition that the statement tests. + + :type: NodeNG or None + """ + body = None + """The contents of the block. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the statement tests. + :type test: NodeNG or None + + :param body: The contents of the block. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + def get_children(self): + yield self.test + yield self.body + yield self.orelse + + def op_left_associative(self): + # `1 if True else 2 if False else 3` is parsed as + # `1 if True else (2 if False else 3)` + return False + + +class Import(mixins.NoChildrenMixin, mixins.ImportFromMixin, Statement): + """Class representing an :class:`ast.Import` node. + + >>> node = astroid.extract_node('import astroid') + >>> node + + """ + + _other_fields = ("names",) + + def __init__(self, names=None, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being imported. + :type names: list(tuple(str, str or None)) or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being imported. + + Each entry is a :class:`tuple` of the name being imported, + and the alias that the name is assigned to (if any). + + :type: list(tuple(str, str or None)) or None + """ + + super(Import, self).__init__(lineno, col_offset, parent) + + +class Index(NodeNG): + """Class representing an :class:`ast.Index` node. + + An :class:`Index` is a simple subscript. + + >>> node = astroid.extract_node('things[1]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("value",) + value = None + """The value to subscript with. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value to subscript with. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class Keyword(NodeNG): + """Class representing an :class:`ast.keyword` node. + + >>> node = astroid.extract_node('function(a_kwarg=True)') + >>> node + + >>> node.keywords + [] + """ + + _astroid_fields = ("value",) + _other_fields = ("arg",) + value = None + """The value being assigned to the keyword argument. + + :type: NodeNG or None + """ + + def __init__(self, arg=None, lineno=None, col_offset=None, parent=None): + """ + :param arg: The argument being assigned to. + :type arg: Name or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.arg = arg + """The argument being assigned to. + + :type: Name or None + """ + + super(Keyword, self).__init__(lineno, col_offset, parent) + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value being assigned to the ketword argument. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class List(_BaseContainer): + """Class representing an :class:`ast.List` node. + + >>> node = astroid.extract_node('[1, 2, 3]') + >>> node + + """ + + _other_fields = ("ctx",) + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the list is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the list is assigned to or loaded from. + + :type: Context or None + """ + + super(List, self).__init__(lineno, col_offset, parent) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.list" % BUILTINS + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + """ + return _container_getitem(self, self.elts, index, context=context) + + +class Nonlocal(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Nonlocal` node. + + >>> node = astroid.extract_node(''' + def function(): + nonlocal var + ''') + >>> node + + >>> node.body[0] + + """ + + _other_fields = ("names",) + + def __init__(self, names, lineno=None, col_offset=None, parent=None): + """ + :param names: The names being declared as not local. + :type names: list(str) + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.names = names + """The names being declared as not local. + + :type: list(str) + """ + + super(Nonlocal, self).__init__(lineno, col_offset, parent) + + def _infer_name(self, frame, name): + return name + + +class Pass(mixins.NoChildrenMixin, Statement): + """Class representing an :class:`ast.Pass` node. + + >>> node = astroid.extract_node('pass') + >>> node + + """ + + +class Print(Statement): + """Class representing an :class:`ast.Print` node. + + >>> node = astroid.extract_node('print "A message"') + >>> node + + """ + + _astroid_fields = ("dest", "values") + dest = None + """Where to print to. + + :type: NodeNG or None + """ + values = None + """What to print. + + :type: list(NodeNG) or None + """ + + def __init__(self, nl=None, lineno=None, col_offset=None, parent=None): + """ + :param nl: Whether to print a new line. + :type nl: bool or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.nl = nl + """Whether to print a new line. + + :type: bool or None + """ + + super(Print, self).__init__(lineno, col_offset, parent) + + def postinit(self, dest=None, values=None): + """Do some setup after initialisation. + + :param dest: Where to print to. + :type dest: NodeNG or None + + :param values: What to print. + :type values: list(NodeNG) or None + """ + self.dest = dest + self.values = values + + +class Raise(Statement): + """Class representing an :class:`ast.Raise` node. + + >>> node = astroid.extract_node('raise RuntimeError("Something bad happened!")') + >>> node + + """ + + exc = None + """What is being raised. + + :type: NodeNG or None + """ + _astroid_fields = ("exc", "cause") + cause = None + """The exception being used to raise this one. + + :type: NodeNG or None + """ + + def postinit(self, exc=None, cause=None): + """Do some setup after initialisation. + + :param exc: What is being raised. + :type exc: NodeNG or None + + :param cause: The exception being used to raise this one. + :type cause: NodeNG or None + """ + self.exc = exc + self.cause = cause + + def raises_not_implemented(self): + """Check if this node raises a :class:`NotImplementedError`. + + :returns: True if this node raises a :class:`NotImplementedError`, + False otherwise. + :rtype: bool + """ + if not self.exc: + return False + for name in self.exc._get_name_nodes(): + if name.name == "NotImplementedError": + return True + return False + + def get_children(self): + if self.exc is not None: + yield self.exc + + if self.cause is not None: + yield self.cause + + +class Return(Statement): + """Class representing an :class:`ast.Return` node. + + >>> node = astroid.extract_node('return True') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """The value being returned. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value being returned. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + if self.value is not None: + yield self.value + + def is_tuple_return(self): + return isinstance(self.value, Tuple) + + def _get_return_nodes_skip_functions(self): + yield self + + +class Set(_BaseContainer): + """Class representing an :class:`ast.Set` node. + + >>> node = astroid.extract_node('{1, 2, 3}') + >>> node + + """ + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.set" % BUILTINS + + +class Slice(NodeNG): + """Class representing an :class:`ast.Slice` node. + + >>> node = astroid.extract_node('things[1:3]') + >>> node + + >>> node.slice + + """ + + _astroid_fields = ("lower", "upper", "step") + lower = None + """The lower index in the slice. + + :type: NodeNG or None + """ + upper = None + """The upper index in the slice. + + :type: NodeNG or None + """ + step = None + """The step to take between indexes. + + :type: NodeNG or None + """ + + def postinit(self, lower=None, upper=None, step=None): + """Do some setup after initialisation. + + :param lower: The lower index in the slice. + :value lower: NodeNG or None + + :param upper: The upper index in the slice. + :value upper: NodeNG or None + + :param step: The step to take between index. + :param step: NodeNG or None + """ + self.lower = lower + self.upper = upper + self.step = step + + def _wrap_attribute(self, attr): + """Wrap the empty attributes of the Slice in a Const node.""" + if not attr: + const = const_factory(attr) + const.parent = self + return const + return attr + + @decorators.cachedproperty + def _proxied(self): + builtins = MANAGER.astroid_cache[BUILTINS] + return builtins.getattr("slice")[0] + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.slice" % BUILTINS + + def igetattr(self, attrname, context=None): + """Infer the possible values of the given attribute on the slice. + + :param attrname: The name of the attribute to infer. + :type attrname: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG) + """ + if attrname == "start": + yield self._wrap_attribute(self.lower) + elif attrname == "stop": + yield self._wrap_attribute(self.upper) + elif attrname == "step": + yield self._wrap_attribute(self.step) + else: + yield from self.getattr(attrname, context=context) + + def getattr(self, attrname, context=None): + return self._proxied.getattr(attrname, context) + + def get_children(self): + if self.lower is not None: + yield self.lower + + if self.upper is not None: + yield self.upper + + if self.step is not None: + yield self.step + + +class Starred(mixins.ParentAssignTypeMixin, NodeNG): + """Class representing an :class:`ast.Starred` node. + + >>> node = astroid.extract_node('*args') + >>> node + + """ + + _astroid_fields = ("value",) + _other_fields = ("ctx",) + value = None + """What is being unpacked. + + :type: NodeNG or None + """ + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the list is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the starred item is assigned to or loaded from. + + :type: Context or None + """ + + super(Starred, self).__init__( + lineno=lineno, col_offset=col_offset, parent=parent + ) + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: What is being unpacked. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + yield self.value + + +class Subscript(NodeNG): + """Class representing an :class:`ast.Subscript` node. + + >>> node = astroid.extract_node('things[1:3]') + >>> node + + """ + + _astroid_fields = ("value", "slice") + _other_fields = ("ctx",) + value = None + """What is being indexed. + + :type: NodeNG or None + """ + slice = None + """The slice being used to lookup. + + :type: NodeNG or None + """ + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the subscripted item is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the subscripted item is assigned to or loaded from. + + :type: Context or None + """ + + super(Subscript, self).__init__( + lineno=lineno, col_offset=col_offset, parent=parent + ) + + # pylint: disable=redefined-builtin; had to use the same name as builtin ast module. + def postinit(self, value=None, slice=None): + """Do some setup after initialisation. + + :param value: What is being indexed. + :type value: NodeNG or None + + :param slice: The slice being used to lookup. + :type slice: NodeNG or None + """ + self.value = value + self.slice = slice + + def get_children(self): + yield self.value + yield self.slice + + +class TryExcept(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.TryExcept` node. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + ''') + >>> node + + """ + + _astroid_fields = ("body", "handlers", "orelse") + _multi_line_block_fields = ("body", "handlers", "orelse") + body = None + """The contents of the block to catch exceptions from. + + :type: list(NodeNG) or None + """ + handlers = None + """The exception handlers. + + :type: list(ExceptHandler) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, body=None, handlers=None, orelse=None): + """Do some setup after initialisation. + + :param body: The contents of the block to catch exceptions from. + :type body: list(NodeNG) or None + + :param handlers: The exception handlers. + :type handlers: list(ExceptHandler) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.body = body + self.handlers = handlers + self.orelse = orelse + + def _infer_name(self, frame, name): + return name + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + last = None + for exhandler in self.handlers: + if exhandler.type and lineno == exhandler.type.fromlineno: + return lineno, lineno + if exhandler.body[0].fromlineno <= lineno <= exhandler.body[-1].tolineno: + return lineno, exhandler.body[-1].tolineno + if last is None: + last = exhandler.body[0].fromlineno - 1 + return self._elsed_block_range(lineno, self.orelse, last) + + def get_children(self): + yield from self.body + + yield from self.handlers or () + yield from self.orelse or () + + +class TryFinally(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.TryFinally` node. + + >>> node = astroid.extract_node(''' + try: + do_something() + except Exception as error: + print("Error!") + finally: + print("Cleanup!") + ''') + >>> node + + """ + + _astroid_fields = ("body", "finalbody") + _multi_line_block_fields = ("body", "finalbody") + body = None + """The try-except that the finally is attached to. + + :type: list(TryExcept) or None + """ + finalbody = None + """The contents of the ``finally`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, body=None, finalbody=None): + """Do some setup after initialisation. + + :param body: The try-except that the finally is attached to. + :type body: list(TryExcept) or None + + :param finalbody: The contents of the ``finally`` block. + :type finalbody: list(NodeNG) or None + """ + self.body = body + self.finalbody = finalbody + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + child = self.body[0] + # py2.5 try: except: finally: + if ( + isinstance(child, TryExcept) + and child.fromlineno == self.fromlineno + and lineno > self.fromlineno + and lineno <= child.tolineno + ): + return child.block_range(lineno) + return self._elsed_block_range(lineno, self.finalbody) + + def get_children(self): + yield from self.body + yield from self.finalbody + + +class Tuple(_BaseContainer): + """Class representing an :class:`ast.Tuple` node. + + >>> node = astroid.extract_node('(1, 2, 3)') + >>> node + + """ + + _other_fields = ("ctx",) + + def __init__(self, ctx=None, lineno=None, col_offset=None, parent=None): + """ + :param ctx: Whether the tuple is assigned to or loaded from. + :type ctx: Context or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.ctx = ctx + """Whether the tuple is assigned to or loaded from. + + :type: Context or None + """ + + super(Tuple, self).__init__(lineno, col_offset, parent) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.tuple" % BUILTINS + + def getitem(self, index, context=None): + """Get an item from this node. + + :param index: The node to use as a subscript index. + :type index: Const or Slice + """ + return _container_getitem(self, self.elts, index, context=context) + + +class UnaryOp(NodeNG): + """Class representing an :class:`ast.UnaryOp` node. + + >>> node = astroid.extract_node('-5') + >>> node + + """ + + _astroid_fields = ("operand",) + _other_fields = ("op",) + operand = None + """What the unary operator is applied to. + + :type: NodeNG or None + """ + + def __init__(self, op=None, lineno=None, col_offset=None, parent=None): + """ + :param op: The operator. + :type: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.op = op + """The operator. + + :type: str or None + """ + + super(UnaryOp, self).__init__(lineno, col_offset, parent) + + def postinit(self, operand=None): + """Do some setup after initialisation. + + :param operand: What the unary operator is applied to. + :type operand: NodeNG or None + """ + self.operand = operand + + # This is set by inference.py + def _infer_unaryop(self, context=None): + raise NotImplementedError + + def type_errors(self, context=None): + """Get a list of type errors which can occur during inference. + + Each TypeError is represented by a :class:`BadBinaryOperationMessage`, + which holds the original exception. + + :returns: The list of possible type errors. + :rtype: list(BadBinaryOperationMessage) + """ + try: + results = self._infer_unaryop(context=context) + return [ + result + for result in results + if isinstance(result, util.BadUnaryOperationMessage) + ] + except exceptions.InferenceError: + return [] + + def get_children(self): + yield self.operand + + def op_precedence(self): + if self.op == "not": + return OP_PRECEDENCE[self.op] + + return super().op_precedence() + + +class While(mixins.MultiLineBlockMixin, mixins.BlockRangeMixIn, Statement): + """Class representing an :class:`ast.While` node. + + >>> node = astroid.extract_node(''' + while condition(): + print("True") + ''') + >>> node + + """ + + _astroid_fields = ("test", "body", "orelse") + _multi_line_block_fields = ("body", "orelse") + test = None + """The condition that the loop tests. + + :type: NodeNG or None + """ + body = None + """The contents of the loop. + + :type: list(NodeNG) or None + """ + orelse = None + """The contents of the ``else`` block. + + :type: list(NodeNG) or None + """ + + def postinit(self, test=None, body=None, orelse=None): + """Do some setup after initialisation. + + :param test: The condition that the loop tests. + :type test: NodeNG or None + + :param body: The contents of the loop. + :type body: list(NodeNG) or None + + :param orelse: The contents of the ``else`` block. + :type orelse: list(NodeNG) or None + """ + self.test = test + self.body = body + self.orelse = orelse + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.test.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: The line number to start the range at. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + starting at the given line number. + :rtype: tuple(int, int) + """ + return self._elsed_block_range(lineno, self.orelse) + + def get_children(self): + yield self.test + + yield from self.body + yield from self.orelse + + +class With( + mixins.MultiLineBlockMixin, + mixins.BlockRangeMixIn, + mixins.AssignTypeMixin, + Statement, +): + """Class representing an :class:`ast.With` node. + + >>> node = astroid.extract_node(''' + with open(file_path) as file_: + print(file_.read()) + ''') + >>> node + + """ + + _astroid_fields = ("items", "body") + _other_other_fields = ("type_annotation",) + _multi_line_block_fields = ("body",) + items = None + """The pairs of context managers and the names they are assigned to. + + :type: list(tuple(NodeNG, AssignName or None)) or None + """ + body = None + """The contents of the ``with`` block. + + :type: list(NodeNG) or None + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + + def postinit(self, items=None, body=None, type_annotation=None): + """Do some setup after initialisation. + + :param items: The pairs of context managers and the names + they are assigned to. + :type items: list(tuple(NodeNG, AssignName or None)) or None + + :param body: The contents of the ``with`` block. + :type body: list(NodeNG) or None + """ + self.items = items + self.body = body + self.type_annotation = type_annotation + + @decorators.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.items[-1][0].tolineno + + def get_children(self): + """Get the child nodes below this node. + + :returns: The children. + :rtype: iterable(NodeNG) + """ + for expr, var in self.items: + yield expr + if var: + yield var + yield from self.body + + +class AsyncWith(With): + """Asynchronous ``with`` built with the ``async`` keyword.""" + + +class Yield(NodeNG): + """Class representing an :class:`ast.Yield` node. + + >>> node = astroid.extract_node('yield True') + >>> node + + """ + + _astroid_fields = ("value",) + value = None + """The value to yield. + + :type: NodeNG or None + """ + + def postinit(self, value=None): + """Do some setup after initialisation. + + :param value: The value to yield. + :type value: NodeNG or None + """ + self.value = value + + def get_children(self): + if self.value is not None: + yield self.value + + def _get_yield_nodes_skip_lambdas(self): + yield self + + +class YieldFrom(Yield): + """Class representing an :class:`ast.YieldFrom` node.""" + + +class DictUnpack(mixins.NoChildrenMixin, NodeNG): + """Represents the unpacking of dicts into dicts using :pep:`448`.""" + + +class FormattedValue(NodeNG): + """Class representing an :class:`ast.FormattedValue` node. + + Represents a :pep:`498` format string. + + >>> node = astroid.extract_node('f"Format {type_}"') + >>> node + + >>> node.values + [, ] + """ + + _astroid_fields = ("value", "format_spec") + value = None + """The value to be formatted into the string. + + :type: NodeNG or None + """ + conversion = None + """The type of formatting to be applied to the value. + + .. seealso:: + :class:`ast.FormattedValue` + + :type: int or None + """ + format_spec = None + """The formatting to be applied to the value. + + .. seealso:: + :class:`ast.FormattedValue` + + :type: JoinedStr or None + """ + + def postinit(self, value, conversion=None, format_spec=None): + """Do some setup after initialisation. + + :param value: The value to be formatted into the string. + :type value: NodeNG + + :param conversion: The type of formatting to be applied to the value. + :type conversion: int or None + + :param format_spec: The formatting to be applied to the value. + :type format_spec: JoinedStr or None + """ + self.value = value + self.conversion = conversion + self.format_spec = format_spec + + def get_children(self): + yield self.value + + if self.format_spec is not None: + yield self.format_spec + + +class JoinedStr(NodeNG): + """Represents a list of string expressions to be joined. + + >>> node = astroid.extract_node('f"Format {type_}"') + >>> node + + """ + + _astroid_fields = ("values",) + values = None + """The string expressions to be joined. + + :type: list(FormattedValue or Const) or None + """ + + def postinit(self, values=None): + """Do some setup after initialisation. + + :param value: The string expressions to be joined. + + :type: list(FormattedValue or Const) or None + """ + self.values = values + + def get_children(self): + yield from self.values + + +class Unknown(mixins.AssignTypeMixin, NodeNG): + """This node represents a node in a constructed AST where + introspection is not possible. At the moment, it's only used in + the args attribute of FunctionDef nodes where function signature + introspection failed. + """ + + name = "Unknown" + + def qname(self): + return "Unknown" + + def infer(self, context=None, **kwargs): + """Inference on an Unknown node immediately terminates.""" + yield util.Uninferable + + +# constants ############################################################## + +CONST_CLS = { + list: List, + tuple: Tuple, + dict: Dict, + set: Set, + type(None): Const, + type(NotImplemented): Const, +} + + +def _update_const_classes(): + """update constant classes, so the keys of CONST_CLS can be reused""" + klasses = (bool, int, float, complex, str, bytes) + for kls in klasses: + CONST_CLS[kls] = Const + + +_update_const_classes() + + +def _two_step_initialization(cls, value): + instance = cls() + instance.postinit(value) + return instance + + +def _dict_initialization(cls, value): + if isinstance(value, dict): + value = tuple(value.items()) + return _two_step_initialization(cls, value) + + +_CONST_CLS_CONSTRUCTORS = { + List: _two_step_initialization, + Tuple: _two_step_initialization, + Dict: _dict_initialization, + Set: _two_step_initialization, + Const: lambda cls, value: cls(value), +} + + +def const_factory(value): + """return an astroid node for a python value""" + # XXX we should probably be stricter here and only consider stuff in + # CONST_CLS or do better treatment: in case where value is not in CONST_CLS, + # we should rather recall the builder on this value than returning an empty + # node (another option being that const_factory shouldn't be called with something + # not in CONST_CLS) + assert not isinstance(value, NodeNG) + + # Hack for ignoring elements of a sequence + # or a mapping, in order to avoid transforming + # each element to an AST. This is fixed in 2.0 + # and this approach is a temporary hack. + if isinstance(value, (list, set, tuple, dict)): + elts = [] + else: + elts = value + + try: + initializer_cls = CONST_CLS[value.__class__] + initializer = _CONST_CLS_CONSTRUCTORS[initializer_cls] + return initializer(initializer_cls, elts) + except (KeyError, AttributeError): + node = EmptyNode() + node.object = value + return node + + +def is_from_decorator(node): + """Return True if the given node is the child of a decorator""" + parent = node.parent + while parent is not None: + if isinstance(parent, Decorators): + return True + parent = parent.parent + return False diff --git a/basic python programmes/venv/Lib/site-packages/astroid/nodes.py b/basic python programmes/venv/Lib/site-packages/astroid/nodes.py new file mode 100644 index 0000000..2067259 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/nodes.py @@ -0,0 +1,173 @@ +# Copyright (c) 2006-2011, 2013 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2017 Ashley Whetter +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Every available node class. + +.. seealso:: + :doc:`ast documentation ` + +All nodes inherit from :class:`~astroid.node_classes.NodeNG`. +""" +# pylint: disable=unused-import,redefined-builtin + +from astroid.node_classes import ( + Arguments, + AssignAttr, + Assert, + Assign, + AnnAssign, + AssignName, + AugAssign, + Repr, + BinOp, + BoolOp, + Break, + Call, + Compare, + Comprehension, + Const, + Continue, + Decorators, + DelAttr, + DelName, + Delete, + Dict, + Expr, + Ellipsis, + EmptyNode, + ExceptHandler, + Exec, + ExtSlice, + For, + ImportFrom, + Attribute, + Global, + If, + IfExp, + Import, + Index, + Keyword, + List, + Name, + Nonlocal, + Pass, + Print, + Raise, + Return, + Set, + Slice, + Starred, + Subscript, + TryExcept, + TryFinally, + Tuple, + UnaryOp, + While, + With, + Yield, + YieldFrom, + const_factory, + AsyncFor, + Await, + AsyncWith, + FormattedValue, + JoinedStr, + # Node not present in the builtin ast module. + DictUnpack, + Unknown, +) +from astroid.scoped_nodes import ( + Module, + GeneratorExp, + Lambda, + DictComp, + ListComp, + SetComp, + FunctionDef, + ClassDef, + AsyncFunctionDef, +) + + +ALL_NODE_CLASSES = ( + AsyncFunctionDef, + AsyncFor, + AsyncWith, + Await, + Arguments, + AssignAttr, + Assert, + Assign, + AnnAssign, + AssignName, + AugAssign, + Repr, + BinOp, + BoolOp, + Break, + Call, + ClassDef, + Compare, + Comprehension, + Const, + Continue, + Decorators, + DelAttr, + DelName, + Delete, + Dict, + DictComp, + DictUnpack, + Expr, + Ellipsis, + EmptyNode, + ExceptHandler, + Exec, + ExtSlice, + For, + ImportFrom, + FunctionDef, + Attribute, + GeneratorExp, + Global, + If, + IfExp, + Import, + Index, + Keyword, + Lambda, + List, + ListComp, + Name, + Nonlocal, + Module, + Pass, + Print, + Raise, + Return, + Set, + SetComp, + Slice, + Starred, + Subscript, + TryExcept, + TryFinally, + Tuple, + UnaryOp, + While, + With, + Yield, + YieldFrom, + FormattedValue, + JoinedStr, +) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/objects.py b/basic python programmes/venv/Lib/site-packages/astroid/objects.py new file mode 100644 index 0000000..367f650 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/objects.py @@ -0,0 +1,250 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +Inference objects are a way to represent composite AST nodes, +which are used only as inference results, so they can't be found in the +original AST tree. For instance, inferring the following frozenset use, +leads to an inferred FrozenSet: + + Call(func=Name('frozenset'), args=Tuple(...)) +""" + +import builtins + +from astroid import bases +from astroid import decorators +from astroid import exceptions +from astroid import MANAGER +from astroid import node_classes +from astroid import scoped_nodes +from astroid import util + + +BUILTINS = builtins.__name__ +objectmodel = util.lazy_import("interpreter.objectmodel") + + +class FrozenSet(node_classes._BaseContainer): + """class representing a FrozenSet composite node""" + + def pytype(self): + return "%s.frozenset" % BUILTINS + + def _infer(self, context=None): + yield self + + @decorators.cachedproperty + def _proxied(self): # pylint: disable=method-hidden + ast_builtins = MANAGER.astroid_cache[BUILTINS] + return ast_builtins.getattr("frozenset")[0] + + +class Super(node_classes.NodeNG): + """Proxy class over a super call. + + This class offers almost the same behaviour as Python's super, + which is MRO lookups for retrieving attributes from the parents. + + The *mro_pointer* is the place in the MRO from where we should + start looking, not counting it. *mro_type* is the object which + provides the MRO, it can be both a type or an instance. + *self_class* is the class where the super call is, while + *scope* is the function where the super call is. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.SuperModel()) + + # pylint: disable=super-init-not-called + def __init__(self, mro_pointer, mro_type, self_class, scope): + self.type = mro_type + self.mro_pointer = mro_pointer + self._class_based = False + self._self_class = self_class + self._scope = scope + + def _infer(self, context=None): + yield self + + def super_mro(self): + """Get the MRO which will be used to lookup attributes in this super.""" + if not isinstance(self.mro_pointer, scoped_nodes.ClassDef): + raise exceptions.SuperError( + "The first argument to super must be a subtype of " + "type, not {mro_pointer}.", + super_=self, + ) + + if isinstance(self.type, scoped_nodes.ClassDef): + # `super(type, type)`, most likely in a class method. + self._class_based = True + mro_type = self.type + else: + mro_type = getattr(self.type, "_proxied", None) + if not isinstance(mro_type, (bases.Instance, scoped_nodes.ClassDef)): + raise exceptions.SuperError( + "The second argument to super must be an " + "instance or subtype of type, not {type}.", + super_=self, + ) + + if not mro_type.newstyle: + raise exceptions.SuperError( + "Unable to call super on old-style classes.", super_=self + ) + + mro = mro_type.mro() + if self.mro_pointer not in mro: + raise exceptions.SuperError( + "The second argument to super must be an " + "instance or subtype of type, not {type}.", + super_=self, + ) + + index = mro.index(self.mro_pointer) + return mro[index + 1 :] + + @decorators.cachedproperty + def _proxied(self): + ast_builtins = MANAGER.astroid_cache[BUILTINS] + return ast_builtins.getattr("super")[0] + + def pytype(self): + return "%s.super" % BUILTINS + + def display_type(self): + return "Super of" + + @property + def name(self): + """Get the name of the MRO pointer.""" + return self.mro_pointer.name + + def qname(self): + return "super" + + def igetattr(self, name, context=None): + """Retrieve the inferred values of the given attribute name.""" + + if name in self.special_attributes: + yield self.special_attributes.lookup(name) + return + + try: + mro = self.super_mro() + # Don't let invalid MROs or invalid super calls + # leak out as is from this function. + except exceptions.SuperError as exc: + raise exceptions.AttributeInferenceError( + ( + "Lookup for {name} on {target!r} because super call {super!r} " + "is invalid." + ), + target=self, + attribute=name, + context=context, + super_=exc.super_, + ) from exc + except exceptions.MroError as exc: + raise exceptions.AttributeInferenceError( + ( + "Lookup for {name} on {target!r} failed because {cls!r} has an " + "invalid MRO." + ), + target=self, + attribute=name, + context=context, + mros=exc.mros, + cls=exc.cls, + ) from exc + found = False + for cls in mro: + if name not in cls.locals: + continue + + found = True + for inferred in bases._infer_stmts([cls[name]], context, frame=self): + if not isinstance(inferred, scoped_nodes.FunctionDef): + yield inferred + continue + + # We can obtain different descriptors from a super depending + # on what we are accessing and where the super call is. + if inferred.type == "classmethod": + yield bases.BoundMethod(inferred, cls) + elif self._scope.type == "classmethod" and inferred.type == "method": + yield inferred + elif self._class_based or inferred.type == "staticmethod": + yield inferred + elif bases._is_property(inferred): + # TODO: support other descriptors as well. + try: + yield from inferred.infer_call_result(self, context) + except exceptions.InferenceError: + yield util.Uninferable + else: + yield bases.BoundMethod(inferred, cls) + + if not found: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def getattr(self, name, context=None): + return list(self.igetattr(name, context=context)) + + +class ExceptionInstance(bases.Instance): + """Class for instances of exceptions + + It has special treatment for some of the exceptions's attributes, + which are transformed at runtime into certain concrete objects, such as + the case of .args. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor( + lambda: objectmodel.ExceptionInstanceModel() + ) + + +class DictInstance(bases.Instance): + """Special kind of instances for dictionaries + + This instance knows the underlying object model of the dictionaries, which means + that methods such as .values or .items can be properly inferred. + """ + + # pylint: disable=unnecessary-lambda + special_attributes = util.lazy_descriptor(lambda: objectmodel.DictModel()) + + +# Custom objects tailored for dictionaries, which are used to +# disambiguate between the types of Python 2 dict's method returns +# and Python 3 (where they return set like objects). +class DictItems(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class DictKeys(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +class DictValues(bases.Proxy): + __str__ = node_classes.NodeNG.__str__ + __repr__ = node_classes.NodeNG.__repr__ + + +# TODO: Hack to solve the circular import problem between node_classes and objects +# This is not needed in 2.0, which has a cleaner design overall +node_classes.Dict.__bases__ = (node_classes.NodeNG, DictInstance) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/protocols.py b/basic python programmes/venv/Lib/site-packages/astroid/protocols.py new file mode 100644 index 0000000..86889b4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/protocols.py @@ -0,0 +1,760 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Dmitry Pribysh +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to handle python protocols for nodes +where it makes sense. +""" + +import collections +import operator as operator_mod +import sys + +import itertools + +from astroid import Store +from astroid import arguments +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators +from astroid import node_classes +from astroid import helpers +from astroid import nodes +from astroid import util + +raw_building = util.lazy_import("raw_building") +objects = util.lazy_import("objects") + + +def _reflected_name(name): + return "__r" + name[2:] + + +def _augmented_name(name): + return "__i" + name[2:] + + +_CONTEXTLIB_MGR = "contextlib.contextmanager" +BIN_OP_METHOD = { + "+": "__add__", + "-": "__sub__", + "/": "__truediv__", + "//": "__floordiv__", + "*": "__mul__", + "**": "__pow__", + "%": "__mod__", + "&": "__and__", + "|": "__or__", + "^": "__xor__", + "<<": "__lshift__", + ">>": "__rshift__", + "@": "__matmul__", +} + +REFLECTED_BIN_OP_METHOD = { + key: _reflected_name(value) for (key, value) in BIN_OP_METHOD.items() +} +AUGMENTED_OP_METHOD = { + key + "=": _augmented_name(value) for (key, value) in BIN_OP_METHOD.items() +} + +UNARY_OP_METHOD = { + "+": "__pos__", + "-": "__neg__", + "~": "__invert__", + "not": None, # XXX not '__nonzero__' +} +_UNARY_OPERATORS = { + "+": operator_mod.pos, + "-": operator_mod.neg, + "~": operator_mod.invert, + "not": operator_mod.not_, +} + + +def _infer_unary_op(obj, op): + func = _UNARY_OPERATORS[op] + value = func(obj) + return nodes.const_factory(value) + + +nodes.Tuple.infer_unary_op = lambda self, op: _infer_unary_op(tuple(self.elts), op) +nodes.List.infer_unary_op = lambda self, op: _infer_unary_op(self.elts, op) +nodes.Set.infer_unary_op = lambda self, op: _infer_unary_op(set(self.elts), op) +nodes.Const.infer_unary_op = lambda self, op: _infer_unary_op(self.value, op) +nodes.Dict.infer_unary_op = lambda self, op: _infer_unary_op(dict(self.items), op) + +# Binary operations + +BIN_OP_IMPL = { + "+": lambda a, b: a + b, + "-": lambda a, b: a - b, + "/": lambda a, b: a / b, + "//": lambda a, b: a // b, + "*": lambda a, b: a * b, + "**": lambda a, b: a ** b, + "%": lambda a, b: a % b, + "&": lambda a, b: a & b, + "|": lambda a, b: a | b, + "^": lambda a, b: a ^ b, + "<<": lambda a, b: a << b, + ">>": lambda a, b: a >> b, +} +if sys.version_info >= (3, 5): + # MatMult is available since Python 3.5+. + BIN_OP_IMPL["@"] = operator_mod.matmul + +for _KEY, _IMPL in list(BIN_OP_IMPL.items()): + BIN_OP_IMPL[_KEY + "="] = _IMPL + + +@decorators.yes_if_nothing_inferred +def const_infer_binary_op(self, opnode, operator, other, context, _): + not_implemented = nodes.Const(NotImplemented) + if isinstance(other, nodes.Const): + try: + impl = BIN_OP_IMPL[operator] + try: + yield nodes.const_factory(impl(self.value, other.value)) + except TypeError: + # ArithmeticError is not enough: float >> float is a TypeError + yield not_implemented + except Exception: # pylint: disable=broad-except + yield util.Uninferable + except TypeError: + yield not_implemented + elif isinstance(self.value, str) and operator == "%": + # TODO(cpopa): implement string interpolation later on. + yield util.Uninferable + else: + yield not_implemented + + +nodes.Const.infer_binary_op = const_infer_binary_op + + +def _multiply_seq_by_int(self, opnode, other, context): + node = self.__class__(parent=opnode) + filtered_elts = ( + helpers.safe_infer(elt, context) or util.Uninferable + for elt in self.elts + if elt is not util.Uninferable + ) + node.elts = list(filtered_elts) * other.value + return node + + +def _filter_uninferable_nodes(elts, context): + for elt in elts: + if elt is util.Uninferable: + yield nodes.Unknown() + else: + for inferred in elt.infer(context): + if inferred is not util.Uninferable: + yield inferred + else: + yield nodes.Unknown() + + +@decorators.yes_if_nothing_inferred +def tl_infer_binary_op(self, opnode, operator, other, context, method): + not_implemented = nodes.Const(NotImplemented) + if isinstance(other, self.__class__) and operator == "+": + node = self.__class__(parent=opnode) + node.elts = list( + itertools.chain( + _filter_uninferable_nodes(self.elts, context), + _filter_uninferable_nodes(other.elts, context), + ) + ) + yield node + elif isinstance(other, nodes.Const) and operator == "*": + if not isinstance(other.value, int): + yield not_implemented + return + yield _multiply_seq_by_int(self, opnode, other, context) + elif isinstance(other, bases.Instance) and operator == "*": + # Verify if the instance supports __index__. + as_index = helpers.class_instance_as_index(other) + if not as_index: + yield util.Uninferable + else: + yield _multiply_seq_by_int(self, opnode, as_index, context) + else: + yield not_implemented + + +nodes.Tuple.infer_binary_op = tl_infer_binary_op +nodes.List.infer_binary_op = tl_infer_binary_op + + +@decorators.yes_if_nothing_inferred +def instance_class_infer_binary_op(self, opnode, operator, other, context, method): + return method.infer_call_result(self, context) + + +bases.Instance.infer_binary_op = instance_class_infer_binary_op +nodes.ClassDef.infer_binary_op = instance_class_infer_binary_op + + +# assignment ################################################################## + +"""the assigned_stmts method is responsible to return the assigned statement +(e.g. not inferred) according to the assignment type. + +The `assign_path` argument is used to record the lhs path of the original node. +For instance if we want assigned statements for 'c' in 'a, (b,c)', assign_path +will be [1, 1] once arrived to the Assign node. + +The `context` argument is the current inference context which should be given +to any intermediary inference necessary. +""" + + +def _resolve_looppart(parts, assign_path, context): + """recursive function to resolve multiple assignments on loops""" + assign_path = assign_path[:] + index = assign_path.pop(0) + for part in parts: + if part is util.Uninferable: + continue + if not hasattr(part, "itered"): + continue + try: + itered = part.itered() + except TypeError: + continue + for stmt in itered: + index_node = nodes.Const(index) + try: + assigned = stmt.getitem(index_node, context) + except ( + AttributeError, + exceptions.AstroidTypeError, + exceptions.AstroidIndexError, + ): + continue + if not assign_path: + # we achieved to resolved the assignment path, + # don't infer the last part + yield assigned + elif assigned is util.Uninferable: + break + else: + # we are not yet on the last part of the path + # search on each possibly inferred value + try: + yield from _resolve_looppart( + assigned.infer(context), assign_path, context + ) + except exceptions.InferenceError: + break + + +@decorators.raise_if_nothing_inferred +def for_assigned_stmts(self, node=None, context=None, assign_path=None): + if isinstance(self, nodes.AsyncFor) or getattr(self, "is_async", False): + # Skip inferring of async code for now + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + if assign_path is None: + for lst in self.iter.infer(context): + if isinstance(lst, (nodes.Tuple, nodes.List)): + yield from lst.elts + else: + yield from _resolve_looppart(self.iter.infer(context), assign_path, context) + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.For.assigned_stmts = for_assigned_stmts +nodes.Comprehension.assigned_stmts = for_assigned_stmts + + +def sequence_assigned_stmts(self, node=None, context=None, assign_path=None): + if assign_path is None: + assign_path = [] + try: + index = self.elts.index(node) + except ValueError as exc: + raise exceptions.InferenceError( + "Tried to retrieve a node {node!r} which does not exist", + node=self, + assign_path=assign_path, + context=context, + ) from exc + + assign_path.insert(0, index) + return self.parent.assigned_stmts( + node=self, context=context, assign_path=assign_path + ) + + +nodes.Tuple.assigned_stmts = sequence_assigned_stmts +nodes.List.assigned_stmts = sequence_assigned_stmts + + +def assend_assigned_stmts(self, node=None, context=None, assign_path=None): + return self.parent.assigned_stmts(node=self, context=context) + + +nodes.AssignName.assigned_stmts = assend_assigned_stmts +nodes.AssignAttr.assigned_stmts = assend_assigned_stmts + + +def _arguments_infer_argname(self, name, context): + # arguments information may be missing, in which case we can't do anything + # more + if not (self.args or self.vararg or self.kwarg): + yield util.Uninferable + return + # first argument of instance/class method + if self.args and getattr(self.args[0], "name", None) == name: + functype = self.parent.type + cls = self.parent.parent.scope() + is_metaclass = isinstance(cls, nodes.ClassDef) and cls.type == "metaclass" + # If this is a metaclass, then the first argument will always + # be the class, not an instance. + if is_metaclass or functype == "classmethod": + yield cls + return + if functype == "method": + yield bases.Instance(cls) + return + + if context and context.callcontext: + call_site = arguments.CallSite(context.callcontext, context.extra_context) + yield from call_site.infer_argument(self.parent, name, context) + return + + if name == self.vararg: + vararg = nodes.const_factory(()) + vararg.parent = self + yield vararg + return + if name == self.kwarg: + kwarg = nodes.const_factory({}) + kwarg.parent = self + yield kwarg + return + # if there is a default value, yield it. And then yield Uninferable to reflect + # we can't guess given argument value + try: + context = contextmod.copy_context(context) + yield from self.default_value(name).infer(context) + yield util.Uninferable + except exceptions.NoDefault: + yield util.Uninferable + + +def arguments_assigned_stmts(self, node=None, context=None, assign_path=None): + if context.callcontext: + # reset call context/name + callcontext = context.callcontext + context = contextmod.copy_context(context) + context.callcontext = None + args = arguments.CallSite(callcontext) + return args.infer_argument(self.parent, node.name, context) + return _arguments_infer_argname(self, node.name, context) + + +nodes.Arguments.assigned_stmts = arguments_assigned_stmts + + +@decorators.raise_if_nothing_inferred +def assign_assigned_stmts(self, node=None, context=None, assign_path=None): + if not assign_path: + yield self.value + return None + yield from _resolve_assignment_parts( + self.value.infer(context), assign_path, context + ) + + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +def assign_annassigned_stmts(self, node=None, context=None, assign_path=None): + for inferred in assign_assigned_stmts(self, node, context, assign_path): + if inferred is None: + yield util.Uninferable + else: + yield inferred + + +nodes.Assign.assigned_stmts = assign_assigned_stmts +nodes.AnnAssign.assigned_stmts = assign_annassigned_stmts +nodes.AugAssign.assigned_stmts = assign_assigned_stmts + + +def _resolve_assignment_parts(parts, assign_path, context): + """recursive function to resolve multiple assignments""" + assign_path = assign_path[:] + index = assign_path.pop(0) + for part in parts: + assigned = None + if isinstance(part, nodes.Dict): + # A dictionary in an iterating context + try: + assigned, _ = part.items[index] + except IndexError: + return + + elif hasattr(part, "getitem"): + index_node = nodes.Const(index) + try: + assigned = part.getitem(index_node, context) + except (exceptions.AstroidTypeError, exceptions.AstroidIndexError): + return + + if not assigned: + return + + if not assign_path: + # we achieved to resolved the assignment path, don't infer the + # last part + yield assigned + elif assigned is util.Uninferable: + return + else: + # we are not yet on the last part of the path search on each + # possibly inferred value + try: + yield from _resolve_assignment_parts( + assigned.infer(context), assign_path, context + ) + except exceptions.InferenceError: + return + + +@decorators.raise_if_nothing_inferred +def excepthandler_assigned_stmts(self, node=None, context=None, assign_path=None): + for assigned in node_classes.unpack_infer(self.type): + if isinstance(assigned, nodes.ClassDef): + assigned = objects.ExceptionInstance(assigned) + + yield assigned + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.ExceptHandler.assigned_stmts = excepthandler_assigned_stmts + + +def _infer_context_manager(self, mgr, context): + try: + inferred = next(mgr.infer(context=context)) + except (StopIteration, exceptions.InferenceError): + return + if isinstance(inferred, bases.Generator): + # Check if it is decorated with contextlib.contextmanager. + func = inferred.parent + if not func.decorators: + return + for decorator_node in func.decorators.nodes: + try: + decorator = next(decorator_node.infer(context)) + except StopIteration: + return + if isinstance(decorator, nodes.FunctionDef): + if decorator.qname() == _CONTEXTLIB_MGR: + break + else: + # It doesn't interest us. + return + + # Get the first yield point. If it has multiple yields, + # then a RuntimeError will be raised. + + possible_yield_points = func.nodes_of_class(nodes.Yield) + # Ignore yields in nested functions + yield_point = next( + (node for node in possible_yield_points if node.scope() == func), None + ) + if yield_point: + if not yield_point.value: + const = nodes.Const(None) + const.parent = yield_point + const.lineno = yield_point.lineno + yield const + else: + yield from yield_point.value.infer(context=context) + elif isinstance(inferred, bases.Instance): + try: + enter = next(inferred.igetattr("__enter__", context=context)) + except ( + StopIteration, + exceptions.InferenceError, + exceptions.AttributeInferenceError, + ): + return + if not isinstance(enter, bases.BoundMethod): + return + if not context.callcontext: + context.callcontext = contextmod.CallContext(args=[inferred]) + yield from enter.infer_call_result(self, context) + + +@decorators.raise_if_nothing_inferred +def with_assigned_stmts(self, node=None, context=None, assign_path=None): + """Infer names and other nodes from a *with* statement. + + This enables only inference for name binding in a *with* statement. + For instance, in the following code, inferring `func` will return + the `ContextManager` class, not whatever ``__enter__`` returns. + We are doing this intentionally, because we consider that the context + manager result is whatever __enter__ returns and what it is binded + using the ``as`` keyword. + + class ContextManager(object): + def __enter__(self): + return 42 + with ContextManager() as f: + pass + + # ContextManager().infer() will return ContextManager + # f.infer() will return 42. + + Arguments: + self: nodes.With + node: The target of the assignment, `as (a, b)` in `with foo as (a, b)`. + context: Inference context used for caching already inferred objects + assign_path: + A list of indices, where each index specifies what item to fetch from + the inference results. + """ + try: + mgr = next(mgr for (mgr, vars) in self.items if vars == node) + except StopIteration: + return None + if assign_path is None: + yield from _infer_context_manager(self, mgr, context) + else: + for result in _infer_context_manager(self, mgr, context): + # Walk the assign_path and get the item at the final index. + obj = result + for index in assign_path: + if not hasattr(obj, "elts"): + raise exceptions.InferenceError( + "Wrong type ({targets!r}) for {node!r} assignment", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) + try: + obj = obj.elts[index] + except IndexError as exc: + raise exceptions.InferenceError( + "Tried to infer a nonexistent target with index {index} " + "in {node!r}.", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) from exc + except TypeError as exc: + raise exceptions.InferenceError( + "Tried to unpack a non-iterable value " "in {node!r}.", + node=self, + targets=node, + assign_path=assign_path, + context=context, + ) from exc + yield obj + return dict(node=self, unknown=node, assign_path=assign_path, context=context) + + +nodes.With.assigned_stmts = with_assigned_stmts + + +@decorators.yes_if_nothing_inferred +def starred_assigned_stmts(self, node=None, context=None, assign_path=None): + """ + Arguments: + self: nodes.Starred + node: a node related to the current underlying Node. + context: Inference context used for caching already inferred objects + assign_path: + A list of indices, where each index specifies what item to fetch from + the inference results. + """ + # pylint: disable=too-many-locals,too-many-branches,too-many-statements + def _determine_starred_iteration_lookups(starred, target, lookups): + # Determine the lookups for the rhs of the iteration + itered = target.itered() + for index, element in enumerate(itered): + if ( + isinstance(element, nodes.Starred) + and element.value.name == starred.value.name + ): + lookups.append((index, len(itered))) + break + if isinstance(element, nodes.Tuple): + lookups.append((index, len(element.itered()))) + _determine_starred_iteration_lookups(starred, element, lookups) + + stmt = self.statement() + if not isinstance(stmt, (nodes.Assign, nodes.For)): + raise exceptions.InferenceError( + "Statement {stmt!r} enclosing {node!r} " "must be an Assign or For node.", + node=self, + stmt=stmt, + unknown=node, + context=context, + ) + + if context is None: + context = contextmod.InferenceContext() + + if isinstance(stmt, nodes.Assign): + value = stmt.value + lhs = stmt.targets[0] + + if sum(1 for _ in lhs.nodes_of_class(nodes.Starred)) > 1: + raise exceptions.InferenceError( + "Too many starred arguments in the " " assignment targets {lhs!r}.", + node=self, + targets=lhs, + unknown=node, + context=context, + ) + + try: + rhs = next(value.infer(context)) + except exceptions.InferenceError: + yield util.Uninferable + return + if rhs is util.Uninferable or not hasattr(rhs, "itered"): + yield util.Uninferable + return + + try: + elts = collections.deque(rhs.itered()) + except TypeError: + yield util.Uninferable + return + + # Unpack iteratively the values from the rhs of the assignment, + # until the find the starred node. What will remain will + # be the list of values which the Starred node will represent + # This is done in two steps, from left to right to remove + # anything before the starred node and from right to left + # to remove anything after the starred node. + + for index, left_node in enumerate(lhs.elts): + if not isinstance(left_node, nodes.Starred): + if not elts: + break + elts.popleft() + continue + lhs_elts = collections.deque(reversed(lhs.elts[index:])) + for right_node in lhs_elts: + if not isinstance(right_node, nodes.Starred): + if not elts: + break + elts.pop() + continue + # We're done + packed = nodes.List( + ctx=Store, parent=self, lineno=lhs.lineno, col_offset=lhs.col_offset + ) + packed.postinit(elts=elts) + yield packed + break + + if isinstance(stmt, nodes.For): + try: + inferred_iterable = next(stmt.iter.infer(context=context)) + except exceptions.InferenceError: + yield util.Uninferable + return + if inferred_iterable is util.Uninferable or not hasattr( + inferred_iterable, "itered" + ): + yield util.Uninferable + return + try: + itered = inferred_iterable.itered() + except TypeError: + yield util.Uninferable + return + + target = stmt.target + + if not isinstance(target, nodes.Tuple): + raise exceptions.InferenceError( + "Could not make sense of this, the target must be a tuple", + context=context, + ) + + lookups = [] + _determine_starred_iteration_lookups(self, target, lookups) + if not lookups: + raise exceptions.InferenceError( + "Could not make sense of this, needs at least a lookup", context=context + ) + + # Make the last lookup a slice, since that what we want for a Starred node + last_element_index, last_element_length = lookups[-1] + is_starred_last = last_element_index == (last_element_length - 1) + + lookup_slice = slice( + last_element_index, + None if is_starred_last else (last_element_length - last_element_index), + ) + lookups[-1] = lookup_slice + + for element in itered: + + # We probably want to infer the potential values *for each* element in an + # iterable, but we can't infer a list of all values, when only a list of + # step values are expected: + # + # for a, *b in [...]: + # b + # + # *b* should now point to just the elements at that particular iteration step, + # which astroid can't know about. + + found_element = None + for lookup in lookups: + if not hasattr(element, "itered"): + break + if not isinstance(lookup, slice): + # Grab just the index, not the whole length + lookup = lookup[0] + try: + itered_inner_element = element.itered() + element = itered_inner_element[lookup] + except IndexError: + break + except TypeError: + # Most likely the itered() call failed, cannot make sense of this + yield util.Uninferable + return + else: + found_element = element + + unpacked = nodes.List( + ctx=Store, parent=self, lineno=self.lineno, col_offset=self.col_offset + ) + unpacked.postinit(elts=found_element or []) + yield unpacked + return + + yield util.Uninferable + + +nodes.Starred.assigned_stmts = starred_assigned_stmts diff --git a/basic python programmes/venv/Lib/site-packages/astroid/raw_building.py b/basic python programmes/venv/Lib/site-packages/astroid/raw_building.py new file mode 100644 index 0000000..1cd6c81 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/raw_building.py @@ -0,0 +1,458 @@ +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2012 FELD Boris +# Copyright (c) 2014-2018 Claudiu Popa +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Florian Bruhin +# Copyright (c) 2015 Ovidiu Sabou +# Copyright (c) 2016 Derek Gustafson +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains a set of functions to create astroid trees from scratch +(build_* functions) or from living object (object_build_* functions) +""" + +import builtins +import inspect +import logging +import os +import sys +import types + +from astroid import bases +from astroid import manager +from astroid import node_classes +from astroid import nodes + + +MANAGER = manager.AstroidManager() +# the keys of CONST_CLS eg python builtin types + +_CONSTANTS = tuple(node_classes.CONST_CLS) +_BUILTINS = vars(builtins) +_LOG = logging.getLogger(__name__) + + +def _io_discrepancy(member): + # _io module names itself `io`: http://bugs.python.org/issue18602 + member_self = getattr(member, "__self__", None) + return ( + member_self + and inspect.ismodule(member_self) + and member_self.__name__ == "_io" + and member.__module__ == "io" + ) + + +def _attach_local_node(parent, node, name): + node.name = name # needed by add_local_node + parent.add_local_node(node) + + +def _add_dunder_class(func, member): + """Add a __class__ member to the given func node, if we can determine it.""" + python_cls = member.__class__ + cls_name = getattr(python_cls, "__name__", None) + if not cls_name: + return + cls_bases = [ancestor.__name__ for ancestor in python_cls.__bases__] + ast_klass = build_class(cls_name, cls_bases, python_cls.__doc__) + func.instance_attrs["__class__"] = [ast_klass] + + +_marker = object() + + +def attach_dummy_node(node, name, runtime_object=_marker): + """create a dummy node and register it in the locals of the given + node with the specified name + """ + enode = nodes.EmptyNode() + enode.object = runtime_object + _attach_local_node(node, enode, name) + + +def _has_underlying_object(self): + return self.object is not None and self.object is not _marker + + +nodes.EmptyNode.has_underlying_object = _has_underlying_object + + +def attach_const_node(node, name, value): + """create a Const node and register it in the locals of the given + node with the specified name + """ + if name not in node.special_attributes: + _attach_local_node(node, nodes.const_factory(value), name) + + +def attach_import_node(node, modname, membername): + """create a ImportFrom node and register it in the locals of the given + node with the specified name + """ + from_node = nodes.ImportFrom(modname, [(membername, None)]) + _attach_local_node(node, from_node, membername) + + +def build_module(name, doc=None): + """create and initialize an astroid Module node""" + node = nodes.Module(name, doc, pure_python=False) + node.package = False + node.parent = None + return node + + +def build_class(name, basenames=(), doc=None): + """create and initialize an astroid ClassDef node""" + node = nodes.ClassDef(name, doc) + for base in basenames: + basenode = nodes.Name() + basenode.name = base + node.bases.append(basenode) + basenode.parent = node + return node + + +def build_function(name, args=None, defaults=None, doc=None): + """create and initialize an astroid FunctionDef node""" + args, defaults = args or [], defaults or [] + # first argument is now a list of decorators + func = nodes.FunctionDef(name, doc) + func.args = argsnode = nodes.Arguments() + argsnode.args = [] + for arg in args: + argsnode.args.append(nodes.Name()) + argsnode.args[-1].name = arg + argsnode.args[-1].parent = argsnode + argsnode.defaults = [] + for default in defaults: + argsnode.defaults.append(nodes.const_factory(default)) + argsnode.defaults[-1].parent = argsnode + argsnode.kwarg = None + argsnode.vararg = None + argsnode.parent = func + if args: + register_arguments(func) + return func + + +def build_from_import(fromname, names): + """create and initialize an astroid ImportFrom import statement""" + return nodes.ImportFrom(fromname, [(name, None) for name in names]) + + +def register_arguments(func, args=None): + """add given arguments to local + + args is a list that may contains nested lists + (i.e. def func(a, (b, c, d)): ...) + """ + if args is None: + args = func.args.args + if func.args.vararg: + func.set_local(func.args.vararg, func.args) + if func.args.kwarg: + func.set_local(func.args.kwarg, func.args) + for arg in args: + if isinstance(arg, nodes.Name): + func.set_local(arg.name, arg) + else: + register_arguments(func, arg.elts) + + +def object_build_class(node, member, localname): + """create astroid for a living class object""" + basenames = [base.__name__ for base in member.__bases__] + return _base_class_object_build(node, member, basenames, localname=localname) + + +def object_build_function(node, member, localname): + """create astroid for a living function object""" + # pylint: disable=deprecated-method; completely removed in 2.0 + args, varargs, varkw, defaults = inspect.getargspec(member) + if varargs is not None: + args.append(varargs) + if varkw is not None: + args.append(varkw) + func = build_function( + getattr(member, "__name__", None) or localname, args, defaults, member.__doc__ + ) + node.add_local_node(func, localname) + + +def object_build_datadescriptor(node, member, name): + """create astroid for a living data descriptor object""" + return _base_class_object_build(node, member, [], name) + + +def object_build_methoddescriptor(node, member, localname): + """create astroid for a living method descriptor object""" + # FIXME get arguments ? + func = build_function( + getattr(member, "__name__", None) or localname, doc=member.__doc__ + ) + # set node's arguments to None to notice that we have no information, not + # and empty argument list + func.args.args = None + node.add_local_node(func, localname) + _add_dunder_class(func, member) + + +def _base_class_object_build(node, member, basenames, name=None, localname=None): + """create astroid for a living class object, with a given set of base names + (e.g. ancestors) + """ + klass = build_class( + name or getattr(member, "__name__", None) or localname, + basenames, + member.__doc__, + ) + klass._newstyle = isinstance(member, type) + node.add_local_node(klass, localname) + try: + # limit the instantiation trick since it's too dangerous + # (such as infinite test execution...) + # this at least resolves common case such as Exception.args, + # OSError.errno + if issubclass(member, Exception): + instdict = member().__dict__ + else: + raise TypeError + except: # pylint: disable=bare-except + pass + else: + for item_name, obj in instdict.items(): + valnode = nodes.EmptyNode() + valnode.object = obj + valnode.parent = klass + valnode.lineno = 1 + klass.instance_attrs[item_name] = [valnode] + return klass + + +def _build_from_function(node, name, member, module): + # verify this is not an imported function + try: + code = member.__code__ + except AttributeError: + # Some implementations don't provide the code object, + # such as Jython. + code = None + filename = getattr(code, "co_filename", None) + if filename is None: + assert isinstance(member, object) + object_build_methoddescriptor(node, member, name) + elif filename != getattr(module, "__file__", None): + attach_dummy_node(node, name, member) + else: + object_build_function(node, member, name) + + +class InspectBuilder: + """class for building nodes from living object + + this is actually a really minimal representation, including only Module, + FunctionDef and ClassDef nodes and some others as guessed. + """ + + # astroid from living objects ############################################### + + def __init__(self): + self._done = {} + self._module = None + + def inspect_build(self, module, modname=None, path=None): + """build astroid from a living module (i.e. using inspect) + this is used when there is no python source code available (either + because it's a built-in module or because the .py is not available) + """ + self._module = module + if modname is None: + modname = module.__name__ + try: + node = build_module(modname, module.__doc__) + except AttributeError: + # in jython, java modules have no __doc__ (see #109562) + node = build_module(modname) + node.file = node.path = os.path.abspath(path) if path else path + node.name = modname + MANAGER.cache_module(node) + node.package = hasattr(module, "__path__") + self._done = {} + self.object_build(node, module) + return node + + def object_build(self, node, obj): + """recursive method which create a partial ast from real objects + (only function, class, and method are handled) + """ + if obj in self._done: + return self._done[obj] + self._done[obj] = node + for name in dir(obj): + try: + member = getattr(obj, name) + except AttributeError: + # damned ExtensionClass.Base, I know you're there ! + attach_dummy_node(node, name) + continue + if inspect.ismethod(member): + member = member.__func__ + if inspect.isfunction(member): + _build_from_function(node, name, member, self._module) + elif inspect.isbuiltin(member): + if not _io_discrepancy(member) and self.imported_member( + node, member, name + ): + continue + object_build_methoddescriptor(node, member, name) + elif inspect.isclass(member): + if self.imported_member(node, member, name): + continue + if member in self._done: + class_node = self._done[member] + if class_node not in node.locals.get(name, ()): + node.add_local_node(class_node, name) + else: + class_node = object_build_class(node, member, name) + # recursion + self.object_build(class_node, member) + if name == "__class__" and class_node.parent is None: + class_node.parent = self._done[self._module] + elif inspect.ismethoddescriptor(member): + assert isinstance(member, object) + object_build_methoddescriptor(node, member, name) + elif inspect.isdatadescriptor(member): + assert isinstance(member, object) + object_build_datadescriptor(node, member, name) + elif isinstance(member, _CONSTANTS): + attach_const_node(node, name, member) + elif inspect.isroutine(member): + # This should be called for Jython, where some builtin + # methods aren't caught by isbuiltin branch. + _build_from_function(node, name, member, self._module) + else: + # create an empty node so that the name is actually defined + attach_dummy_node(node, name, member) + return None + + def imported_member(self, node, member, name): + """verify this is not an imported class or handle it""" + # /!\ some classes like ExtensionClass doesn't have a __module__ + # attribute ! Also, this may trigger an exception on badly built module + # (see http://www.logilab.org/ticket/57299 for instance) + try: + modname = getattr(member, "__module__", None) + except: # pylint: disable=bare-except + _LOG.exception( + "unexpected error while building " "astroid from living object" + ) + modname = None + if modname is None: + if name in ("__new__", "__subclasshook__"): + # Python 2.5.1 (r251:54863, Sep 1 2010, 22:03:14) + # >>> print object.__new__.__module__ + # None + modname = builtins.__name__ + else: + attach_dummy_node(node, name, member) + return True + + real_name = {"gtk": "gtk_gtk", "_io": "io"}.get(modname, modname) + + if real_name != self._module.__name__: + # check if it sounds valid and then add an import node, else use a + # dummy node + try: + getattr(sys.modules[modname], name) + except (KeyError, AttributeError): + attach_dummy_node(node, name, member) + else: + attach_import_node(node, modname, name) + return True + return False + + +### astroid bootstrapping ###################################################### +Astroid_BUILDER = InspectBuilder() + +_CONST_PROXY = {} + + +def _astroid_bootstrapping(astroid_builtin=None): + """astroid boot strapping the builtins module""" + # this boot strapping is necessary since we need the Const nodes to + # inspect_build builtins, and then we can proxy Const + if astroid_builtin is None: + astroid_builtin = Astroid_BUILDER.inspect_build(builtins) + + # pylint: disable=redefined-outer-name + for cls, node_cls in node_classes.CONST_CLS.items(): + if cls is type(None): + proxy = build_class("NoneType") + proxy.parent = astroid_builtin + elif cls is type(NotImplemented): + proxy = build_class("NotImplementedType") + proxy.parent = astroid_builtin + else: + proxy = astroid_builtin.getattr(cls.__name__)[0] + if cls in (dict, list, set, tuple): + node_cls._proxied = proxy + else: + _CONST_PROXY[cls] = proxy + + +_astroid_bootstrapping() + +# TODO : find a nicer way to handle this situation; +def _set_proxied(const): + return _CONST_PROXY[const.value.__class__] + + +nodes.Const._proxied = property(_set_proxied) + +_GeneratorType = nodes.ClassDef( + types.GeneratorType.__name__, types.GeneratorType.__doc__ +) +_GeneratorType.parent = MANAGER.astroid_cache[builtins.__name__] +bases.Generator._proxied = _GeneratorType +Astroid_BUILDER.object_build(bases.Generator._proxied, types.GeneratorType) + +if hasattr(types, "AsyncGeneratorType"): + # pylint: disable=no-member; AsyncGeneratorType + _AsyncGeneratorType = nodes.ClassDef( + types.AsyncGeneratorType.__name__, types.AsyncGeneratorType.__doc__ + ) + _AsyncGeneratorType.parent = MANAGER.astroid_cache[builtins.__name__] + bases.AsyncGenerator._proxied = _AsyncGeneratorType + Astroid_BUILDER.object_build( + bases.AsyncGenerator._proxied, types.AsyncGeneratorType + ) +# pylint: enable=no-member + + +_builtins = MANAGER.astroid_cache[builtins.__name__] +BUILTIN_TYPES = ( + types.GetSetDescriptorType, + types.GeneratorType, + types.MemberDescriptorType, + type(None), + type(NotImplemented), + types.FunctionType, + types.MethodType, + types.BuiltinFunctionType, + types.ModuleType, + types.TracebackType, +) +for _type in BUILTIN_TYPES: + if _type.__name__ not in _builtins: + cls = nodes.ClassDef(_type.__name__, _type.__doc__) + cls.parent = MANAGER.astroid_cache[builtins.__name__] + Astroid_BUILDER.object_build(cls, _type) + _builtins[_type.__name__] = cls diff --git a/basic python programmes/venv/Lib/site-packages/astroid/rebuilder.py b/basic python programmes/venv/Lib/site-packages/astroid/rebuilder.py new file mode 100644 index 0000000..4a2d52a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/rebuilder.py @@ -0,0 +1,1066 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2013-2018 Claudiu Popa +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 Alexander Presnyakov +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2016 Jared Garst +# Copyright (c) 2017 Hugo +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 rr- +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Bryce Guinta + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""this module contains utilities for rebuilding a _ast tree in +order to get a single Astroid representation +""" + +import sys + +import astroid +from astroid._ast import _parse, _get_parser_module, parse_function_type_comment +from astroid import nodes + + +CONST_NAME_TRANSFORMS = {"None": None, "True": True, "False": False} + +REDIRECT = { + "arguments": "Arguments", + "comprehension": "Comprehension", + "ListCompFor": "Comprehension", + "GenExprFor": "Comprehension", + "excepthandler": "ExceptHandler", + "keyword": "Keyword", +} +PY3 = sys.version_info >= (3, 0) +PY34 = sys.version_info >= (3, 4) +PY37 = sys.version_info >= (3, 7) + + +def _binary_operators_from_module(module): + binary_operators = { + module.Add: "+", + module.BitAnd: "&", + module.BitOr: "|", + module.BitXor: "^", + module.Div: "/", + module.FloorDiv: "//", + module.Mod: "%", + module.Mult: "*", + module.Pow: "**", + module.Sub: "-", + module.LShift: "<<", + module.RShift: ">>", + } + if sys.version_info >= (3, 5): + binary_operators[module.MatMult] = "@" + return binary_operators + + +def _bool_operators_from_module(module): + return {module.And: "and", module.Or: "or"} + + +def _unary_operators_from_module(module): + return {module.UAdd: "+", module.USub: "-", module.Not: "not", module.Invert: "~"} + + +def _compare_operators_from_module(module): + return { + module.Eq: "==", + module.Gt: ">", + module.GtE: ">=", + module.In: "in", + module.Is: "is", + module.IsNot: "is not", + module.Lt: "<", + module.LtE: "<=", + module.NotEq: "!=", + module.NotIn: "not in", + } + + +def _contexts_from_module(module): + return { + module.Load: astroid.Load, + module.Store: astroid.Store, + module.Del: astroid.Del, + module.Param: astroid.Store, + } + + +def _visit_or_none(node, attr, visitor, parent, visit="visit", **kws): + """If the given node has an attribute, visits the attribute, and + otherwise returns None. + + """ + value = getattr(node, attr, None) + if value: + return getattr(visitor, visit)(value, parent, **kws) + + return None + + +class TreeRebuilder: + """Rebuilds the _ast tree to become an Astroid tree""" + + def __init__(self, manager, parse_python_two: bool = False): + self._manager = manager + self._global_names = [] + self._import_from_nodes = [] + self._delayed_assattr = [] + self._visit_meths = {} + + # Configure the right classes for the right module + self._parser_module = _get_parser_module(parse_python_two=parse_python_two) + self._unary_op_classes = _unary_operators_from_module(self._parser_module) + self._cmp_op_classes = _compare_operators_from_module(self._parser_module) + self._bool_op_classes = _bool_operators_from_module(self._parser_module) + self._bin_op_classes = _binary_operators_from_module(self._parser_module) + self._context_classes = _contexts_from_module(self._parser_module) + + def _get_doc(self, node): + try: + if PY37 and hasattr(node, "docstring"): + doc = node.docstring + return node, doc + if ( + node.body + and isinstance(node.body[0], self._parser_module.Expr) + and isinstance(node.body[0].value, self._parser_module.Str) + ): + doc = node.body[0].value.s + node.body = node.body[1:] + return node, doc + except IndexError: + pass # ast built from scratch + return node, None + + def _get_context(self, node): + return self._context_classes.get(type(node.ctx), astroid.Load) + + def visit_module(self, node, modname, modpath, package): + """visit a Module node by returning a fresh instance of it""" + node, doc = self._get_doc(node) + newnode = nodes.Module( + name=modname, + doc=doc, + file=modpath, + path=[modpath], + package=package, + parent=None, + ) + newnode.postinit([self.visit(child, newnode) for child in node.body]) + return newnode + + def visit(self, node, parent): + cls = node.__class__ + if cls in self._visit_meths: + visit_method = self._visit_meths[cls] + else: + cls_name = cls.__name__ + visit_name = "visit_" + REDIRECT.get(cls_name, cls_name).lower() + visit_method = getattr(self, visit_name) + self._visit_meths[cls] = visit_method + return visit_method(node, parent) + + def _save_assignment(self, node, name=None): + """save assignement situation since node.parent is not available yet""" + if self._global_names and node.name in self._global_names[-1]: + node.root().set_local(node.name, node) + else: + node.parent.set_local(node.name, node) + + def visit_arguments(self, node, parent): + """visit an Arguments node by returning a fresh instance of it""" + vararg, kwarg = node.vararg, node.kwarg + if PY34: + newnode = nodes.Arguments( + vararg.arg if vararg else None, kwarg.arg if kwarg else None, parent + ) + else: + newnode = nodes.Arguments(vararg, kwarg, parent) + args = [self.visit(child, newnode) for child in node.args] + defaults = [self.visit(child, newnode) for child in node.defaults] + varargannotation = None + kwargannotation = None + # change added in 82732 (7c5c678e4164), vararg and kwarg + # are instances of `_ast.arg`, not strings + if vararg: + if PY34: + if node.vararg.annotation: + varargannotation = self.visit(node.vararg.annotation, newnode) + vararg = vararg.arg + if kwarg: + if PY34: + if node.kwarg.annotation: + kwargannotation = self.visit(node.kwarg.annotation, newnode) + kwarg = kwarg.arg + if PY3: + kwonlyargs = [self.visit(child, newnode) for child in node.kwonlyargs] + kw_defaults = [ + self.visit(child, newnode) if child else None + for child in node.kw_defaults + ] + annotations = [ + self.visit(arg.annotation, newnode) if arg.annotation else None + for arg in node.args + ] + kwonlyargs_annotations = [ + self.visit(arg.annotation, newnode) if arg.annotation else None + for arg in node.kwonlyargs + ] + else: + kwonlyargs = [] + kw_defaults = [] + annotations = [] + kwonlyargs_annotations = [] + + newnode.postinit( + args=args, + defaults=defaults, + kwonlyargs=kwonlyargs, + kw_defaults=kw_defaults, + annotations=annotations, + kwonlyargs_annotations=kwonlyargs_annotations, + varargannotation=varargannotation, + kwargannotation=kwargannotation, + ) + # save argument names in locals: + if vararg: + newnode.parent.set_local(vararg, newnode) + if kwarg: + newnode.parent.set_local(kwarg, newnode) + return newnode + + def visit_assert(self, node, parent): + """visit a Assert node by returning a fresh instance of it""" + newnode = nodes.Assert(node.lineno, node.col_offset, parent) + if node.msg: + msg = self.visit(node.msg, newnode) + else: + msg = None + newnode.postinit(self.visit(node.test, newnode), msg) + return newnode + + def check_type_comment(self, node): + type_comment = getattr(node, "type_comment", None) + if not type_comment: + return None + + try: + type_comment_ast = _parse(type_comment) + except SyntaxError: + # Invalid type comment, just skip it. + return None + + type_object = self.visit(type_comment_ast.body[0], node) + if not isinstance(type_object, nodes.Expr): + return None + + return type_object.value + + def check_function_type_comment(self, node): + type_comment = getattr(node, "type_comment", None) + if not type_comment: + return None + + try: + type_comment_ast = parse_function_type_comment(type_comment) + except SyntaxError: + # Invalid type comment, just skip it. + return None + + returns = None + argtypes = [ + self.visit(elem, node) for elem in (type_comment_ast.argtypes or []) + ] + if type_comment_ast.returns: + returns = self.visit(type_comment_ast.returns, node) + + return returns, argtypes + + def visit_assign(self, node, parent): + """visit a Assign node by returning a fresh instance of it""" + type_annotation = self.check_type_comment(node) + newnode = nodes.Assign(node.lineno, node.col_offset, parent) + newnode.postinit( + targets=[self.visit(child, newnode) for child in node.targets], + value=self.visit(node.value, newnode), + type_annotation=type_annotation, + ) + return newnode + + def visit_assignname(self, node, parent, node_name=None): + """visit a node and return a AssignName node""" + newnode = nodes.AssignName( + node_name, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + self._save_assignment(newnode) + return newnode + + def visit_augassign(self, node, parent): + """visit a AugAssign node by returning a fresh instance of it""" + newnode = nodes.AugAssign( + self._bin_op_classes[type(node.op)] + "=", + node.lineno, + node.col_offset, + parent, + ) + newnode.postinit( + self.visit(node.target, newnode), self.visit(node.value, newnode) + ) + return newnode + + def visit_repr(self, node, parent): + """visit a Backquote node by returning a fresh instance of it""" + newnode = nodes.Repr(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_binop(self, node, parent): + """visit a BinOp node by returning a fresh instance of it""" + newnode = nodes.BinOp( + self._bin_op_classes[type(node.op)], node.lineno, node.col_offset, parent + ) + newnode.postinit( + self.visit(node.left, newnode), self.visit(node.right, newnode) + ) + return newnode + + def visit_boolop(self, node, parent): + """visit a BoolOp node by returning a fresh instance of it""" + newnode = nodes.BoolOp( + self._bool_op_classes[type(node.op)], node.lineno, node.col_offset, parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.values]) + return newnode + + def visit_break(self, node, parent): + """visit a Break node by returning a fresh instance of it""" + return nodes.Break( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_call(self, node, parent): + """visit a CallFunc node by returning a fresh instance of it""" + newnode = nodes.Call(node.lineno, node.col_offset, parent) + starargs = _visit_or_none(node, "starargs", self, newnode) + kwargs = _visit_or_none(node, "kwargs", self, newnode) + args = [self.visit(child, newnode) for child in node.args] + + if node.keywords: + keywords = [self.visit(child, newnode) for child in node.keywords] + else: + keywords = None + if starargs: + new_starargs = nodes.Starred( + col_offset=starargs.col_offset, + lineno=starargs.lineno, + parent=starargs.parent, + ) + new_starargs.postinit(value=starargs) + args.append(new_starargs) + if kwargs: + new_kwargs = nodes.Keyword( + arg=None, + col_offset=kwargs.col_offset, + lineno=kwargs.lineno, + parent=kwargs.parent, + ) + new_kwargs.postinit(value=kwargs) + if keywords: + keywords.append(new_kwargs) + else: + keywords = [new_kwargs] + + newnode.postinit(self.visit(node.func, newnode), args, keywords) + return newnode + + def visit_classdef(self, node, parent, newstyle=None): + """visit a ClassDef node to become astroid""" + node, doc = self._get_doc(node) + newnode = nodes.ClassDef(node.name, doc, node.lineno, node.col_offset, parent) + metaclass = None + if PY3: + for keyword in node.keywords: + if keyword.arg == "metaclass": + metaclass = self.visit(keyword, newnode).value + break + if node.decorator_list: + decorators = self.visit_decorators(node, newnode) + else: + decorators = None + newnode.postinit( + [self.visit(child, newnode) for child in node.bases], + [self.visit(child, newnode) for child in node.body], + decorators, + newstyle, + metaclass, + [ + self.visit(kwd, newnode) + for kwd in node.keywords + if kwd.arg != "metaclass" + ] + if PY3 + else [], + ) + return newnode + + def visit_const(self, node, parent): + """visit a Const node by returning a fresh instance of it""" + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_continue(self, node, parent): + """visit a Continue node by returning a fresh instance of it""" + return nodes.Continue( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_compare(self, node, parent): + """visit a Compare node by returning a fresh instance of it""" + newnode = nodes.Compare(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.left, newnode), + [ + (self._cmp_op_classes[op.__class__], self.visit(expr, newnode)) + for (op, expr) in zip(node.ops, node.comparators) + ], + ) + return newnode + + def visit_comprehension(self, node, parent): + """visit a Comprehension node by returning a fresh instance of it""" + newnode = nodes.Comprehension(parent) + newnode.postinit( + self.visit(node.target, newnode), + self.visit(node.iter, newnode), + [self.visit(child, newnode) for child in node.ifs], + getattr(node, "is_async", None), + ) + return newnode + + def visit_decorators(self, node, parent): + """visit a Decorators node by returning a fresh instance of it""" + # /!\ node is actually a _ast.FunctionDef node while + # parent is an astroid.nodes.FunctionDef node + newnode = nodes.Decorators(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.decorator_list]) + return newnode + + def visit_delete(self, node, parent): + """visit a Delete node by returning a fresh instance of it""" + newnode = nodes.Delete(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.targets]) + return newnode + + def _visit_dict_items(self, node, parent, newnode): + for key, value in zip(node.keys, node.values): + rebuilt_value = self.visit(value, newnode) + if not key: + # Python 3.5 and extended unpacking + rebuilt_key = nodes.DictUnpack( + rebuilt_value.lineno, rebuilt_value.col_offset, parent + ) + else: + rebuilt_key = self.visit(key, newnode) + yield rebuilt_key, rebuilt_value + + def visit_dict(self, node, parent): + """visit a Dict node by returning a fresh instance of it""" + newnode = nodes.Dict(node.lineno, node.col_offset, parent) + items = list(self._visit_dict_items(node, parent, newnode)) + newnode.postinit(items) + return newnode + + def visit_dictcomp(self, node, parent): + """visit a DictComp node by returning a fresh instance of it""" + newnode = nodes.DictComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.key, newnode), + self.visit(node.value, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_expr(self, node, parent): + """visit a Expr node by returning a fresh instance of it""" + newnode = nodes.Expr(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + # Not used in Python 3.8+. + def visit_ellipsis(self, node, parent): + """visit an Ellipsis node by returning a fresh instance of it""" + return nodes.Ellipsis( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_emptynode(self, node, parent): + """visit an EmptyNode node by returning a fresh instance of it""" + return nodes.EmptyNode( + getattr(node, "lineno", None), getattr(node, "col_offset", None), parent + ) + + def visit_excepthandler(self, node, parent): + """visit an ExceptHandler node by returning a fresh instance of it""" + newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent) + # /!\ node.name can be a tuple + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + _visit_or_none(node, "name", self, newnode), + [self.visit(child, newnode) for child in node.body], + ) + return newnode + + def visit_exec(self, node, parent): + """visit an Exec node by returning a fresh instance of it""" + newnode = nodes.Exec(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.body, newnode), + _visit_or_none(node, "globals", self, newnode), + _visit_or_none(node, "locals", self, newnode), + ) + return newnode + + # Not used in Python 3.8+. + def visit_extslice(self, node, parent): + """visit an ExtSlice node by returning a fresh instance of it""" + newnode = nodes.ExtSlice(parent=parent) + newnode.postinit([self.visit(dim, newnode) for dim in node.dims]) + return newnode + + def _visit_for(self, cls, node, parent): + """visit a For node by returning a fresh instance of it""" + newnode = cls(node.lineno, node.col_offset, parent) + type_annotation = self.check_type_comment(node) + newnode.postinit( + target=self.visit(node.target, newnode), + iter=self.visit(node.iter, newnode), + body=[self.visit(child, newnode) for child in node.body], + orelse=[self.visit(child, newnode) for child in node.orelse], + type_annotation=type_annotation, + ) + return newnode + + def visit_for(self, node, parent): + return self._visit_for(nodes.For, node, parent) + + def visit_importfrom(self, node, parent): + """visit an ImportFrom node by returning a fresh instance of it""" + names = [(alias.name, alias.asname) for alias in node.names] + newnode = nodes.ImportFrom( + node.module or "", + names, + node.level or None, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + # store From names to add them to locals after building + self._import_from_nodes.append(newnode) + return newnode + + def _visit_functiondef(self, cls, node, parent): + """visit an FunctionDef node to become astroid""" + self._global_names.append({}) + node, doc = self._get_doc(node) + newnode = cls(node.name, doc, node.lineno, node.col_offset, parent) + if node.decorator_list: + decorators = self.visit_decorators(node, newnode) + else: + decorators = None + if PY3 and node.returns: + returns = self.visit(node.returns, newnode) + else: + returns = None + + type_comment_args = type_comment_returns = None + type_comment_annotation = self.check_function_type_comment(node) + if type_comment_annotation: + type_comment_returns, type_comment_args = type_comment_annotation + newnode.postinit( + args=self.visit(node.args, newnode), + body=[self.visit(child, newnode) for child in node.body], + decorators=decorators, + returns=returns, + type_comment_returns=type_comment_returns, + type_comment_args=type_comment_args, + ) + self._global_names.pop() + return newnode + + def visit_functiondef(self, node, parent): + return self._visit_functiondef(nodes.FunctionDef, node, parent) + + def visit_generatorexp(self, node, parent): + """visit a GeneratorExp node by returning a fresh instance of it""" + newnode = nodes.GeneratorExp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_attribute(self, node, parent): + """visit an Attribute node by returning a fresh instance of it""" + context = self._get_context(node) + if context == astroid.Del: + # FIXME : maybe we should reintroduce and visit_delattr ? + # for instance, deactivating assign_ctx + newnode = nodes.DelAttr(node.attr, node.lineno, node.col_offset, parent) + elif context == astroid.Store: + newnode = nodes.AssignAttr(node.attr, node.lineno, node.col_offset, parent) + # Prohibit a local save if we are in an ExceptHandler. + if not isinstance(parent, astroid.ExceptHandler): + self._delayed_assattr.append(newnode) + else: + newnode = nodes.Attribute(node.attr, node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_global(self, node, parent): + """visit a Global node to become astroid""" + newnode = nodes.Global( + node.names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + if self._global_names: # global at the module level, no effect + for name in node.names: + self._global_names[-1].setdefault(name, []).append(newnode) + return newnode + + def visit_if(self, node, parent): + """visit an If node by returning a fresh instance of it""" + newnode = nodes.If(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_ifexp(self, node, parent): + """visit a IfExp node by returning a fresh instance of it""" + newnode = nodes.IfExp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + self.visit(node.body, newnode), + self.visit(node.orelse, newnode), + ) + return newnode + + def visit_import(self, node, parent): + """visit a Import node by returning a fresh instance of it""" + names = [(alias.name, alias.asname) for alias in node.names] + newnode = nodes.Import( + names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + # save import names in parent's locals: + for (name, asname) in newnode.names: + name = asname or name + parent.set_local(name.split(".")[0], newnode) + return newnode + + # Not used in Python 3.8+. + def visit_index(self, node, parent): + """visit a Index node by returning a fresh instance of it""" + newnode = nodes.Index(parent=parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_keyword(self, node, parent): + """visit a Keyword node by returning a fresh instance of it""" + newnode = nodes.Keyword(node.arg, parent=parent) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_lambda(self, node, parent): + """visit a Lambda node by returning a fresh instance of it""" + newnode = nodes.Lambda(node.lineno, node.col_offset, parent) + newnode.postinit(self.visit(node.args, newnode), self.visit(node.body, newnode)) + return newnode + + def visit_list(self, node, parent): + """visit a List node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.List( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_listcomp(self, node, parent): + """visit a ListComp node by returning a fresh instance of it""" + newnode = nodes.ListComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_name(self, node, parent): + """visit a Name node by returning a fresh instance of it""" + context = self._get_context(node) + # True and False can be assigned to something in py2x, so we have to + # check first the context. + if context == astroid.Del: + newnode = nodes.DelName(node.id, node.lineno, node.col_offset, parent) + elif context == astroid.Store: + newnode = nodes.AssignName(node.id, node.lineno, node.col_offset, parent) + elif node.id in CONST_NAME_TRANSFORMS: + newnode = nodes.Const( + CONST_NAME_TRANSFORMS[node.id], + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + return newnode + else: + newnode = nodes.Name(node.id, node.lineno, node.col_offset, parent) + # XXX REMOVE me : + if context in (astroid.Del, astroid.Store): # 'Aug' ?? + self._save_assignment(newnode) + return newnode + + def visit_constant(self, node, parent): + """visit a Constant node by returning a fresh instance of Const""" + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + # Not used in Python 3.8+. + def visit_str(self, node, parent): + """visit a String/Bytes node by returning a fresh instance of Const""" + return nodes.Const( + node.s, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + visit_bytes = visit_str + + # Not used in Python 3.8+. + def visit_num(self, node, parent): + """visit a Num node by returning a fresh instance of Const""" + return nodes.Const( + node.n, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_pass(self, node, parent): + """visit a Pass node by returning a fresh instance of it""" + return nodes.Pass(node.lineno, node.col_offset, parent) + + def visit_print(self, node, parent): + """visit a Print node by returning a fresh instance of it""" + newnode = nodes.Print(node.nl, node.lineno, node.col_offset, parent) + newnode.postinit( + _visit_or_none(node, "dest", self, newnode), + [self.visit(child, newnode) for child in node.values], + ) + return newnode + + def visit_raise(self, node, parent): + """visit a Raise node by returning a fresh instance of it""" + newnode = nodes.Raise(node.lineno, node.col_offset, parent) + # pylint: disable=too-many-function-args + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + _visit_or_none(node, "inst", self, newnode), + _visit_or_none(node, "tback", self, newnode), + ) + return newnode + + def visit_return(self, node, parent): + """visit a Return node by returning a fresh instance of it""" + newnode = nodes.Return(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_set(self, node, parent): + """visit a Set node by returning a fresh instance of it""" + newnode = nodes.Set(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_setcomp(self, node, parent): + """visit a SetComp node by returning a fresh instance of it""" + newnode = nodes.SetComp(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.elt, newnode), + [self.visit(child, newnode) for child in node.generators], + ) + return newnode + + def visit_slice(self, node, parent): + """visit a Slice node by returning a fresh instance of it""" + newnode = nodes.Slice(parent=parent) + newnode.postinit( + _visit_or_none(node, "lower", self, newnode), + _visit_or_none(node, "upper", self, newnode), + _visit_or_none(node, "step", self, newnode), + ) + return newnode + + def visit_subscript(self, node, parent): + """visit a Subscript node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.Subscript( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit( + self.visit(node.value, newnode), self.visit(node.slice, newnode) + ) + return newnode + + def visit_tryexcept(self, node, parent): + """visit a TryExcept node by returning a fresh instance of it""" + newnode = nodes.TryExcept(node.lineno, node.col_offset, parent) + newnode.postinit( + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.handlers], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_tryfinally(self, node, parent): + """visit a TryFinally node by returning a fresh instance of it""" + newnode = nodes.TryFinally(node.lineno, node.col_offset, parent) + newnode.postinit( + [self.visit(child, newnode) for child in node.body], + [self.visit(n, newnode) for n in node.finalbody], + ) + return newnode + + def visit_tuple(self, node, parent): + """visit a Tuple node by returning a fresh instance of it""" + context = self._get_context(node) + newnode = nodes.Tuple( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit([self.visit(child, newnode) for child in node.elts]) + return newnode + + def visit_unaryop(self, node, parent): + """visit a UnaryOp node by returning a fresh instance of it""" + newnode = nodes.UnaryOp( + self._unary_op_classes[node.op.__class__], + node.lineno, + node.col_offset, + parent, + ) + newnode.postinit(self.visit(node.operand, newnode)) + return newnode + + def visit_while(self, node, parent): + """visit a While node by returning a fresh instance of it""" + newnode = nodes.While(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.test, newnode), + [self.visit(child, newnode) for child in node.body], + [self.visit(child, newnode) for child in node.orelse], + ) + return newnode + + def visit_with(self, node, parent): + newnode = nodes.With(node.lineno, node.col_offset, parent) + expr = self.visit(node.context_expr, newnode) + if node.optional_vars is not None: + optional_vars = self.visit(node.optional_vars, newnode) + else: + optional_vars = None + + type_annotation = self.check_type_comment(node) + newnode.postinit( + items=[(expr, optional_vars)], + body=[self.visit(child, newnode) for child in node.body], + type_annotation=type_annotation, + ) + return newnode + + def visit_yield(self, node, parent): + """visit a Yield node by returning a fresh instance of it""" + newnode = nodes.Yield(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + +class TreeRebuilder3(TreeRebuilder): + """extend and overwrite TreeRebuilder for python3k""" + + def visit_arg(self, node, parent): + """visit an arg node by returning a fresh AssName instance""" + return self.visit_assignname(node, parent, node.arg) + + # Not used in Python 3.8+. + def visit_nameconstant(self, node, parent): + # in Python 3.4 we have NameConstant for True / False / None + return nodes.Const( + node.value, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_excepthandler(self, node, parent): + """visit an ExceptHandler node by returning a fresh instance of it""" + newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent) + if node.name: + name = self.visit_assignname(node, newnode, node.name) + else: + name = None + newnode.postinit( + _visit_or_none(node, "type", self, newnode), + name, + [self.visit(child, newnode) for child in node.body], + ) + return newnode + + def visit_nonlocal(self, node, parent): + """visit a Nonlocal node and return a new instance of it""" + return nodes.Nonlocal( + node.names, + getattr(node, "lineno", None), + getattr(node, "col_offset", None), + parent, + ) + + def visit_raise(self, node, parent): + """visit a Raise node by returning a fresh instance of it""" + newnode = nodes.Raise(node.lineno, node.col_offset, parent) + # no traceback; anyway it is not used in Pylint + newnode.postinit( + _visit_or_none(node, "exc", self, newnode), + _visit_or_none(node, "cause", self, newnode), + ) + return newnode + + def visit_starred(self, node, parent): + """visit a Starred node and return a new instance of it""" + context = self._get_context(node) + newnode = nodes.Starred( + ctx=context, lineno=node.lineno, col_offset=node.col_offset, parent=parent + ) + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_try(self, node, parent): + # python 3.3 introduce a new Try node replacing + # TryFinally/TryExcept nodes + if node.finalbody: + newnode = nodes.TryFinally(node.lineno, node.col_offset, parent) + if node.handlers: + body = [self.visit_tryexcept(node, newnode)] + else: + body = [self.visit(child, newnode) for child in node.body] + newnode.postinit(body, [self.visit(n, newnode) for n in node.finalbody]) + return newnode + elif node.handlers: + return self.visit_tryexcept(node, parent) + return None + + def visit_annassign(self, node, parent): + """visit an AnnAssign node by returning a fresh instance of it""" + newnode = nodes.AnnAssign(node.lineno, node.col_offset, parent) + annotation = _visit_or_none(node, "annotation", self, newnode) + newnode.postinit( + target=self.visit(node.target, newnode), + annotation=annotation, + simple=node.simple, + value=_visit_or_none(node, "value", self, newnode), + ) + return newnode + + def _visit_with(self, cls, node, parent): + if "items" not in node._fields: + # python < 3.3 + return super(TreeRebuilder3, self).visit_with(node, parent) + + newnode = cls(node.lineno, node.col_offset, parent) + + def visit_child(child): + expr = self.visit(child.context_expr, newnode) + var = _visit_or_none(child, "optional_vars", self, newnode) + return expr, var + + type_annotation = self.check_type_comment(node) + newnode.postinit( + items=[visit_child(child) for child in node.items], + body=[self.visit(child, newnode) for child in node.body], + type_annotation=type_annotation, + ) + return newnode + + def visit_with(self, node, parent): + return self._visit_with(nodes.With, node, parent) + + def visit_yieldfrom(self, node, parent): + newnode = nodes.YieldFrom(node.lineno, node.col_offset, parent) + if node.value is not None: + newnode.postinit(self.visit(node.value, newnode)) + return newnode + + def visit_classdef(self, node, parent, newstyle=True): + return super(TreeRebuilder3, self).visit_classdef( + node, parent, newstyle=newstyle + ) + + # Async structs added in Python 3.5 + def visit_asyncfunctiondef(self, node, parent): + return self._visit_functiondef(nodes.AsyncFunctionDef, node, parent) + + def visit_asyncfor(self, node, parent): + return self._visit_for(nodes.AsyncFor, node, parent) + + def visit_await(self, node, parent): + newnode = nodes.Await(node.lineno, node.col_offset, parent) + newnode.postinit(value=self.visit(node.value, newnode)) + return newnode + + def visit_asyncwith(self, node, parent): + return self._visit_with(nodes.AsyncWith, node, parent) + + def visit_joinedstr(self, node, parent): + newnode = nodes.JoinedStr(node.lineno, node.col_offset, parent) + newnode.postinit([self.visit(child, newnode) for child in node.values]) + return newnode + + def visit_formattedvalue(self, node, parent): + newnode = nodes.FormattedValue(node.lineno, node.col_offset, parent) + newnode.postinit( + self.visit(node.value, newnode), + node.conversion, + _visit_or_none(node, "format_spec", self, newnode), + ) + return newnode + + +if sys.version_info >= (3, 0): + TreeRebuilder = TreeRebuilder3 diff --git a/basic python programmes/venv/Lib/site-packages/astroid/scoped_nodes.py b/basic python programmes/venv/Lib/site-packages/astroid/scoped_nodes.py new file mode 100644 index 0000000..6e580d5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/scoped_nodes.py @@ -0,0 +1,2804 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2010 Daniel Harding +# Copyright (c) 2011, 2013-2015 Google, Inc. +# Copyright (c) 2013-2018 Claudiu Popa +# Copyright (c) 2013 Phil Schaf +# Copyright (c) 2014 Eevee (Alex Munroe) +# Copyright (c) 2015-2016 Florian Bruhin +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2015 Rene Zhang +# Copyright (c) 2015 Philip Lorenz +# Copyright (c) 2016-2017 Derek Gustafson +# Copyright (c) 2017-2018 Bryce Guinta +# Copyright (c) 2017-2018 Ashley Whetter +# Copyright (c) 2017 Łukasz Rogalski +# Copyright (c) 2017 David Euresti +# Copyright (c) 2018 Nick Drozd +# Copyright (c) 2018 Anthony Sottile +# Copyright (c) 2018 HoverHell + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +""" +This module contains the classes for "scoped" node, i.e. which are opening a +new local scope in the language definition : Module, ClassDef, FunctionDef (and +Lambda, GeneratorExp, DictComp and SetComp to some extent). +""" + +import builtins +import sys +import io +import itertools +from typing import Optional, List + +from astroid import bases +from astroid import context as contextmod +from astroid import exceptions +from astroid import decorators as decorators_mod +from astroid.interpreter import objectmodel +from astroid.interpreter import dunder_lookup +from astroid import manager +from astroid import mixins +from astroid import node_classes +from astroid import util + + +BUILTINS = builtins.__name__ +ITER_METHODS = ("__iter__", "__getitem__") + + +def _c3_merge(sequences, cls, context): + """Merges MROs in *sequences* to a single MRO using the C3 algorithm. + + Adapted from http://www.python.org/download/releases/2.3/mro/. + + """ + result = [] + while True: + sequences = [s for s in sequences if s] # purge empty sequences + if not sequences: + return result + for s1 in sequences: # find merge candidates among seq heads + candidate = s1[0] + for s2 in sequences: + if candidate in s2[1:]: + candidate = None + break # reject the current head, it appears later + else: + break + if not candidate: + # Show all the remaining bases, which were considered as + # candidates for the next mro sequence. + raise exceptions.InconsistentMroError( + message="Cannot create a consistent method resolution order " + "for MROs {mros} of class {cls!r}.", + mros=sequences, + cls=cls, + context=context, + ) + + result.append(candidate) + # remove the chosen candidate + for seq in sequences: + if seq[0] == candidate: + del seq[0] + return None + + +def _verify_duplicates_mro(sequences, cls, context): + for sequence in sequences: + names = [(node.lineno, node.qname()) for node in sequence if node.name] + if len(names) != len(set(names)): + raise exceptions.DuplicateBasesError( + message="Duplicates found in MROs {mros} for {cls!r}.", + mros=sequences, + cls=cls, + context=context, + ) + + +def function_to_method(n, klass): + if isinstance(n, FunctionDef): + if n.type == "classmethod": + return bases.BoundMethod(n, klass) + if n.type != "staticmethod": + return bases.UnboundMethod(n) + return n + + +MANAGER = manager.AstroidManager() + + +def builtin_lookup(name): + """lookup a name into the builtin module + return the list of matching statements and the astroid for the builtin + module + """ + builtin_astroid = MANAGER.ast_from_module(builtins) + if name == "__dict__": + return builtin_astroid, () + try: + stmts = builtin_astroid.locals[name] + except KeyError: + stmts = () + return builtin_astroid, stmts + + +# TODO move this Mixin to mixins.py; problem: 'FunctionDef' in _scope_lookup +class LocalsDictNodeNG(node_classes.LookupMixIn, node_classes.NodeNG): + """ this class provides locals handling common to Module, FunctionDef + and ClassDef nodes, including a dict like interface for direct access + to locals information + """ + + # attributes below are set by the builder module or by raw factories + + locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + def qname(self): + """Get the 'qualified' name of the node. + + For example: module.name, module.class.name ... + + :returns: The qualified name. + :rtype: str + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/278 + if self.parent is None: + return self.name + return "%s.%s" % (self.parent.frame().qname(), self.name) + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self + + def scope(self): + """The first parent node defining a new scope. + + :returns: The first parent scope node. + :rtype: Module or FunctionDef or ClassDef or Lambda or GenExpr + """ + return self + + def _scope_lookup(self, node, name, offset=0): + """XXX method for interfacing the scope lookup""" + try: + stmts = node._filter_stmts(self.locals[name], self, offset) + except KeyError: + stmts = () + if stmts: + return self, stmts + if self.parent: # i.e. not Module + # nested scope: if parent scope is a function, that's fine + # else jump to the module + pscope = self.parent.scope() + if not pscope.is_function: + pscope = pscope.root() + return pscope.scope_lookup(node, name) + return builtin_lookup(name) # Module + + def set_local(self, name, stmt): + """Define that the given name is declared in the given statement node. + + .. seealso:: :meth:`scope` + + :param name: The name that is being defined. + :type name: str + + :param stmt: The statement that defines the given name. + :type stmt: NodeNG + """ + # assert not stmt in self.locals.get(name, ()), (self, stmt) + self.locals.setdefault(name, []).append(stmt) + + __setitem__ = set_local + + def _append_node(self, child): + """append a child, linking it in the tree""" + # pylint: disable=no-member; depending by the class + # which uses the current class as a mixin or base class. + # It's rewritten in 2.0, so it makes no sense for now + # to spend development time on it. + self.body.append(child) + child.parent = self + + def add_local_node(self, child_node, name=None): + """Append a child that should alter the locals of this scope node. + + :param child_node: The child node that will alter locals. + :type child_node: NodeNG + + :param name: The name of the local that will be altered by + the given child node. + :type name: str or None + """ + if name != "__class__": + # add __class__ node as a child will cause infinite recursion later! + self._append_node(child_node) + self.set_local(name or child_node.name, child_node) + + def __getitem__(self, item): + """The first node the defines the given local. + + :param item: The name of the locally defined object. + :type item: str + + :raises KeyError: If the name is not defined. + """ + return self.locals[item][0] + + def __iter__(self): + """Iterate over the names of locals defined in this scoped node. + + :returns: The names of the defined locals. + :rtype: iterable(str) + """ + return iter(self.keys()) + + def keys(self): + """The names of locals defined in this scoped node. + + :returns: The names of the defined locals. + :rtype: list(str) + """ + return list(self.locals.keys()) + + def values(self): + """The nodes that define the locals in this scoped node. + + :returns: The nodes that define locals. + :rtype: list(NodeNG) + """ + return [self[key] for key in self.keys()] + + def items(self): + """Get the names of the locals and the node that defines the local. + + :returns: The names of locals and their associated node. + :rtype: list(tuple(str, NodeNG)) + """ + return list(zip(self.keys(), self.values())) + + def __contains__(self, name): + """Check if a local is defined in this scope. + + :param name: The name of the local to check for. + :type name: str + + :returns: True if this node has a local of the given name, + False otherwise. + :rtype: bool + """ + return name in self.locals + + +class Module(LocalsDictNodeNG): + """Class representing an :class:`ast.Module` node. + + >>> node = astroid.extract_node('import astroid') + >>> node + + >>> node.parent + + """ + + _astroid_fields = ("body",) + + fromlineno = 0 + """The first line that this node appears on in the source code. + + :type: int or None + """ + lineno = 0 + """The line that this node appears on in the source code. + + :type: int or None + """ + + # attributes below are set by the builder module or by raw factories + + file = None + """The path to the file that this ast has been extracted from. + + This will be ``None`` when the representation has been built from a + built-in module. + + :type: str or None + """ + file_bytes = None + """The string/bytes that this ast was built from. + + :type: str or bytes or None + """ + file_encoding = None + """The encoding of the source file. + + This is used to get unicode out of a source file. + Python 2 only. + + :type: str or None + """ + name = None + """The name of the module. + + :type: str or None + """ + pure_python = None + """Whether the ast was built from source. + + :type: bool or None + """ + package = None + """Whether the node represents a package or a module. + + :type: bool or None + """ + globals = None + """A map of the name of a global variable to the node defining the global. + + :type: dict(str, NodeNG) + """ + + # Future imports + future_imports = None + """The imports from ``__future__``. + + :type: set(str) or None + """ + special_attributes = objectmodel.ModuleModel() + """The names of special attributes that this module has. + + :type: objectmodel.ModuleModel + """ + + # names of module attributes available through the global scope + scope_attrs = {"__name__", "__doc__", "__file__", "__path__", "__package__"} + """The names of module attributes available through the global scope. + + :type: str(str) + """ + + _other_fields = ( + "name", + "doc", + "file", + "path", + "package", + "pure_python", + "future_imports", + ) + _other_other_fields = ("locals", "globals") + + def __init__( + self, + name, + doc, + file=None, + path: Optional[List[str]] = None, + package=None, + parent=None, + pure_python=True, + ): + """ + :param name: The name of the module. + :type name: str + + :param doc: The module docstring. + :type doc: str + + :param file: The path to the file that this ast has been extracted from. + :type file: str or None + + :param path: + :type path: Optional[List[str]] + + :param package: Whether the node represents a package or a module. + :type package: bool or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + + :param pure_python: Whether the ast was built from source. + :type pure_python: bool or None + """ + self.name = name + self.doc = doc + self.file = file + self.path = path + self.package = package + self.parent = parent + self.pure_python = pure_python + self.locals = self.globals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + self.body = [] + """The contents of the module. + + :type: list(NodeNG) or None + """ + self.future_imports = set() + + # pylint: enable=redefined-builtin + + def postinit(self, body=None): + """Do some setup after initialisation. + + :param body: The contents of the module. + :type body: list(NodeNG) or None + """ + self.body = body + + def _get_stream(self): + if self.file_bytes is not None: + return io.BytesIO(self.file_bytes) + if self.file is not None: + stream = open(self.file, "rb") + return stream + return None + + def stream(self): + """Get a stream to the underlying file or bytes. + + :type: file or io.BytesIO or None + """ + return self._get_stream() + + def block_range(self, lineno): + """Get a range from where this node starts to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to. + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given variable is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name of the variable to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + if name in self.scope_attrs and name not in self.locals: + try: + return self, self.getattr(name) + except exceptions.AttributeInferenceError: + return self, () + return self._scope_lookup(node, name, offset) + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + return "%s.module" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + return "Module" + + def getattr(self, name, context=None, ignore_locals=False): + result = [] + name_in_locals = name in self.locals + + if name in self.special_attributes and not ignore_locals and not name_in_locals: + result = [self.special_attributes.lookup(name)] + elif not ignore_locals and name_in_locals: + result = self.locals[name] + elif self.package: + try: + result = [self.import_module(name, relative_only=True)] + except (exceptions.AstroidBuildingError, SyntaxError) as exc: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) from exc + result = [n for n in result if not isinstance(n, node_classes.DelName)] + if result: + return result + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def igetattr(self, name, context=None): + """Infer the possible values of the given variable. + + :param name: The name of the variable to infer. + :type name: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG) or None + """ + # set lookup name since this is necessary to infer on import nodes for + # instance + context = contextmod.copy_context(context) + context.lookupname = name + try: + return bases._infer_stmts(self.getattr(name, context), context, frame=self) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + def fully_defined(self): + """Check if this module has been build from a .py file. + + If so, the module contains a complete representation, + including the code. + + :returns: True if the module has been built from a .py file. + :rtype: bool + """ + return self.file is not None and self.file.endswith(".py") + + def statement(self): + """The first parent node, including self, marked as statement node. + + :returns: The first parent statement. + :rtype: NodeNG + """ + return self + + def previous_sibling(self): + """The previous sibling statement. + + :returns: The previous sibling statement node. + :rtype: NodeNG or None + """ + + def next_sibling(self): + """The next sibling statement node. + + :returns: The next sibling statement node. + :rtype: NodeNG or None + """ + + _absolute_import_activated = True + + def absolute_import_activated(self): + """Whether :pep:`328` absolute import behaviour has been enabled. + + :returns: True if :pep:`328` has been enabled, False otherwise. + :rtype: bool + """ + return self._absolute_import_activated + + def import_module(self, modname, relative_only=False, level=None): + """Get the ast for a given module as if imported from this module. + + :param modname: The name of the module to "import". + :type modname: str + + :param relative_only: Whether to only consider relative imports. + :type relative_only: bool + + :param level: The level of relative import. + :type level: int or None + + :returns: The imported module ast. + :rtype: NodeNG + """ + if relative_only and level is None: + level = 0 + absmodname = self.relative_to_absolute_name(modname, level) + + try: + return MANAGER.ast_from_module_name(absmodname) + except exceptions.AstroidBuildingError: + # we only want to import a sub module or package of this module, + # skip here + if relative_only: + raise + return MANAGER.ast_from_module_name(modname) + + def relative_to_absolute_name(self, modname, level): + """Get the absolute module name for a relative import. + + The relative import can be implicit or explicit. + + :param modname: The module name to convert. + :type modname: str + + :param level: The level of relative import. + :type level: int + + :returns: The absolute module name. + :rtype: str + + :raises TooManyLevelsError: When the relative import refers to a + module too far above this one. + """ + # XXX this returns non sens when called on an absolute import + # like 'pylint.checkers.astroid.utils' + # XXX doesn't return absolute name if self.name isn't absolute name + if self.absolute_import_activated() and level is None: + return modname + if level: + if self.package: + level = level - 1 + if level and self.name.count(".") < level: + raise exceptions.TooManyLevelsError(level=level, name=self.name) + + package_name = self.name.rsplit(".", level)[0] + elif self.package: + package_name = self.name + else: + package_name = self.name.rsplit(".", 1)[0] + + if package_name: + if not modname: + return package_name + return "%s.%s" % (package_name, modname) + return modname + + def wildcard_import_names(self): + """The list of imported names when this module is 'wildcard imported'. + + It doesn't include the '__builtins__' name which is added by the + current CPython implementation of wildcard imports. + + :returns: The list of imported names. + :rtype: list(str) + """ + # We separate the different steps of lookup in try/excepts + # to avoid catching too many Exceptions + default = [name for name in self.keys() if not name.startswith("_")] + try: + all_values = self["__all__"] + except KeyError: + return default + + try: + explicit = next(all_values.assigned_stmts()) + except exceptions.InferenceError: + return default + except AttributeError: + # not an assignment node + # XXX infer? + return default + + # Try our best to detect the exported name. + inferred = [] + try: + explicit = next(explicit.infer()) + except exceptions.InferenceError: + return default + if not isinstance(explicit, (node_classes.Tuple, node_classes.List)): + return default + + str_const = lambda node: ( + isinstance(node, node_classes.Const) and isinstance(node.value, str) + ) + for node in explicit.elts: + if str_const(node): + inferred.append(node.value) + else: + try: + inferred_node = next(node.infer()) + except exceptions.InferenceError: + continue + if str_const(inferred_node): + inferred.append(inferred_node.value) + return inferred + + def public_names(self): + """The list of the names that are publicly available in this module. + + :returns: The list of publc names. + :rtype: list(str) + """ + return [name for name in self.keys() if not name.startswith("_")] + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`Module` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield from self.body + + +class ComprehensionScope(LocalsDictNodeNG): + """Scoping for different types of comprehensions.""" + + def frame(self): + """The first parent frame node. + + A frame node is a :class:`Module`, :class:`FunctionDef`, + or :class:`ClassDef`. + + :returns: The first parent frame node. + :rtype: Module or FunctionDef or ClassDef + """ + return self.parent.frame() + + scope_lookup = LocalsDictNodeNG._scope_lookup + + +class GeneratorExp(ComprehensionScope): + """Class representing an :class:`ast.GeneratorExp` node. + + >>> node = astroid.extract_node('(thing for thing in things if thing)') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + _other_other_fields = ("locals",) + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(GeneratorExp, self).__init__(lineno, col_offset, parent) + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`GeneratorExp` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield self.elt + + yield from self.generators + + +class DictComp(ComprehensionScope): + """Class representing an :class:`ast.DictComp` node. + + >>> node = astroid.extract_node('{k:v for k, v in things if k > v}') + >>> node + + """ + + _astroid_fields = ("key", "value", "generators") + _other_other_fields = ("locals",) + key = None + """What produces the keys. + + :type: NodeNG or None + """ + value = None + """What produces the values. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(DictComp, self).__init__(lineno, col_offset, parent) + + def postinit(self, key=None, value=None, generators=None): + """Do some setup after initialisation. + + :param key: What produces the keys. + :type key: NodeNG or None + + :param value: What produces the values. + :type value: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.key = key + self.value = value + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`DictComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.key + yield self.value + + yield from self.generators + + +class SetComp(ComprehensionScope): + """Class representing an :class:`ast.SetComp` node. + + >>> node = astroid.extract_node('{thing for thing in things if thing}') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + _other_other_fields = ("locals",) + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining the local. + + :type: dict(str, NodeNG) + """ + + super(SetComp, self).__init__(lineno, col_offset, parent) + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + if generators is None: + self.generators = [] + else: + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`SetComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.elt + + yield from self.generators + + +class _ListComp(node_classes.NodeNG): + """Class representing an :class:`ast.ListComp` node. + + >>> node = astroid.extract_node('[thing for thing in things if thing]') + >>> node + + """ + + _astroid_fields = ("elt", "generators") + elt = None + """The element that forms the output of the expression. + + :type: NodeNG or None + """ + generators = None + """The generators that are looped through. + + :type: list(Comprehension) or None + """ + + def postinit(self, elt=None, generators=None): + """Do some setup after initialisation. + + :param elt: The element that forms the output of the expression. + :type elt: NodeNG or None + + :param generators: The generators that are looped through. + :type generators: list(Comprehension) or None + """ + self.elt = elt + self.generators = generators + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`ListComp` this is always :class:`Uninferable`. + :rtype: Uninferable + """ + return util.Uninferable + + def get_children(self): + yield self.elt + + yield from self.generators + + +class ListComp(_ListComp, ComprehensionScope): + """Class representing an :class:`ast.ListComp` node. + + >>> node = astroid.extract_node('[thing for thing in things if thing]') + >>> node + + """ + + _other_other_fields = ("locals",) + + def __init__(self, lineno=None, col_offset=None, parent=None): + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + super(ListComp, self).__init__(lineno, col_offset, parent) + + +def _infer_decorator_callchain(node): + """Detect decorator call chaining and see if the end result is a + static or a classmethod. + """ + if not isinstance(node, FunctionDef): + return None + if not node.parent: + return None + try: + result = next(node.infer_call_result(node.parent)) + except exceptions.InferenceError: + return None + if isinstance(result, bases.Instance): + result = result._proxied + if isinstance(result, ClassDef): + if result.is_subtype_of("%s.classmethod" % BUILTINS): + return "classmethod" + if result.is_subtype_of("%s.staticmethod" % BUILTINS): + return "staticmethod" + return None + + +class Lambda(mixins.FilterStmtsMixin, LocalsDictNodeNG): + """Class representing an :class:`ast.Lambda` node. + + >>> node = astroid.extract_node('lambda arg: arg + 1') + >>> node + l.1 at 0x7f23b2e41518> + """ + + _astroid_fields = ("args", "body") + _other_other_fields = ("locals",) + name = "" + is_lambda = True + + def implicit_parameters(self): + return 0 + + # function's type, 'function' | 'method' | 'staticmethod' | 'classmethod' + @property + def type(self): + """Whether this is a method or function. + + :returns: 'method' if this is a method, 'function' otherwise. + :rtype: str + """ + # pylint: disable=no-member + if self.args.args and self.args.args[0].name == "self": + if isinstance(self.parent.scope(), ClassDef): + return "method" + return "function" + + def __init__(self, lineno=None, col_offset=None, parent=None): + """ + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + self.args = [] + """The arguments that the function takes. + + :type: Arguments or list + """ + + self.body = [] + """The contents of the function body. + + :type: list(NodeNG) + """ + + super(Lambda, self).__init__(lineno, col_offset, parent) + + def postinit(self, args, body): + """Do some setup after initialisation. + + :param args: The arguments that the function takes. + :type args: Arguments + + :param body: The contents of the function body. + :type body: list(NodeNG) + """ + self.args = args + self.body = body + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + if "method" in self.type: + return "%s.instancemethod" % BUILTINS + return "%s.function" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + if "method" in self.type: + return "Method" + return "Function" + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + For a :class:`Lambda` this is always ``True``. + :rtype: bool + """ + return True + + def argnames(self): + """Get the names of each of the arguments. + + :returns: The names of the arguments. + :rtype: list(str) + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + + if self.args.args: # maybe None with builtin functions + names = _rec_get_names(self.args.args) + else: + names = [] + if self.args.vararg: + names.append(self.args.vararg) + if self.args.kwarg: + names.append(self.args.kwarg) + return names + + def infer_call_result(self, caller, context=None): + """Infer what the function returns when called. + + :param caller: Unused + :type caller: object + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + return self.body.infer(context) + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given names is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + # pylint: disable=no-member; github.com/pycqa/astroid/issues/291 + # args is in fact redefined later on by postinit. Can't be changed + # to None due to a strong interaction between Lambda and FunctionDef. + + if node in self.args.defaults or node in self.args.kw_defaults: + frame = self.parent.frame() + # line offset to avoid that def func(f=func) resolve the default + # value to the defined function + offset = -1 + else: + # check this is not used in function decorators + frame = self + return frame._scope_lookup(node, name, offset) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`Lambda` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + yield self.args + yield self.body + + +class FunctionDef(mixins.MultiLineBlockMixin, node_classes.Statement, Lambda): + """Class representing an :class:`ast.FunctionDef`. + + >>> node = astroid.extract_node(''' + ... def my_func(arg): + ... return arg + 1 + ... ''') + >>> node + + """ + + _astroid_fields = ("decorators", "args", "returns", "body") + _multi_line_block_fields = ("body",) + returns = None + decorators = None + """The decorators that are applied to this method or function. + + :type: Decorators or None + """ + special_attributes = objectmodel.FunctionModel() + """The names of special attributes that this function has. + + :type: objectmodel.FunctionModel + """ + is_function = True + """Whether this node indicates a function. + + For a :class:`FunctionDef` this is always ``True``. + + :type: bool + """ + type_annotation = None + """If present, this will contain the type annotation passed by a type comment + + :type: NodeNG or None + """ + type_comment_args = None + """ + If present, this will contain the type annotation for arguments + passed by a type comment + """ + type_comment_returns = None + """If present, this will contain the return type annotation, passed by a type comment""" + # attributes below are set by the builder module or by raw factories + _other_fields = ("name", "doc") + _other_other_fields = ( + "locals", + "_type", + "type_comment_returns", + "type_comment_args", + ) + _type = None + + def __init__(self, name=None, doc=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name of the function. + :type name: str or None + + :param doc: The function's docstring. + :type doc: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.name = name + """The name of the function. + + :type name: str or None + """ + + self.doc = doc + """The function's docstring. + + :type doc: str or None + """ + + self.instance_attrs = {} + super(FunctionDef, self).__init__(lineno, col_offset, parent) + if parent: + frame = parent.frame() + frame.set_local(name, self) + + # pylint: disable=arguments-differ; different than Lambdas + def postinit( + self, + args, + body, + decorators=None, + returns=None, + type_comment_returns=None, + type_comment_args=None, + ): + """Do some setup after initialisation. + + :param args: The arguments that the function takes. + :type args: Arguments or list + + :param body: The contents of the function body. + :type body: list(NodeNG) + + :param decorators: The decorators that are applied to this + method or function. + :type decorators: Decorators or None + :params type_comment_returns: + The return type annotation passed via a type comment. + :params type_comment_args: + The args type annotation passed via a type comment. + """ + self.args = args + self.body = body + self.decorators = decorators + self.returns = returns + self.type_comment_returns = type_comment_returns + self.type_comment_args = type_comment_args + + if isinstance(self.parent.frame(), ClassDef): + self.set_local("__class__", self.parent.frame()) + + @decorators_mod.cachedproperty + def extra_decorators(self): + """The extra decorators that this function can have. + + Additional decorators are considered when they are used as + assignments, as in ``method = staticmethod(method)``. + The property will return all the callables that are used for + decoration. + + :type: list(NodeNG) + """ + frame = self.parent.frame() + if not isinstance(frame, ClassDef): + return [] + + decorators = [] + for assign in frame._get_assign_nodes(): + if isinstance(assign.value, node_classes.Call) and isinstance( + assign.value.func, node_classes.Name + ): + for assign_node in assign.targets: + if not isinstance(assign_node, node_classes.AssignName): + # Support only `name = callable(name)` + continue + + if assign_node.name != self.name: + # Interested only in the assignment nodes that + # decorates the current method. + continue + try: + meth = frame[self.name] + except KeyError: + continue + else: + # Must be a function and in the same frame as the + # original method. + if ( + isinstance(meth, FunctionDef) + and assign_node.frame() == frame + ): + decorators.append(assign.value) + return decorators + + @decorators_mod.cachedproperty + def type(self): + """The function type for this node. + + Possible values are: method, function, staticmethod, classmethod. + + :type: str + """ + builtin_descriptors = {"classmethod", "staticmethod"} + + for decorator in self.extra_decorators: + if decorator.func.name in builtin_descriptors: + return decorator.func.name + + frame = self.parent.frame() + type_name = "function" + if isinstance(frame, ClassDef): + if self.name == "__new__": + return "classmethod" + if sys.version_info >= (3, 6) and self.name == "__init_subclass__": + return "classmethod" + + type_name = "method" + + if not self.decorators: + return type_name + + for node in self.decorators.nodes: + if isinstance(node, node_classes.Name): + if node.name in builtin_descriptors: + return node.name + + if isinstance(node, node_classes.Call): + # Handle the following case: + # @some_decorator(arg1, arg2) + # def func(...) + # + try: + current = next(node.func.infer()) + except exceptions.InferenceError: + continue + _type = _infer_decorator_callchain(current) + if _type is not None: + return _type + + try: + for inferred in node.infer(): + # Check to see if this returns a static or a class method. + _type = _infer_decorator_callchain(inferred) + if _type is not None: + return _type + + if not isinstance(inferred, ClassDef): + continue + for ancestor in inferred.ancestors(): + if not isinstance(ancestor, ClassDef): + continue + if ancestor.is_subtype_of("%s.classmethod" % BUILTINS): + return "classmethod" + if ancestor.is_subtype_of("%s.staticmethod" % BUILTINS): + return "staticmethod" + except exceptions.InferenceError: + pass + return type_name + + @decorators_mod.cachedproperty + def fromlineno(self): + """The first line that this node appears on in the source code. + + :type: int or None + """ + # lineno is the line number of the first decorator, we want the def + # statement lineno + lineno = self.lineno + if self.decorators is not None: + lineno += sum( + node.tolineno - node.lineno + 1 for node in self.decorators.nodes + ) + + return lineno + + @decorators_mod.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + return self.args.tolineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def getattr(self, name, context=None): + """this method doesn't look in the instance_attrs dictionary since it's + done by an Instance proxy at inference time. + """ + if name in self.instance_attrs: + return self.instance_attrs[name] + if name in self.special_attributes: + return [self.special_attributes.lookup(name)] + raise exceptions.AttributeInferenceError(target=self, attribute=name) + + def igetattr(self, name, context=None): + """Inferred getattr, which returns an iterator of inferred statements.""" + try: + return bases._infer_stmts(self.getattr(name, context), context, frame=self) + except exceptions.AttributeInferenceError as error: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) from error + + def is_method(self): + """Check if this function node represents a method. + + :returns: True if this is a method, False otherwise. + :rtype: bool + """ + # check we are defined in a ClassDef, because this is usually expected + # (e.g. pylint...) when is_method() return True + return self.type != "function" and isinstance(self.parent.frame(), ClassDef) + + @decorators_mod.cached + def decoratornames(self): + """Get the qualified names of each of the decorators on this function. + + :returns: The names of the decorators. + :rtype: set(str) + """ + result = set() + decoratornodes = [] + if self.decorators is not None: + decoratornodes += self.decorators.nodes + decoratornodes += self.extra_decorators + for decnode in decoratornodes: + try: + for infnode in decnode.infer(): + result.add(infnode.qname()) + except exceptions.InferenceError: + continue + return result + + def is_bound(self): + """Check if the function is bound to an instance or class. + + :returns: True if the function is bound to an instance or class, + False otherwise. + :rtype: bool + """ + return self.type == "classmethod" + + def is_abstract(self, pass_is_abstract=True): + """Check if the method is abstract. + + A method is considered abstract if any of the following is true: + * The only statement is 'raise NotImplementedError' + * The only statement is 'pass' and pass_is_abstract is True + * The method is annotated with abc.astractproperty/abc.abstractmethod + + :returns: True if the method is abstract, False otherwise. + :rtype: bool + """ + if self.decorators: + for node in self.decorators.nodes: + try: + inferred = next(node.infer()) + except exceptions.InferenceError: + continue + if inferred and inferred.qname() in ( + "abc.abstractproperty", + "abc.abstractmethod", + ): + return True + + for child_node in self.body: + if isinstance(child_node, node_classes.Raise): + if child_node.raises_not_implemented(): + return True + return pass_is_abstract and isinstance(child_node, node_classes.Pass) + # empty function is the same as function with a single "pass" statement + if pass_is_abstract: + return True + + def is_generator(self): + """Check if this is a generator function. + + :returns: True is this is a generator function, False otherwise. + :rtype: bool + """ + return next(self._get_yield_nodes_skip_lambdas(), False) + + def infer_call_result(self, caller=None, context=None): + """Infer what the function returns when called. + + :returns: What the function returns. + :rtype: iterable(NodeNG or Uninferable) or None + """ + if self.is_generator(): + if isinstance(self, AsyncFunctionDef): + generator_cls = bases.AsyncGenerator + else: + generator_cls = bases.Generator + result = generator_cls(self) + yield result + return + # This is really a gigantic hack to work around metaclass generators + # that return transient class-generating functions. Pylint's AST structure + # cannot handle a base class object that is only used for calling __new__, + # but does not contribute to the inheritance structure itself. We inject + # a fake class into the hierarchy here for several well-known metaclass + # generators, and filter it out later. + if ( + self.name == "with_metaclass" + and len(self.args.args) == 1 + and self.args.vararg is not None + ): + metaclass = next(caller.args[0].infer(context)) + if isinstance(metaclass, ClassDef): + class_bases = [next(arg.infer(context)) for arg in caller.args[1:]] + new_class = ClassDef(name="temporary_class") + new_class.hide = True + new_class.parent = self + new_class.postinit( + bases=[base for base in class_bases if base != util.Uninferable], + body=[], + decorators=[], + metaclass=metaclass, + ) + yield new_class + return + returns = self._get_return_nodes_skip_functions() + + first_return = next(returns, None) + if not first_return: + raise exceptions.InferenceError("Empty return iterator") + + for returnnode in itertools.chain((first_return,), returns): + if returnnode.value is None: + yield node_classes.Const(None) + else: + try: + yield from returnnode.value.infer(context) + except exceptions.InferenceError: + yield util.Uninferable + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`FunctionDef` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + if self.decorators is not None: + yield self.decorators + + yield self.args + + if self.returns is not None: + yield self.returns + + yield from self.body + + +class AsyncFunctionDef(FunctionDef): + """Class representing an :class:`ast.FunctionDef` node. + + A :class:`AsyncFunctionDef` is an asynchronous function + created with the `async` keyword. + + >>> node = astroid.extract_node(''' + async def func(things): + async for thing in things: + print(thing) + ''') + >>> node + + >>> node.body[0] + + """ + + +def _rec_get_names(args, names=None): + """return a list of all argument names""" + if names is None: + names = [] + for arg in args: + if isinstance(arg, node_classes.Tuple): + _rec_get_names(arg.elts, names) + else: + names.append(arg.name) + return names + + +def _is_metaclass(klass, seen=None): + """ Return if the given class can be + used as a metaclass. + """ + if klass.name == "type": + return True + if seen is None: + seen = set() + for base in klass.bases: + try: + for baseobj in base.infer(): + baseobj_name = baseobj.qname() + if baseobj_name in seen: + continue + else: + seen.add(baseobj_name) + if isinstance(baseobj, bases.Instance): + # not abstract + return False + if baseobj is util.Uninferable: + continue + if baseobj is klass: + continue + if not isinstance(baseobj, ClassDef): + continue + if baseobj._type == "metaclass": + return True + if _is_metaclass(baseobj, seen): + return True + except exceptions.InferenceError: + continue + return False + + +def _class_type(klass, ancestors=None): + """return a ClassDef node type to differ metaclass and exception + from 'regular' classes + """ + # XXX we have to store ancestors in case we have an ancestor loop + if klass._type is not None: + return klass._type + if _is_metaclass(klass): + klass._type = "metaclass" + elif klass.name.endswith("Exception"): + klass._type = "exception" + else: + if ancestors is None: + ancestors = set() + klass_name = klass.qname() + if klass_name in ancestors: + # XXX we are in loop ancestors, and have found no type + klass._type = "class" + return "class" + ancestors.add(klass_name) + for base in klass.ancestors(recurs=False): + name = _class_type(base, ancestors) + if name != "class": + if name == "metaclass" and not _is_metaclass(klass): + # don't propagate it if the current class + # can't be a metaclass + continue + klass._type = base.type + break + if klass._type is None: + klass._type = "class" + return klass._type + + +def get_wrapping_class(node): + """Get the class that wraps the given node. + + We consider that a class wraps a node if the class + is a parent for the said node. + + :returns: The class that wraps the given node + :rtype: ClassDef or None + """ + + klass = node.frame() + while klass is not None and not isinstance(klass, ClassDef): + if klass.parent is None: + klass = None + else: + klass = klass.parent.frame() + return klass + + +class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, node_classes.Statement): + """Class representing an :class:`ast.ClassDef` node. + + >>> node = astroid.extract_node(''' + class Thing: + def my_meth(self, arg): + return arg + self.offset + ''') + >>> node + + """ + + # some of the attributes below are set by the builder module or + # by a raw factories + + # a dictionary of class instances attributes + _astroid_fields = ("decorators", "bases", "body") # name + + decorators = None + """The decorators that are applied to this class. + + :type: Decorators or None + """ + special_attributes = objectmodel.ClassModel() + """The names of special attributes that this class has. + + :type: objectmodel.ClassModel + """ + + _type = None + _metaclass_hack = False + hide = False + type = property( + _class_type, + doc=( + "The class type for this node.\n\n" + "Possible values are: class, metaclass, exception.\n\n" + ":type: str" + ), + ) + _other_fields = ("name", "doc") + _other_other_fields = ("locals", "_newstyle") + _newstyle = None + + def __init__(self, name=None, doc=None, lineno=None, col_offset=None, parent=None): + """ + :param name: The name of the class. + :type name: str or None + + :param doc: The function's docstring. + :type doc: str or None + + :param lineno: The line that this node appears on in the source code. + :type lineno: int or None + + :param col_offset: The column that this node appears on in the + source code. + :type col_offset: int or None + + :param parent: The parent node in the syntax tree. + :type parent: NodeNG or None + """ + self.instance_attrs = {} + self.locals = {} + """A map of the name of a local variable to the node defining it. + + :type: dict(str, NodeNG) + """ + + self.keywords = [] + """The keywords given to the class definition. + + This is usually for :pep:`3115` style metaclass declaration. + + :type: list(Keyword) or None + """ + + self.bases = [] + """What the class inherits from. + + :type: list(NodeNG) + """ + + self.body = [] + """The contents of the class body. + + :type: list(NodeNG) + """ + + self.name = name + """The name of the class. + + :type name: str or None + """ + + self.doc = doc + """The class' docstring. + + :type doc: str or None + """ + + super(ClassDef, self).__init__(lineno, col_offset, parent) + if parent is not None: + parent.frame().set_local(name, self) + + for local_name, node in self.implicit_locals(): + self.add_local_node(node, local_name) + + def implicit_parameters(self): + return 1 + + def implicit_locals(self): + """Get implicitly defined class definition locals. + + :returns: the the name and Const pair for each local + :rtype: tuple(tuple(str, node_classes.Const), ...) + """ + locals_ = (("__module__", self.special_attributes.py__module__),) + if sys.version_info >= (3, 3): + # __qualname__ is defined in PEP3155 + locals_ += (("__qualname__", self.special_attributes.py__qualname__),) + return locals_ + + # pylint: disable=redefined-outer-name + def postinit( + self, bases, body, decorators, newstyle=None, metaclass=None, keywords=None + ): + """Do some setup after initialisation. + + :param bases: What the class inherits from. + :type bases: list(NodeNG) + + :param body: The contents of the class body. + :type body: list(NodeNG) + + :param decorators: The decorators that are applied to this class. + :type decorators: Decorators or None + + :param newstyle: Whether this is a new style class or not. + :type newstyle: bool or None + + :param metaclass: The metaclass of this class. + :type metaclass: NodeNG or None + + :param keywords: The keywords given to the class definition. + :type keywords: list(Keyword) or None + """ + self.keywords = keywords + self.bases = bases + self.body = body + self.decorators = decorators + if newstyle is not None: + self._newstyle = newstyle + if metaclass is not None: + self._metaclass = metaclass + + def _newstyle_impl(self, context=None): + if context is None: + context = contextmod.InferenceContext() + if self._newstyle is not None: + return self._newstyle + for base in self.ancestors(recurs=False, context=context): + if base._newstyle_impl(context): + self._newstyle = True + break + klass = self.declared_metaclass() + # could be any callable, we'd need to infer the result of klass(name, + # bases, dict). punt if it's not a class node. + if klass is not None and isinstance(klass, ClassDef): + self._newstyle = klass._newstyle_impl(context) + if self._newstyle is None: + self._newstyle = False + return self._newstyle + + _newstyle = None + newstyle = property( + _newstyle_impl, + doc=("Whether this is a new style class or not\n\n" ":type: bool or None"), + ) + + @decorators_mod.cachedproperty + def blockstart_tolineno(self): + """The line on which the beginning of this block ends. + + :type: int + """ + if self.bases: + return self.bases[-1].tolineno + + return self.fromlineno + + def block_range(self, lineno): + """Get a range from the given line number to where this node ends. + + :param lineno: Unused. + :type lineno: int + + :returns: The range of line numbers that this node belongs to, + :rtype: tuple(int, int) + """ + return self.fromlineno, self.tolineno + + def pytype(self): + """Get the name of the type that this node represents. + + :returns: The name of the type. + :rtype: str + """ + if self.newstyle: + return "%s.type" % BUILTINS + return "%s.classobj" % BUILTINS + + def display_type(self): + """A human readable type of this node. + + :returns: The type of this node. + :rtype: str + """ + return "Class" + + def callable(self): + """Whether this node defines something that is callable. + + :returns: True if this defines something that is callable, + False otherwise. + For a :class:`ClassDef` this is always ``True``. + :rtype: bool + """ + return True + + def is_subtype_of(self, type_name, context=None): + """Whether this class is a subtype of the given type. + + :param type_name: The name of the type of check against. + :type type_name: str + + :returns: True if this class is a subtype of the given type, + False otherwise. + :rtype: bool + """ + if self.qname() == type_name: + return True + for anc in self.ancestors(context=context): + if anc.qname() == type_name: + return True + return False + + def _infer_type_call(self, caller, context): + name_node = next(caller.args[0].infer(context)) + if isinstance(name_node, node_classes.Const) and isinstance( + name_node.value, str + ): + name = name_node.value + else: + return util.Uninferable + + result = ClassDef(name, None) + + # Get the bases of the class. + class_bases = next(caller.args[1].infer(context)) + if isinstance(class_bases, (node_classes.Tuple, node_classes.List)): + result.bases = class_bases.itered() + else: + # There is currently no AST node that can represent an 'unknown' + # node (Uninferable is not an AST node), therefore we simply return Uninferable here + # although we know at least the name of the class. + return util.Uninferable + + # Get the members of the class + try: + members = next(caller.args[2].infer(context)) + except exceptions.InferenceError: + members = None + + if members and isinstance(members, node_classes.Dict): + for attr, value in members.items: + if isinstance(attr, node_classes.Const) and isinstance(attr.value, str): + result.locals[attr.value] = [value] + + result.parent = caller.parent + return result + + def infer_call_result(self, caller, context=None): + """infer what a class is returning when called""" + if ( + self.is_subtype_of("%s.type" % (BUILTINS,), context) + and len(caller.args) == 3 + ): + result = self._infer_type_call(caller, context) + yield result + return + + dunder_call = None + try: + metaclass = self.metaclass(context=context) + if metaclass is not None: + dunder_call = next(metaclass.igetattr("__call__", context)) + except exceptions.AttributeInferenceError: + pass + if dunder_call and dunder_call.qname() != "builtins.type.__call__": + context = contextmod.bind_context_to_node(context, self) + yield from dunder_call.infer_call_result(caller, context) + else: + # Call type.__call__ if not set metaclass + # (since type is the default metaclass) + yield bases.Instance(self) + + def scope_lookup(self, node, name, offset=0): + """Lookup where the given name is assigned. + + :param node: The node to look for assignments up to. + Any assignments after the given node are ignored. + :type node: NodeNG + + :param name: The name to find assignments for. + :type name: str + + :param offset: The line offset to filter statements up to. + :type offset: int + + :returns: This scope node and the list of assignments associated to the + given name according to the scope where it has been found (locals, + globals or builtin). + :rtype: tuple(str, list(NodeNG)) + """ + # If the name looks like a builtin name, just try to look + # into the upper scope of this class. We might have a + # decorator that it's poorly named after a builtin object + # inside this class. + lookup_upper_frame = ( + isinstance(node.parent, node_classes.Decorators) + and name in MANAGER.astroid_cache[builtins.__name__] + ) + if ( + any(node == base or base.parent_of(node) for base in self.bases) + or lookup_upper_frame + ): + # Handle the case where we have either a name + # in the bases of a class, which exists before + # the actual definition or the case where we have + # a Getattr node, with that name. + # + # name = ... + # class A(name): + # def name(self): ... + # + # import name + # class A(name.Name): + # def name(self): ... + + frame = self.parent.frame() + # line offset to avoid that class A(A) resolve the ancestor to + # the defined class + offset = -1 + else: + frame = self + return frame._scope_lookup(node, name, offset) + + @property + def basenames(self): + """The names of the parent classes + + Names are given in the order they appear in the class definition. + + :type: list(str) + """ + return [bnode.as_string() for bnode in self.bases] + + def ancestors(self, recurs=True, context=None): + """Iterate over the base classes in prefixed depth first order. + + :param recurs: Whether to recurse or return direct ancestors only. + :type recurs: bool + + :returns: The base classes + :rtype: iterable(NodeNG) + """ + # FIXME: should be possible to choose the resolution order + # FIXME: inference make infinite loops possible here + yielded = {self} + if context is None: + context = contextmod.InferenceContext() + if not self.bases and self.qname() != "builtins.object": + yield builtin_lookup("object")[1][0] + return + + for stmt in self.bases: + try: + for baseobj in stmt.infer(context): + if not isinstance(baseobj, ClassDef): + if isinstance(baseobj, bases.Instance): + baseobj = baseobj._proxied + else: + continue + if not baseobj.hide: + if baseobj in yielded: + continue + yielded.add(baseobj) + yield baseobj + if not recurs: + continue + for grandpa in baseobj.ancestors(recurs=True, context=context): + if grandpa is self: + # This class is the ancestor of itself. + break + if grandpa in yielded: + continue + yielded.add(grandpa) + yield grandpa + except exceptions.InferenceError: + continue + + def local_attr_ancestors(self, name, context=None): + """Iterate over the parents that define the given name. + + :param name: The name to find definitions for. + :type name: str + + :returns: The parents that define the given name. + :rtype: iterable(NodeNG) + """ + # Look up in the mro if we can. This will result in the + # attribute being looked up just as Python does it. + try: + ancestors = self.mro(context)[1:] + except exceptions.MroError: + # Fallback to use ancestors, we can't determine + # a sane MRO. + ancestors = self.ancestors(context=context) + for astroid in ancestors: + if name in astroid: + yield astroid + + def instance_attr_ancestors(self, name, context=None): + """Iterate over the parents that define the given name as an attribute. + + :param name: The name to find definitions for. + :type name: str + + :returns: The parents that define the given name as + an instance attribute. + :rtype: iterable(NodeNG) + """ + for astroid in self.ancestors(context=context): + if name in astroid.instance_attrs: + yield astroid + + def has_base(self, node): + """Whether this class directly inherits from the given node. + + :param node: The node to check for. + :type node: NodeNG + + :returns: True if this class directly inherits from the given node. + :rtype: bool + """ + return node in self.bases + + def local_attr(self, name, context=None): + """Get the list of assign nodes associated to the given name. + + Assignments are looked for in both this class and in parents. + + :returns: The list of assignments to the given name. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If no attribute with this name + can be found in this class or parent classes. + """ + result = [] + if name in self.locals: + result = self.locals[name] + else: + class_node = next(self.local_attr_ancestors(name, context), None) + if class_node: + result = class_node.locals[name] + result = [n for n in result if not isinstance(n, node_classes.DelAttr)] + if result: + return result + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def instance_attr(self, name, context=None): + """Get the list of nodes associated to the given attribute name. + + Assignments are looked for in both this class and in parents. + + :returns: The list of assignments to the given name. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If no attribute with this name + can be found in this class or parent classes. + """ + # Return a copy, so we don't modify self.instance_attrs, + # which could lead to infinite loop. + values = list(self.instance_attrs.get(name, [])) + # get all values from parents + for class_node in self.instance_attr_ancestors(name, context): + values += class_node.instance_attrs[name] + values = [n for n in values if not isinstance(n, node_classes.DelAttr)] + if values: + return values + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + + def instantiate_class(self): + """Get an :class:`Instance` of the :class:`ClassDef` node. + + :returns: An :class:`Instance` of the :class:`ClassDef` node, + or self if this is not possible. + :rtype: Instance or ClassDef + """ + return bases.Instance(self) + + def getattr(self, name, context=None, class_context=True): + """Get an attribute from this class, using Python's attribute semantic. + + This method doesn't look in the :attr:`instance_attrs` dictionary + since it is done by an :class:`Instance` proxy at inference time. + It may return an :class:`Uninferable` object if + the attribute has not been + found, but a ``__getattr__`` or ``__getattribute__`` method is defined. + If ``class_context`` is given, then it is considered that the + attribute is accessed from a class context, + e.g. ClassDef.attribute, otherwise it might have been accessed + from an instance as well. If ``class_context`` is used in that + case, then a lookup in the implicit metaclass and the explicit + metaclass will be done. + + :param name: The attribute to look for. + :type name: str + + :param class_context: Whether the attribute can be accessed statically. + :type class_context: bool + + :returns: The attribute. + :rtype: list(NodeNG) + + :raises AttributeInferenceError: If the attribute cannot be inferred. + """ + values = self.locals.get(name, []) + if name in self.special_attributes and class_context and not values: + result = [self.special_attributes.lookup(name)] + if name == "__bases__": + # Need special treatment, since they are mutable + # and we need to return all the values. + result += values + return result + + # don't modify the list in self.locals! + values = list(values) + for classnode in self.ancestors(recurs=True, context=context): + values += classnode.locals.get(name, []) + + if class_context: + values += self._metaclass_lookup_attribute(name, context) + + if not values: + raise exceptions.AttributeInferenceError( + target=self, attribute=name, context=context + ) + return values + + def _metaclass_lookup_attribute(self, name, context): + """Search the given name in the implicit and the explicit metaclass.""" + attrs = set() + implicit_meta = self.implicit_metaclass() + metaclass = self.metaclass() + for cls in {implicit_meta, metaclass}: + if cls and cls != self and isinstance(cls, ClassDef): + cls_attributes = self._get_attribute_from_metaclass(cls, name, context) + attrs.update(set(cls_attributes)) + return attrs + + def _get_attribute_from_metaclass(self, cls, name, context): + try: + attrs = cls.getattr(name, context=context, class_context=True) + except exceptions.AttributeInferenceError: + return + + for attr in bases._infer_stmts(attrs, context, frame=cls): + if not isinstance(attr, FunctionDef): + yield attr + continue + + if bases._is_property(attr): + yield from attr.infer_call_result(self, context) + continue + if attr.type == "classmethod": + # If the method is a classmethod, then it will + # be bound to the metaclass, not to the class + # from where the attribute is retrieved. + # get_wrapping_class could return None, so just + # default to the current class. + frame = get_wrapping_class(attr) or self + yield bases.BoundMethod(attr, frame) + elif attr.type == "staticmethod": + yield attr + else: + yield bases.BoundMethod(attr, self) + + def igetattr(self, name, context=None, class_context=True): + """Infer the possible values of the given variable. + + :param name: The name of the variable to infer. + :type name: str + + :returns: The inferred possible values. + :rtype: iterable(NodeNG or Uninferable) + """ + # set lookup name since this is necessary to infer on import nodes for + # instance + context = contextmod.copy_context(context) + context.lookupname = name + try: + attr = self.getattr(name, context, class_context=class_context)[0] + for inferred in bases._infer_stmts([attr], context, frame=self): + # yield Uninferable object instead of descriptors when necessary + if not isinstance(inferred, node_classes.Const) and isinstance( + inferred, bases.Instance + ): + try: + inferred._proxied.getattr("__get__", context) + except exceptions.AttributeInferenceError: + yield inferred + else: + yield util.Uninferable + else: + yield function_to_method(inferred, self) + except exceptions.AttributeInferenceError as error: + if not name.startswith("__") and self.has_dynamic_getattr(context): + # class handle some dynamic attributes, return a Uninferable object + yield util.Uninferable + else: + raise exceptions.InferenceError( + error.message, target=self, attribute=name, context=context + ) + + def has_dynamic_getattr(self, context=None): + """Check if the class has a custom __getattr__ or __getattribute__. + + If any such method is found and it is not from + builtins, nor from an extension module, then the function + will return True. + + :returns: True if the class has a custom + __getattr__ or __getattribute__, False otherwise. + :rtype: bool + """ + + def _valid_getattr(node): + root = node.root() + return root.name != BUILTINS and getattr(root, "pure_python", None) + + try: + return _valid_getattr(self.getattr("__getattr__", context)[0]) + except exceptions.AttributeInferenceError: + # if self.newstyle: XXX cause an infinite recursion error + try: + getattribute = self.getattr("__getattribute__", context)[0] + return _valid_getattr(getattribute) + except exceptions.AttributeInferenceError: + pass + return False + + def getitem(self, index, context=None): + """Return the inference of a subscript. + + This is basically looking up the method in the metaclass and calling it. + + :returns: The inferred value of a subscript to this class. + :rtype: NodeNG + + :raises AstroidTypeError: If this class does not define a + ``__getitem__`` method. + """ + try: + methods = dunder_lookup.lookup(self, "__getitem__") + except exceptions.AttributeInferenceError as exc: + raise exceptions.AstroidTypeError(node=self, context=context) from exc + + method = methods[0] + + # Create a new callcontext for providing index as an argument. + new_context = contextmod.bind_context_to_node(context, self) + new_context.callcontext = contextmod.CallContext(args=[index]) + + try: + return next(method.infer_call_result(self, new_context)) + except exceptions.InferenceError: + return util.Uninferable + + def methods(self): + """Iterate over all of the method defined in this class and its parents. + + :returns: The methods defined on the class. + :rtype: iterable(FunctionDef) + """ + done = {} + for astroid in itertools.chain(iter((self,)), self.ancestors()): + for meth in astroid.mymethods(): + if meth.name in done: + continue + done[meth.name] = None + yield meth + + def mymethods(self): + """Iterate over all of the method defined in this class only. + + :returns: The methods defined on the class. + :rtype: iterable(FunctionDef) + """ + for member in self.values(): + if isinstance(member, FunctionDef): + yield member + + def implicit_metaclass(self): + """Get the implicit metaclass of the current class. + + For newstyle classes, this will return an instance of builtins.type. + For oldstyle classes, it will simply return None, since there's + no implicit metaclass there. + + :returns: The metaclass. + :rtype: builtins.type or None + """ + if self.newstyle: + return builtin_lookup("type")[1][0] + return None + + _metaclass = None + + def declared_metaclass(self, context=None): + """Return the explicit declared metaclass for the current class. + + An explicit declared metaclass is defined + either by passing the ``metaclass`` keyword argument + in the class definition line (Python 3) or (Python 2) by + having a ``__metaclass__`` class attribute, or if there are + no explicit bases but there is a global ``__metaclass__`` variable. + + :returns: The metaclass of this class, + or None if one could not be found. + :rtype: NodeNG or None + """ + for base in self.bases: + try: + for baseobj in base.infer(context=context): + if isinstance(baseobj, ClassDef) and baseobj.hide: + self._metaclass = baseobj._metaclass + self._metaclass_hack = True + break + except exceptions.InferenceError: + pass + + if self._metaclass: + # Expects this from Py3k TreeRebuilder + try: + return next( + node + for node in self._metaclass.infer(context=context) + if node is not util.Uninferable + ) + except (exceptions.InferenceError, StopIteration): + return None + + return None + + def _find_metaclass(self, seen=None, context=None): + if seen is None: + seen = set() + seen.add(self) + + klass = self.declared_metaclass(context=context) + if klass is None: + for parent in self.ancestors(context=context): + if parent not in seen: + klass = parent._find_metaclass(seen) + if klass is not None: + break + return klass + + def metaclass(self, context=None): + """Get the metaclass of this class. + + If this class does not define explicitly a metaclass, + then the first defined metaclass in ancestors will be used + instead. + + :returns: The metaclass of this class. + :rtype: NodeNG or None + """ + return self._find_metaclass(context=context) + + def has_metaclass_hack(self): + return self._metaclass_hack + + def _islots(self): + """ Return an iterator with the inferred slots. """ + if "__slots__" not in self.locals: + return None + for slots in self.igetattr("__slots__"): + # check if __slots__ is a valid type + for meth in ITER_METHODS: + try: + slots.getattr(meth) + break + except exceptions.AttributeInferenceError: + continue + else: + continue + + if isinstance(slots, node_classes.Const): + # a string. Ignore the following checks, + # but yield the node, only if it has a value + if slots.value: + yield slots + continue + if not hasattr(slots, "itered"): + # we can't obtain the values, maybe a .deque? + continue + + if isinstance(slots, node_classes.Dict): + values = [item[0] for item in slots.items] + else: + values = slots.itered() + if values is util.Uninferable: + continue + if not values: + # Stop the iteration, because the class + # has an empty list of slots. + return values + + for elt in values: + try: + for inferred in elt.infer(): + if inferred is util.Uninferable: + continue + if not isinstance( + inferred, node_classes.Const + ) or not isinstance(inferred.value, str): + continue + if not inferred.value: + continue + yield inferred + except exceptions.InferenceError: + continue + + return None + + def _slots(self): + if not self.newstyle: + raise NotImplementedError( + "The concept of slots is undefined for old-style classes." + ) + + slots = self._islots() + try: + first = next(slots) + except StopIteration as exc: + # The class doesn't have a __slots__ definition or empty slots. + if exc.args and exc.args[0] not in ("", None): + return exc.args[0] + return None + return [first] + list(slots) + + # Cached, because inferring them all the time is expensive + @decorators_mod.cached + def slots(self): + """Get all the slots for this node. + + :returns: The names of slots for this class. + If the class doesn't define any slot, through the ``__slots__`` + variable, then this function will return a None. + Also, it will return None in the case the slots were not inferred. + :rtype: list(str) or None + """ + + def grouped_slots(): + # Not interested in object, since it can't have slots. + for cls in self.mro()[:-1]: + try: + cls_slots = cls._slots() + except NotImplementedError: + continue + if cls_slots is not None: + yield from cls_slots + else: + yield None + + if not self.newstyle: + raise NotImplementedError( + "The concept of slots is undefined for old-style classes." + ) + + slots = list(grouped_slots()) + if not all(slot is not None for slot in slots): + return None + + return sorted(slots, key=lambda item: item.value) + + def _inferred_bases(self, context=None): + # Similar with .ancestors, but the difference is when one base is inferred, + # only the first object is wanted. That's because + # we aren't interested in superclasses, as in the following + # example: + # + # class SomeSuperClass(object): pass + # class SomeClass(SomeSuperClass): pass + # class Test(SomeClass): pass + # + # Inferring SomeClass from the Test's bases will give + # us both SomeClass and SomeSuperClass, but we are interested + # only in SomeClass. + + if context is None: + context = contextmod.InferenceContext() + if not self.bases and self.qname() != "builtins.object": + yield builtin_lookup("object")[1][0] + return + + for stmt in self.bases: + try: + baseobj = next(stmt.infer(context=context)) + except exceptions.InferenceError: + continue + if isinstance(baseobj, bases.Instance): + baseobj = baseobj._proxied + if not isinstance(baseobj, ClassDef): + continue + if not baseobj.hide: + yield baseobj + else: + yield from baseobj.bases + + def _compute_mro(self, context=None): + inferred_bases = list(self._inferred_bases(context=context)) + bases_mro = [] + for base in inferred_bases: + if base is self: + continue + + try: + mro = base._compute_mro(context=context) + bases_mro.append(mro) + except NotImplementedError: + # Some classes have in their ancestors both newstyle and + # old style classes. For these we can't retrieve the .mro, + # although in Python it's possible, since the class we are + # currently working is in fact new style. + # So, we fallback to ancestors here. + ancestors = list(base.ancestors(context=context)) + bases_mro.append(ancestors) + + unmerged_mro = [[self]] + bases_mro + [inferred_bases] + _verify_duplicates_mro(unmerged_mro, self, context) + return _c3_merge(unmerged_mro, self, context) + + def mro(self, context=None): + """Get the method resolution order, using C3 linearization. + + :returns: The list of ancestors, sorted by the mro. + :rtype: list(NodeNG) + + :raises NotImplementedError: If this is an old style class, + since they don't have the concept of an MRO. + :raises DuplicateBasesError: Duplicate bases in the same class base + :raises InconsistentMroError: A class' MRO is inconsistent + """ + + if not self.newstyle: + raise NotImplementedError("Could not obtain mro for old-style classes.") + + return self._compute_mro(context=context) + + def bool_value(self): + """Determine the boolean value of this node. + + :returns: The boolean value of this node. + For a :class:`ClassDef` this is always ``True``. + :rtype: bool + """ + return True + + def get_children(self): + if self.decorators is not None: + yield self.decorators + + yield from self.bases + yield from self.body + + @decorators_mod.cached + def _get_assign_nodes(self): + children_assign_nodes = ( + child_node._get_assign_nodes() for child_node in self.body + ) + return list(itertools.chain.from_iterable(children_assign_nodes)) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/test_utils.py b/basic python programmes/venv/Lib/site-packages/astroid/test_utils.py new file mode 100644 index 0000000..55b7e84 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/test_utils.py @@ -0,0 +1,71 @@ +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2016 Jakub Wilk +# Copyright (c) 2018 Anthony Sottile + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +"""Utility functions for test code that uses astroid ASTs as input.""" +import contextlib +import functools +import sys +import warnings + +from astroid import nodes + + +def require_version(minver=None, maxver=None): + """ Compare version of python interpreter to the given one. Skip the test + if older. + """ + + def parse(string, default=None): + string = string or default + try: + return tuple(int(v) for v in string.split(".")) + except ValueError as exc: + raise ValueError( + "{string} is not a correct version : should be X.Y[.Z].".format( + string=string + ) + ) from exc + + def check_require_version(f): + current = sys.version_info[:3] + if parse(minver, "0") < current <= parse(maxver, "4"): + return f + + str_version = ".".join(str(v) for v in sys.version_info) + + @functools.wraps(f) + def new_f(self, *args, **kwargs): + if minver is not None: + self.skipTest( + "Needs Python > %s. Current version is %s." % (minver, str_version) + ) + elif maxver is not None: + self.skipTest( + "Needs Python <= %s. Current version is %s." % (maxver, str_version) + ) + + return new_f + + return check_require_version + + +def get_name_node(start_from, name, index=0): + return [n for n in start_from.nodes_of_class(nodes.Name) if n.name == name][index] + + +@contextlib.contextmanager +def enable_warning(warning): + warnings.simplefilter("always", warning) + try: + yield + finally: + # Reset it to default value, so it will take + # into account the values from the -W flag. + warnings.simplefilter("default", warning) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/transforms.py b/basic python programmes/venv/Lib/site-packages/astroid/transforms.py new file mode 100644 index 0000000..e5506cc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/transforms.py @@ -0,0 +1,90 @@ +# Copyright (c) 2015-2016, 2018 Claudiu Popa +# Copyright (c) 2016 Ceridwen +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + + +import collections +from functools import lru_cache + + +class TransformVisitor: + """A visitor for handling transforms. + + The standard approach of using it is to call + :meth:`~visit` with an *astroid* module and the class + will take care of the rest, walking the tree and running the + transforms for each encountered node. + """ + + TRANSFORM_MAX_CACHE_SIZE = 10000 + + def __init__(self): + self.transforms = collections.defaultdict(list) + + @lru_cache(maxsize=TRANSFORM_MAX_CACHE_SIZE) + def _transform(self, node): + """Call matching transforms for the given node if any and return the + transformed node. + """ + cls = node.__class__ + if cls not in self.transforms: + # no transform registered for this class of node + return node + + transforms = self.transforms[cls] + for transform_func, predicate in transforms: + if predicate is None or predicate(node): + ret = transform_func(node) + # if the transformation function returns something, it's + # expected to be a replacement for the node + if ret is not None: + node = ret + if ret.__class__ != cls: + # Can no longer apply the rest of the transforms. + break + return node + + def _visit(self, node): + if hasattr(node, "_astroid_fields"): + for name in node._astroid_fields: + value = getattr(node, name) + visited = self._visit_generic(value) + if visited != value: + setattr(node, name, visited) + return self._transform(node) + + def _visit_generic(self, node): + if isinstance(node, list): + return [self._visit_generic(child) for child in node] + if isinstance(node, tuple): + return tuple(self._visit_generic(child) for child in node) + if not node or isinstance(node, str): + return node + + return self._visit(node) + + def register_transform(self, node_class, transform, predicate=None): + """Register `transform(node)` function to be applied on the given + astroid's `node_class` if `predicate` is None or returns true + when called with the node as argument. + + The transform function may return a value which is then used to + substitute the original node in the tree. + """ + self.transforms[node_class].append((transform, predicate)) + + def unregister_transform(self, node_class, transform, predicate=None): + """Unregister the given transform.""" + self.transforms[node_class].remove((transform, predicate)) + + def visit(self, module): + """Walk the given astroid *tree* and transform each encountered node + + Only the nodes which have transforms registered will actually + be replaced or changed. + """ + module.body = [self._visit(child) for child in module.body] + return self._transform(module) diff --git a/basic python programmes/venv/Lib/site-packages/astroid/util.py b/basic python programmes/venv/Lib/site-packages/astroid/util.py new file mode 100644 index 0000000..3ab7561 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/astroid/util.py @@ -0,0 +1,164 @@ +# Copyright (c) 2015-2018 Claudiu Popa +# Copyright (c) 2015-2016 Ceridwen +# Copyright (c) 2018 Bryce Guinta +# Copyright (c) 2018 Nick Drozd + +# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html +# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER + +import warnings +from itertools import islice + +import importlib +import lazy_object_proxy + + +def lazy_descriptor(obj): + class DescriptorProxy(lazy_object_proxy.Proxy): + def __get__(self, instance, owner=None): + return self.__class__.__get__(self, instance) + + return DescriptorProxy(obj) + + +def lazy_import(module_name): + return lazy_object_proxy.Proxy( + lambda: importlib.import_module("." + module_name, "astroid") + ) + + +@object.__new__ +class Uninferable: + """Special inference object, which is returned when inference fails.""" + + def __repr__(self): + return "Uninferable" + + __str__ = __repr__ + + def __getattribute__(self, name): + if name == "next": + raise AttributeError("next method should not be called") + if name.startswith("__") and name.endswith("__"): + return object.__getattribute__(self, name) + if name == "accept": + return object.__getattribute__(self, name) + return self + + def __call__(self, *args, **kwargs): + return self + + def __bool__(self): + return False + + __nonzero__ = __bool__ + + def accept(self, visitor): + func = getattr(visitor, "visit_uninferable") + return func(self) + + +class BadOperationMessage: + """Object which describes a TypeError occurred somewhere in the inference chain + + This is not an exception, but a container object which holds the types and + the error which occurred. + """ + + +class BadUnaryOperationMessage(BadOperationMessage): + """Object which describes operational failures on UnaryOps.""" + + def __init__(self, operand, op, error): + self.operand = operand + self.op = op + self.error = error + + @property + def _object_type_helper(self): + helpers = lazy_import("helpers") + return helpers.object_type + + def _object_type(self, obj): + # pylint: disable=not-callable; can't infer lazy_import + objtype = self._object_type_helper(obj) + if objtype is Uninferable: + return None + + return objtype + + def __str__(self): + if hasattr(self.operand, "name"): + operand_type = self.operand.name + else: + object_type = self._object_type(self.operand) + if hasattr(object_type, "name"): + operand_type = object_type.name + else: + # Just fallback to as_string + operand_type = object_type.as_string() + + msg = "bad operand type for unary {}: {}" + return msg.format(self.op, operand_type) + + +class BadBinaryOperationMessage(BadOperationMessage): + """Object which describes type errors for BinOps.""" + + def __init__(self, left_type, op, right_type): + self.left_type = left_type + self.right_type = right_type + self.op = op + + def __str__(self): + msg = "unsupported operand type(s) for {}: {!r} and {!r}" + return msg.format(self.op, self.left_type.name, self.right_type.name) + + +def _instancecheck(cls, other): + wrapped = cls.__wrapped__ + other_cls = other.__class__ + is_instance_of = wrapped is other_cls or issubclass(other_cls, wrapped) + warnings.warn( + "%r is deprecated and slated for removal in astroid " + "2.0, use %r instead" % (cls.__class__.__name__, wrapped.__name__), + PendingDeprecationWarning, + stacklevel=2, + ) + return is_instance_of + + +def proxy_alias(alias_name, node_type): + """Get a Proxy from the given name to the given node type.""" + proxy = type( + alias_name, + (lazy_object_proxy.Proxy,), + { + "__class__": object.__dict__["__class__"], + "__instancecheck__": _instancecheck, + }, + ) + return proxy(lambda: node_type) + + +def limit_inference(iterator, size): + """Limit inference amount. + + Limit inference amount to help with performance issues with + exponentially exploding possible results. + + :param iterator: Inference generator to limit + :type iterator: Iterator(NodeNG) + + :param size: Maximum mount of nodes yielded plus an + Uninferable at the end if limit reached + :type size: int + + :yields: A possibly modified generator + :rtype param: Iterable + """ + yield from islice(iterator, size) + has_more = next(iterator, False) + if has_more is not False: + yield Uninferable + return diff --git a/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/INSTALLER b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/LICENSE.txt b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/LICENSE.txt new file mode 100644 index 0000000..3105888 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2010 Jonathan Hartley +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holders, nor those of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/METADATA b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/METADATA new file mode 100644 index 0000000..d613201 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/METADATA @@ -0,0 +1,376 @@ +Metadata-Version: 2.1 +Name: colorama +Version: 0.4.1 +Summary: Cross-platform colored terminal text. +Home-page: https://github.com/tartley/colorama +Author: Jonathan Hartley +Author-email: tartley@tartley.com +Maintainer: Arnon Yaari +License: BSD +Keywords: color colour terminal text ansi windows crossplatform xplatform +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Terminals +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + +.. image:: https://img.shields.io/pypi/v/colorama.svg + :target: https://pypi.org/project/colorama/ + :alt: Latest Version + +.. image:: https://img.shields.io/pypi/pyversions/colorama.svg + :target: https://pypi.org/project/colorama/ + :alt: Supported Python versions + +.. image:: https://travis-ci.org/tartley/colorama.svg?branch=master + :target: https://travis-ci.org/tartley/colorama + :alt: Build Status + +Download and docs: + https://pypi.org/project/colorama/ +Source code & Development: + https://github.com/tartley/colorama + +Description +=========== + +Makes ANSI escape character sequences (for producing colored terminal text and +cursor positioning) work under MS Windows. + +ANSI escape character sequences have long been used to produce colored terminal +text and cursor positioning on Unix and Macs. Colorama makes this work on +Windows, too, by wrapping ``stdout``, stripping ANSI sequences it finds (which +would appear as gobbledygook in the output), and converting them into the +appropriate win32 calls to modify the state of the terminal. On other platforms, +Colorama does nothing. + +Colorama also provides some shortcuts to help generate ANSI sequences +but works fine in conjunction with any other ANSI sequence generation library, +such as the venerable Termcolor (https://pypi.org/project/termcolor/) +or the fabulous Blessings (https://pypi.org/project/blessings/). + +This has the upshot of providing a simple cross-platform API for printing +colored terminal text from Python, and has the happy side-effect that existing +applications or libraries which use ANSI sequences to produce colored output on +Linux or Macs can now also work on Windows, simply by calling +``colorama.init()``. + +An alternative approach is to install ``ansi.sys`` on Windows machines, which +provides the same behaviour for all applications running in terminals. Colorama +is intended for situations where that isn't easy (e.g., maybe your app doesn't +have an installer.) + +Demo scripts in the source code repository print some colored text using +ANSI sequences. Compare their output under Gnome-terminal's built in ANSI +handling, versus on Windows Command-Prompt using Colorama: + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/ubuntu-demo.png + :width: 661 + :height: 357 + :alt: ANSI sequences on Ubuntu under gnome-terminal. + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/windows-demo.png + :width: 668 + :height: 325 + :alt: Same ANSI sequences on Windows, using Colorama. + +These screengrabs show that, on Windows, Colorama does not support ANSI 'dim +text'; it looks the same as 'normal text'. + + +License +======= + +Copyright Jonathan Hartley 2013. BSD 3-Clause license; see LICENSE file. + + +Dependencies +============ + +None, other than Python. Tested on Python 2.7, 3.4, 3.5 and 3.6. + +Usage +===== + +Initialisation +-------------- + +Applications should initialise Colorama using: + +.. code-block:: python + + from colorama import init + init() + +On Windows, calling ``init()`` will filter ANSI escape sequences out of any +text sent to ``stdout`` or ``stderr``, and replace them with equivalent Win32 +calls. + +On other platforms, calling ``init()`` has no effect (unless you request other +optional functionality; see "Init Keyword Args", below). By design, this permits +applications to call ``init()`` unconditionally on all platforms, after which +ANSI output should just work. + +To stop using colorama before your program exits, simply call ``deinit()``. +This will restore ``stdout`` and ``stderr`` to their original values, so that +Colorama is disabled. To resume using Colorama again, call ``reinit()``; it is +cheaper to calling ``init()`` again (but does the same thing). + + +Colored Output +-------------- + +Cross-platform printing of colored text can then be done using Colorama's +constant shorthand for ANSI escape sequences: + +.. code-block:: python + + from colorama import Fore, Back, Style + print(Fore.RED + 'some red text') + print(Back.GREEN + 'and with a green background') + print(Style.DIM + 'and in dim text') + print(Style.RESET_ALL) + print('back to normal now') + +...or simply by manually printing ANSI sequences from your own code: + +.. code-block:: python + + print('\033[31m' + 'some red text') + print('\033[30m') # and reset to default color + +...or, Colorama can be used happily in conjunction with existing ANSI libraries +such as Termcolor: + +.. code-block:: python + + from colorama import init + from termcolor import colored + + # use Colorama to make Termcolor work on Windows too + init() + + # then use Termcolor for all colored text output + print(colored('Hello, World!', 'green', 'on_red')) + +Available formatting constants are:: + + Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Style: DIM, NORMAL, BRIGHT, RESET_ALL + +``Style.RESET_ALL`` resets foreground, background, and brightness. Colorama will +perform this reset automatically on program exit. + + +Cursor Positioning +------------------ + +ANSI codes to reposition the cursor are supported. See ``demos/demo06.py`` for +an example of how to generate them. + + +Init Keyword Args +----------------- + +``init()`` accepts some ``**kwargs`` to override default behaviour. + +init(autoreset=False): + If you find yourself repeatedly sending reset sequences to turn off color + changes at the end of every print, then ``init(autoreset=True)`` will + automate that: + + .. code-block:: python + + from colorama import init + init(autoreset=True) + print(Fore.RED + 'some red text') + print('automatically back to default color again') + +init(strip=None): + Pass ``True`` or ``False`` to override whether ansi codes should be + stripped from the output. The default behaviour is to strip if on Windows + or if output is redirected (not a tty). + +init(convert=None): + Pass ``True`` or ``False`` to override whether to convert ANSI codes in the + output into win32 calls. The default behaviour is to convert if on Windows + and output is to a tty (terminal). + +init(wrap=True): + On Windows, colorama works by replacing ``sys.stdout`` and ``sys.stderr`` + with proxy objects, which override the ``.write()`` method to do their work. + If this wrapping causes you problems, then this can be disabled by passing + ``init(wrap=False)``. The default behaviour is to wrap if ``autoreset`` or + ``strip`` or ``convert`` are True. + + When wrapping is disabled, colored printing on non-Windows platforms will + continue to work as normal. To do cross-platform colored output, you can + use Colorama's ``AnsiToWin32`` proxy directly: + + .. code-block:: python + + import sys + from colorama import init, AnsiToWin32 + init(wrap=False) + stream = AnsiToWin32(sys.stderr).stream + + # Python 2 + print >>stream, Fore.BLUE + 'blue text on stderr' + + # Python 3 + print(Fore.BLUE + 'blue text on stderr', file=stream) + + +Status & Known Problems +======================= + +I've personally only tested it on Windows XP (CMD, Console2), Ubuntu +(gnome-terminal, xterm), and OS X. + +Some presumably valid ANSI sequences aren't recognised (see details below), +but to my knowledge nobody has yet complained about this. Puzzling. + +See outstanding issues and wishlist: +https://github.com/tartley/colorama/issues + +If anything doesn't work for you, or doesn't do what you expected or hoped for, +I'd love to hear about it on that issues list, would be delighted by patches, +and would be happy to grant commit access to anyone who submits a working patch +or two. + + +Recognised ANSI Sequences +========================= + +ANSI sequences generally take the form: + + ESC [ ; ... + +Where ```` is an integer, and ```` is a single letter. Zero or +more params are passed to a ````. If no params are passed, it is +generally synonymous with passing a single zero. No spaces exist in the +sequence; they have been inserted here simply to read more easily. + +The only ANSI sequences that colorama converts into win32 calls are:: + + ESC [ 0 m # reset all (colors and brightness) + ESC [ 1 m # bright + ESC [ 2 m # dim (looks same as normal brightness) + ESC [ 22 m # normal brightness + + # FOREGROUND: + ESC [ 30 m # black + ESC [ 31 m # red + ESC [ 32 m # green + ESC [ 33 m # yellow + ESC [ 34 m # blue + ESC [ 35 m # magenta + ESC [ 36 m # cyan + ESC [ 37 m # white + ESC [ 39 m # reset + + # BACKGROUND + ESC [ 40 m # black + ESC [ 41 m # red + ESC [ 42 m # green + ESC [ 43 m # yellow + ESC [ 44 m # blue + ESC [ 45 m # magenta + ESC [ 46 m # cyan + ESC [ 47 m # white + ESC [ 49 m # reset + + # cursor positioning + ESC [ y;x H # position cursor at x across, y down + ESC [ y;x f # position cursor at x across, y down + ESC [ n A # move cursor n lines up + ESC [ n B # move cursor n lines down + ESC [ n C # move cursor n characters forward + ESC [ n D # move cursor n characters backward + + # clear the screen + ESC [ mode J # clear the screen + + # clear the line + ESC [ mode K # clear the line + +Multiple numeric params to the ``'m'`` command can be combined into a single +sequence:: + + ESC [ 36 ; 45 ; 1 m # bright cyan text on magenta background + +All other ANSI sequences of the form ``ESC [ ; ... `` +are silently stripped from the output on Windows. + +Any other form of ANSI sequence, such as single-character codes or alternative +initial characters, are not recognised or stripped. It would be cool to add +them though. Let me know if it would be useful for you, via the Issues on +GitHub. + + +Development +=========== + +Help and fixes welcome! + +Running tests requires: + +- Michael Foord's ``mock`` module to be installed. +- Tests are written using 2010-era updates to ``unittest`` + +To run tests:: + + python -m unittest discover -p *_test.py + +This, like a few other handy commands, is captured in a ``Makefile``. + +If you use nose to run the tests, you must pass the ``-s`` flag; otherwise, +``nosetests`` applies its own proxy to ``stdout``, which confuses the unit +tests. + + +Thanks +====== +* Marc Schlaich (schlamar) for a ``setup.py`` fix for Python2.5. +* Marc Abramowitz, reported & fixed a crash on exit with closed ``stdout``, + providing a solution to issue #7's setuptools/distutils debate, + and other fixes. +* User 'eryksun', for guidance on correctly instantiating ``ctypes.windll``. +* Matthew McCormick for politely pointing out a longstanding crash on non-Win. +* Ben Hoyt, for a magnificent fix under 64-bit Windows. +* Jesse at Empty Square for submitting a fix for examples in the README. +* User 'jamessp', an observant documentation fix for cursor positioning. +* User 'vaal1239', Dave Mckee & Lackner Kristof for a tiny but much-needed Win7 + fix. +* Julien Stuyck, for wisely suggesting Python3 compatible updates to README. +* Daniel Griffith for multiple fabulous patches. +* Oscar Lesta for a valuable fix to stop ANSI chars being sent to non-tty + output. +* Roger Binns, for many suggestions, valuable feedback, & bug reports. +* Tim Golden for thought and much appreciated feedback on the initial idea. +* User 'Zearin' for updates to the README file. +* John Szakmeister for adding support for light colors +* Charles Merriam for adding documentation to demos +* Jurko for a fix on 64-bit Windows CPython2.5 w/o ctypes +* Florian Bruhin for a fix when stdout or stderr are None +* Thomas Weininger for fixing ValueError on Windows +* Remi Rampin for better Github integration and fixes to the README file +* Simeon Visser for closing a file handle using 'with' and updating classifiers + to include Python 3.3 and 3.4 +* Andy Neff for fixing RESET of LIGHT_EX colors. +* Jonathan Hartley for the initial idea and implementation. + + diff --git a/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/RECORD b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/RECORD new file mode 100644 index 0000000..99469a6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/RECORD @@ -0,0 +1,18 @@ +colorama/__init__.py,sha256=lJdY6COz9uM_pXwuk9oLr0fp8H8q2RrUqN16GKabvq4,239 +colorama/ansi.py,sha256=Fi0un-QLqRm-v7o_nKiOqyC8PapBJK7DLV_q9LKtTO0,2524 +colorama/ansitowin32.py,sha256=u8QaqdqS_xYSfNkPM1eRJLHz6JMWPodaJaP0mxgHCDc,10462 +colorama/initialise.py,sha256=PprovDNxMTrvoNHFcL2NZjpH2XzDc8BLxLxiErfUl4k,1915 +colorama/win32.py,sha256=bJ8Il9jwaBN5BJ8bmN6FoYZ1QYuMKv2j8fGrXh7TJjw,5404 +colorama/winterm.py,sha256=2y_2b7Zsv34feAsP67mLOVc-Bgq51mdYGo571VprlrM,6438 +colorama-0.4.1.dist-info/LICENSE.txt,sha256=ysNcAmhuXQSlpxQL-zs25zrtSWZW6JEQLkKIhteTAxg,1491 +colorama-0.4.1.dist-info/METADATA,sha256=qIw0-aY6m-JmPaXDBchI1GdlFM1soYaXgXGYLxwFWH8,13164 +colorama-0.4.1.dist-info/WHEEL,sha256=8T8fxefr_r-A79qbOJ9d_AaEgkpCGmEPHc-gpCq5BRg,110 +colorama-0.4.1.dist-info/top_level.txt,sha256=_Kx6-Cni2BT1PEATPhrSRxo0d7kSgfBbHf5o7IF1ABw,9 +colorama-0.4.1.dist-info/RECORD,, +colorama-0.4.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +colorama/__pycache__/ansi.cpython-37.pyc,, +colorama/__pycache__/ansitowin32.cpython-37.pyc,, +colorama/__pycache__/initialise.cpython-37.pyc,, +colorama/__pycache__/win32.cpython-37.pyc,, +colorama/__pycache__/winterm.cpython-37.pyc,, +colorama/__pycache__/__init__.cpython-37.pyc,, diff --git a/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/WHEEL b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/WHEEL new file mode 100644 index 0000000..1001235 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/top_level.txt new file mode 100644 index 0000000..3fcfb51 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama-0.4.1.dist-info/top_level.txt @@ -0,0 +1 @@ +colorama diff --git a/basic python programmes/venv/Lib/site-packages/colorama/__init__.py b/basic python programmes/venv/Lib/site-packages/colorama/__init__.py new file mode 100644 index 0000000..2a3bf47 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama/__init__.py @@ -0,0 +1,6 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.4.1' diff --git a/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..abb23c7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-37.pyc new file mode 100644 index 0000000..a5f0e40 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/ansitowin32.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/ansitowin32.cpython-37.pyc new file mode 100644 index 0000000..1bff3c2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/ansitowin32.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/initialise.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/initialise.cpython-37.pyc new file mode 100644 index 0000000..867285f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/initialise.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/win32.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/win32.cpython-37.pyc new file mode 100644 index 0000000..f47563f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/win32.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-37.pyc new file mode 100644 index 0000000..9a9de1f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/colorama/ansi.py b/basic python programmes/venv/Lib/site-packages/colorama/ansi.py new file mode 100644 index 0000000..7877658 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/basic python programmes/venv/Lib/site-packages/colorama/ansitowin32.py b/basic python programmes/venv/Lib/site-packages/colorama/ansitowin32.py new file mode 100644 index 0000000..359c92b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama/ansitowin32.py @@ -0,0 +1,257 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def __enter__(self, *args, **kwargs): + # special method lookup bypasses __getattr__/__getattribute__, see + # https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit + # thus, contextlib magic methods are not proxied via __getattr__ + return self.__wrapped.__enter__(*args, **kwargs) + + def __exit__(self, *args, **kwargs): + return self.__wrapped.__exit__(*args, **kwargs) + + def write(self, text): + self.__convertor.write(text) + + def isatty(self): + stream = self.__wrapped + if 'PYCHARM_HOSTED' in os.environ: + if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): + return True + try: + stream_isatty = stream.isatty + except AttributeError: + return False + else: + return stream_isatty() + + @property + def closed(self): + stream = self.__wrapped + try: + return stream.closed + except AttributeError: + return True + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not self.stream.closed and not self.stream.isatty()) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not self.stream.closed and self.stream.isatty() + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not self.stream.closed: + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/basic python programmes/venv/Lib/site-packages/colorama/initialise.py b/basic python programmes/venv/Lib/site-packages/colorama/initialise.py new file mode 100644 index 0000000..430d066 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama/initialise.py @@ -0,0 +1,80 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream diff --git a/basic python programmes/venv/Lib/site-packages/colorama/win32.py b/basic python programmes/venv/Lib/site-packages/colorama/win32.py new file mode 100644 index 0000000..c2d8360 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama/win32.py @@ -0,0 +1,152 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in + (_GetStdHandle(STDOUT), _GetStdHandle(STDERR))) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = _GetStdHandle(stream_id) + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = _GetStdHandle(stream_id) + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = _GetStdHandle(stream_id) + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = _GetStdHandle(stream_id) + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = _GetStdHandle(stream_id) + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/basic python programmes/venv/Lib/site-packages/colorama/winterm.py b/basic python programmes/venv/Lib/site-packages/colorama/winterm.py new file mode 100644 index 0000000..0fdb4ec --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/colorama/winterm.py @@ -0,0 +1,169 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + self._light = 0 + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + elif mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + elif mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/basic python programmes/venv/Lib/site-packages/easy-install.pth b/basic python programmes/venv/Lib/site-packages/easy-install.pth new file mode 100644 index 0000000..7cfbf40 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/easy-install.pth @@ -0,0 +1,2 @@ +./setuptools-39.1.0-py3.7.egg +./pip-10.0.1-py3.7.egg diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/DESCRIPTION.rst b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..b4a8f0f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/DESCRIPTION.rst @@ -0,0 +1,618 @@ +.. image:: https://raw.github.com/timothycrosley/isort/master/logo.png + :alt: isort + +######## + +.. image:: https://badge.fury.io/py/isort.svg + :target: https://badge.fury.io/py/isort + :alt: PyPI version + +.. image:: https://travis-ci.org/timothycrosley/isort.svg?branch=master + :target: https://travis-ci.org/timothycrosley/isort + :alt: Build Status + + +.. image:: https://coveralls.io/repos/timothycrosley/isort/badge.svg?branch=release%2F2.6.0&service=github + :target: https://coveralls.io/github/timothycrosley/isort?branch=release%2F2.6.0 + :alt: Coverage + +.. image:: https://img.shields.io/github/license/mashape/apistatus.svg + :target: https://pypi.python.org/pypi/hug/ + :alt: License + +.. image:: https://badges.gitter.im/Join%20Chat.svg + :alt: Join the chat at https://gitter.im/timothycrosley/isort + :target: https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + + +isort your python imports for you so you don't have to. + +isort is a Python utility / library to sort imports alphabetically, and automatically separated into sections. +It provides a command line utility, Python library and `plugins for various editors `_ to quickly sort all your imports. +It currently cleanly supports Python 2.7 - 3.6 without any dependencies. + +.. image:: https://raw.github.com/timothycrosley/isort/develop/example.gif + :alt: Example Usage + +Before isort: + +.. code-block:: python + + from my_lib import Object + + print("Hey") + + import os + + from my_lib import Object3 + + from my_lib import Object2 + + import sys + + from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14 + + import sys + + from __future__ import absolute_import + + from third_party import lib3 + + print("yo") + +After isort: + +.. code-block:: python + + from __future__ import absolute_import + + import os + import sys + + from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, + lib9, lib10, lib11, lib12, lib13, lib14, lib15) + + from my_lib import Object, Object2, Object3 + + print("Hey") + print("yo") + +Installing isort +================ + +Installing isort is as simple as: + +.. code-block:: bash + + pip install isort + +or if you prefer + +.. code-block:: bash + + easy_install isort + +Using isort +=========== + +**From the command line**: + +.. code-block:: bash + + isort mypythonfile.py mypythonfile2.py + +or recursively: + +.. code-block:: bash + + isort -rc . + +*which is equivalent to:* + +.. code-block:: bash + + isort **/*.py + +or to see the proposed changes without applying them: + +.. code-block:: bash + + isort mypythonfile.py --diff + +Finally, to atomically run isort against a project, only applying changes if they don't introduce syntax errors do: + +.. code-block:: bash + + isort -rc --atomic . + +(Note: this is disabled by default as it keeps isort from being able to run against code written using a different version of Python) + +**From within Python**: + +.. code-block:: bash + + from isort import SortImports + + SortImports("pythonfile.py") + +or: + +.. code-block:: bash + + from isort import SortImports + + new_contents = SortImports(file_contents=old_contents).output + +**From within Kate:** + +.. code-block:: bash + + ctrl+[ + +or: + +.. code-block:: bash + + menu > Python > Sort Imports + +Installing isort's Kate plugin +============================== + +For KDE 4.13+ / Pate 2.0+: + +.. code-block:: bash + + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_ui.rc --output-document ~/.kde/share/apps/kate/pate/isort_plugin_ui.rc + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/katepart_isort.desktop --output-document ~/.kde/share/kde4/services/katepart_isort.desktop + +For all older versions: + +.. code-block:: bash + + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_old.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py + +You will then need to restart kate and enable Python Plugins as well as the isort plugin itself. + +Installing isort's for your preferred text editor +================================================= + +Several plugins have been written that enable to use isort from within a variety of text-editors. +You can find a full list of them `on the isort wiki `_. +Additionally, I will enthusiastically accept pull requests that include plugins for other text editors +and add documentation for them as I am notified. + +How does isort work? +==================== + +isort parses specified files for global level import lines (imports outside of try / except blocks, functions, etc..) +and puts them all at the top of the file grouped together by the type of import: + +- Future +- Python Standard Library +- Third Party +- Current Python Project +- Explicitly Local (. before import, as in: ``from . import x``) +- Custom Separate Sections (Defined by forced_separate list in configuration file) +- Custom Sections (Defined by sections list in configuration file) + +Inside of each section the imports are sorted alphabetically. isort automatically removes duplicate python imports, +and wraps long from imports to the specified line length (defaults to 80). + +When will isort not work? +========================= + +If you ever have the situation where you need to have a try / except block in the middle of top-level imports or if +your import order is directly linked to precedence. + +For example: a common practice in Django settings files is importing * from various settings files to form +a new settings file. In this case if any of the imports change order you are changing the settings definition itself. + +However, you can configure isort to skip over just these files - or even to force certain imports to the top. + +Configuring isort +================= + +If you find the default isort settings do not work well for your project, isort provides several ways to adjust +the behavior. + +To configure isort for a single user create a ``~/.isort.cfg`` file: + +.. code-block:: ini + + [settings] + line_length=120 + force_to_top=file1.py,file2.py + skip=file3.py,file4.py + known_future_library=future,pies + known_standard_library=std,std2 + known_third_party=randomthirdparty + known_first_party=mylib1,mylib2 + indent=' ' + multi_line_output=3 + length_sort=1 + forced_separate=django.contrib,django.utils + default_section=FIRSTPARTY + no_lines_before=LOCALFOLDER + +Additionally, you can specify project level configuration simply by placing a ``.isort.cfg`` file at the root of your +project. isort will look up to 25 directories up, from the file it is ran against, to find a project specific configuration. + +Or, if you prefer, you can add an isort section to your project's ``setup.cfg`` or ``tox.ini`` file with any desired settings. + +You can then override any of these settings by using command line arguments, or by passing in override values to the +SortImports class. + +Finally, as of version 3.0 isort supports editorconfig files using the standard syntax defined here: +http://editorconfig.org/ + +Meaning you place any standard isort configuration parameters within a .editorconfig file under the ``*.py`` section +and they will be honored. + +For a full list of isort settings and their meanings `take a look at the isort wiki `_. + +Multi line output modes +======================= + +You will notice above the "multi_line_output" setting. This setting defines how from imports wrap when they extend +past the line_length limit and has 6 possible settings: + +**0 - Grid** + +.. code-block:: python + + from third_party import (lib1, lib2, lib3, + lib4, lib5, ...) + +**1 - Vertical** + +.. code-block:: python + + from third_party import (lib1, + lib2, + lib3 + lib4, + lib5, + ...) + +**2 - Hanging Indent** + +.. code-block:: python + + from third_party import \ + lib1, lib2, lib3, \ + lib4, lib5, lib6 + +**3 - Vertical Hanging Indent** + +.. code-block:: python + + from third_party import ( + lib1, + lib2, + lib3, + lib4, + ) + +**4 - Hanging Grid** + +.. code-block:: python + + from third_party import ( + lib1, lib2, lib3, lib4, + lib5, ...) + +**5 - Hanging Grid Grouped** + +.. code-block:: python + + from third_party import ( + lib1, lib2, lib3, lib4, + lib5, ... + ) + +**6 - NOQA** + +.. code-block:: python + + from third_party import lib1, lib2, lib3, ... # NOQA + +Alternatively, you can set ``force_single_line`` to ``True`` (``-sl`` on the command line) and every import will appear on its +own line: + +.. code-block:: python + + from third_party import lib1 + from third_party import lib2 + from third_party import lib3 + ... + +Note: to change the how constant indents appear - simply change the indent property with the following accepted formats: +* Number of spaces you would like. For example: 4 would cause standard 4 space indentation. +* Tab +* A verbatim string with quotes around it. + +For example: + +.. code-block:: python + + " " + +is equivalent to 4. + +For the import styles that use parentheses, you can control whether or not to +include a trailing comma after the last import with the ``include_trailing_comma`` +option (defaults to ``False``). + +Intelligently Balanced Multi-line Imports +========================================= + +As of isort 3.1.0 support for balanced multi-line imports has been added. +With this enabled isort will dynamically change the import length to the one that produces the most balanced grid, +while staying below the maximum import length defined. + +Example: + +.. code-block:: python + + from __future__ import (absolute_import, division, + print_function, unicode_literals) + +Will be produced instead of: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function, + unicode_literals) + +To enable this set ``balanced_wrapping`` to ``True`` in your config or pass the ``-e`` option into the command line utility. + +Custom Sections and Ordering +============================ + +You can change the section order with ``sections`` option from the default of: + +.. code-block:: ini + + FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER + +to your preference: + +.. code-block:: ini + + sections=FUTURE,STDLIB,FIRSTPARTY,THIRDPARTY,LOCALFOLDER + +You also can define your own sections and their order. + +Example: + +.. code-block:: ini + + known_django=django + known_pandas=pandas,numpy + sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,PANDAS,FIRSTPARTY,LOCALFOLDER + +would create two new sections with the specified known modules. + +The ``no_lines_before`` option will prevent the listed sections from being split from the previous section by an empty line. + +Example: + +.. code-block:: ini + + sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER + no_lines_before=LOCALFOLDER + +would produce a section with both FIRSTPARTY and LOCALFOLDER modules combined. + +Auto-comment import sections +============================ + +Some projects prefer to have import sections uniquely titled to aid in identifying the sections quickly +when visually scanning. isort can automate this as well. To do this simply set the ``import_heading_{section_name}`` +setting for each section you wish to have auto commented - to the desired comment. + +For Example: + +.. code-block:: ini + + import_heading_stdlib=Standard Library + import_heading_firstparty=My Stuff + +Would lead to output looking like the following: + +.. code-block:: python + + # Standard Library + import os + import sys + + import django.settings + + # My Stuff + import myproject.test + +Ordering by import length +========================= + +isort also makes it easy to sort your imports by length, simply by setting the ``length_sort`` option to ``True``. +This will result in the following output style: + +.. code-block:: python + + from evn.util import ( + Pool, + Dict, + Options, + Constant, + DecayDict, + UnexpectedCodePath, + ) + +Skip processing of imports (outside of configuration) +===================================================== + +To make isort ignore a single import simply add a comment at the end of the import line containing the text ``isort:skip``: + +.. code-block:: python + + import module # isort:skip + +or: + +.. code-block:: python + + from xyz import (abc, # isort:skip + yo, + hey) + +To make isort skip an entire file simply add ``isort:skip_file`` to the module's doc string: + +.. code-block:: python + + """ my_module.py + Best module ever + + isort:skip_file + """ + + import b + import a + +Adding an import to multiple files +================================== + +isort makes it easy to add an import statement across multiple files, while being assured it's correctly placed. + +From the command line: + +.. code-block:: bash + + isort -a "from __future__ import print_function" *.py + +from within Kate: + +.. code-block:: + + ctrl+] + +or: + +.. code-block:: + + menu > Python > Add Import + +Removing an import from multiple files +====================================== + +isort also makes it easy to remove an import from multiple files, without having to be concerned with how it was originally +formatted. + +From the command line: + +.. code-block:: bash + + isort -r "os.system" *.py + +from within Kate: + +.. code-block:: + + ctrl+shift+] + +or: + +.. code-block:: + + menu > Python > Remove Import + +Using isort to verify code +========================== + +The ``--check-only`` option +--------------------------- + +isort can also be used to used to verify that code is correctly formatted by running it with ``-c``. +Any files that contain incorrectly sorted and/or formatted imports will be outputted to ``stderr``. + +.. code-block:: bash + + isort **/*.py -c -vb + + SUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good! + ERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted. + +One great place this can be used is with a pre-commit git hook, such as this one by @acdha: + +https://gist.github.com/acdha/8717683 + +This can help to ensure a certain level of code quality throughout a project. + + +Git hook +-------- + +isort provides a hook function that can be integrated into your Git pre-commit script to check +Python code before committing. + +To cause the commit to fail if there are isort errors (strict mode), include the following in +``.git/hooks/pre-commit``: + +.. code-block:: python + + #!/usr/bin/env python + import sys + from isort.hooks import git_hook + + sys.exit(git_hook(strict=True)) + +If you just want to display warnings, but allow the commit to happen anyway, call ``git_hook`` without +the `strict` parameter. + +Setuptools integration +---------------------- + +Upon installation, isort enables a ``setuptools`` command that checks Python files +declared by your project. + +Running ``python setup.py isort`` on the command line will check the files +listed in your ``py_modules`` and ``packages``. If any warning is found, +the command will exit with an error code: + +.. code-block:: bash + + $ python setup.py isort + +Also, to allow users to be able to use the command without having to install +isort themselves, add isort to the setup_requires of your ``setup()`` like so: + +.. code-block:: python + + setup( + name="project", + packages=["project"], + + setup_requires=[ + "isort" + ] + ) + + +Why isort? +========== + +isort simply stands for import sort. It was originally called "sortImports" however I got tired of typing the extra +characters and came to the realization camelCase is not pythonic. + +I wrote isort because in an organization I used to work in the manager came in one day and decided all code must +have alphabetically sorted imports. The code base was huge - and he meant for us to do it by hand. However, being a +programmer - I'm too lazy to spend 8 hours mindlessly performing a function, but not too lazy to spend 16 +hours automating it. I was given permission to open source sortImports and here we are :) + +-------------------------------------------- + +Thanks and I hope you find isort useful! + +~Timothy Crosley + + diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/INSTALLER b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/LICENSE.txt b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/LICENSE.txt new file mode 100644 index 0000000..b5083a5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/METADATA b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/METADATA new file mode 100644 index 0000000..786d7e7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/METADATA @@ -0,0 +1,647 @@ +Metadata-Version: 2.0 +Name: isort +Version: 4.3.4 +Summary: A Python utility / library to sort Python imports. +Home-page: https://github.com/timothycrosley/isort +Author: Timothy Crosley +Author-email: timothy.crosley@gmail.com +License: MIT +Keywords: Refactor,Python,Python2,Python3,Refactoring,Imports,Sort,Clean +Platform: UNKNOWN +Classifier: Development Status :: 6 - Mature +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: Environment :: Console +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Requires-Dist: futures; python_version=="2.7" + +.. image:: https://raw.github.com/timothycrosley/isort/master/logo.png + :alt: isort + +######## + +.. image:: https://badge.fury.io/py/isort.svg + :target: https://badge.fury.io/py/isort + :alt: PyPI version + +.. image:: https://travis-ci.org/timothycrosley/isort.svg?branch=master + :target: https://travis-ci.org/timothycrosley/isort + :alt: Build Status + + +.. image:: https://coveralls.io/repos/timothycrosley/isort/badge.svg?branch=release%2F2.6.0&service=github + :target: https://coveralls.io/github/timothycrosley/isort?branch=release%2F2.6.0 + :alt: Coverage + +.. image:: https://img.shields.io/github/license/mashape/apistatus.svg + :target: https://pypi.python.org/pypi/hug/ + :alt: License + +.. image:: https://badges.gitter.im/Join%20Chat.svg + :alt: Join the chat at https://gitter.im/timothycrosley/isort + :target: https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + + +isort your python imports for you so you don't have to. + +isort is a Python utility / library to sort imports alphabetically, and automatically separated into sections. +It provides a command line utility, Python library and `plugins for various editors `_ to quickly sort all your imports. +It currently cleanly supports Python 2.7 - 3.6 without any dependencies. + +.. image:: https://raw.github.com/timothycrosley/isort/develop/example.gif + :alt: Example Usage + +Before isort: + +.. code-block:: python + + from my_lib import Object + + print("Hey") + + import os + + from my_lib import Object3 + + from my_lib import Object2 + + import sys + + from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14 + + import sys + + from __future__ import absolute_import + + from third_party import lib3 + + print("yo") + +After isort: + +.. code-block:: python + + from __future__ import absolute_import + + import os + import sys + + from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, + lib9, lib10, lib11, lib12, lib13, lib14, lib15) + + from my_lib import Object, Object2, Object3 + + print("Hey") + print("yo") + +Installing isort +================ + +Installing isort is as simple as: + +.. code-block:: bash + + pip install isort + +or if you prefer + +.. code-block:: bash + + easy_install isort + +Using isort +=========== + +**From the command line**: + +.. code-block:: bash + + isort mypythonfile.py mypythonfile2.py + +or recursively: + +.. code-block:: bash + + isort -rc . + +*which is equivalent to:* + +.. code-block:: bash + + isort **/*.py + +or to see the proposed changes without applying them: + +.. code-block:: bash + + isort mypythonfile.py --diff + +Finally, to atomically run isort against a project, only applying changes if they don't introduce syntax errors do: + +.. code-block:: bash + + isort -rc --atomic . + +(Note: this is disabled by default as it keeps isort from being able to run against code written using a different version of Python) + +**From within Python**: + +.. code-block:: bash + + from isort import SortImports + + SortImports("pythonfile.py") + +or: + +.. code-block:: bash + + from isort import SortImports + + new_contents = SortImports(file_contents=old_contents).output + +**From within Kate:** + +.. code-block:: bash + + ctrl+[ + +or: + +.. code-block:: bash + + menu > Python > Sort Imports + +Installing isort's Kate plugin +============================== + +For KDE 4.13+ / Pate 2.0+: + +.. code-block:: bash + + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_ui.rc --output-document ~/.kde/share/apps/kate/pate/isort_plugin_ui.rc + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/katepart_isort.desktop --output-document ~/.kde/share/kde4/services/katepart_isort.desktop + +For all older versions: + +.. code-block:: bash + + wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_old.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py + +You will then need to restart kate and enable Python Plugins as well as the isort plugin itself. + +Installing isort's for your preferred text editor +================================================= + +Several plugins have been written that enable to use isort from within a variety of text-editors. +You can find a full list of them `on the isort wiki `_. +Additionally, I will enthusiastically accept pull requests that include plugins for other text editors +and add documentation for them as I am notified. + +How does isort work? +==================== + +isort parses specified files for global level import lines (imports outside of try / except blocks, functions, etc..) +and puts them all at the top of the file grouped together by the type of import: + +- Future +- Python Standard Library +- Third Party +- Current Python Project +- Explicitly Local (. before import, as in: ``from . import x``) +- Custom Separate Sections (Defined by forced_separate list in configuration file) +- Custom Sections (Defined by sections list in configuration file) + +Inside of each section the imports are sorted alphabetically. isort automatically removes duplicate python imports, +and wraps long from imports to the specified line length (defaults to 80). + +When will isort not work? +========================= + +If you ever have the situation where you need to have a try / except block in the middle of top-level imports or if +your import order is directly linked to precedence. + +For example: a common practice in Django settings files is importing * from various settings files to form +a new settings file. In this case if any of the imports change order you are changing the settings definition itself. + +However, you can configure isort to skip over just these files - or even to force certain imports to the top. + +Configuring isort +================= + +If you find the default isort settings do not work well for your project, isort provides several ways to adjust +the behavior. + +To configure isort for a single user create a ``~/.isort.cfg`` file: + +.. code-block:: ini + + [settings] + line_length=120 + force_to_top=file1.py,file2.py + skip=file3.py,file4.py + known_future_library=future,pies + known_standard_library=std,std2 + known_third_party=randomthirdparty + known_first_party=mylib1,mylib2 + indent=' ' + multi_line_output=3 + length_sort=1 + forced_separate=django.contrib,django.utils + default_section=FIRSTPARTY + no_lines_before=LOCALFOLDER + +Additionally, you can specify project level configuration simply by placing a ``.isort.cfg`` file at the root of your +project. isort will look up to 25 directories up, from the file it is ran against, to find a project specific configuration. + +Or, if you prefer, you can add an isort section to your project's ``setup.cfg`` or ``tox.ini`` file with any desired settings. + +You can then override any of these settings by using command line arguments, or by passing in override values to the +SortImports class. + +Finally, as of version 3.0 isort supports editorconfig files using the standard syntax defined here: +http://editorconfig.org/ + +Meaning you place any standard isort configuration parameters within a .editorconfig file under the ``*.py`` section +and they will be honored. + +For a full list of isort settings and their meanings `take a look at the isort wiki `_. + +Multi line output modes +======================= + +You will notice above the "multi_line_output" setting. This setting defines how from imports wrap when they extend +past the line_length limit and has 6 possible settings: + +**0 - Grid** + +.. code-block:: python + + from third_party import (lib1, lib2, lib3, + lib4, lib5, ...) + +**1 - Vertical** + +.. code-block:: python + + from third_party import (lib1, + lib2, + lib3 + lib4, + lib5, + ...) + +**2 - Hanging Indent** + +.. code-block:: python + + from third_party import \ + lib1, lib2, lib3, \ + lib4, lib5, lib6 + +**3 - Vertical Hanging Indent** + +.. code-block:: python + + from third_party import ( + lib1, + lib2, + lib3, + lib4, + ) + +**4 - Hanging Grid** + +.. code-block:: python + + from third_party import ( + lib1, lib2, lib3, lib4, + lib5, ...) + +**5 - Hanging Grid Grouped** + +.. code-block:: python + + from third_party import ( + lib1, lib2, lib3, lib4, + lib5, ... + ) + +**6 - NOQA** + +.. code-block:: python + + from third_party import lib1, lib2, lib3, ... # NOQA + +Alternatively, you can set ``force_single_line`` to ``True`` (``-sl`` on the command line) and every import will appear on its +own line: + +.. code-block:: python + + from third_party import lib1 + from third_party import lib2 + from third_party import lib3 + ... + +Note: to change the how constant indents appear - simply change the indent property with the following accepted formats: +* Number of spaces you would like. For example: 4 would cause standard 4 space indentation. +* Tab +* A verbatim string with quotes around it. + +For example: + +.. code-block:: python + + " " + +is equivalent to 4. + +For the import styles that use parentheses, you can control whether or not to +include a trailing comma after the last import with the ``include_trailing_comma`` +option (defaults to ``False``). + +Intelligently Balanced Multi-line Imports +========================================= + +As of isort 3.1.0 support for balanced multi-line imports has been added. +With this enabled isort will dynamically change the import length to the one that produces the most balanced grid, +while staying below the maximum import length defined. + +Example: + +.. code-block:: python + + from __future__ import (absolute_import, division, + print_function, unicode_literals) + +Will be produced instead of: + +.. code-block:: python + + from __future__ import (absolute_import, division, print_function, + unicode_literals) + +To enable this set ``balanced_wrapping`` to ``True`` in your config or pass the ``-e`` option into the command line utility. + +Custom Sections and Ordering +============================ + +You can change the section order with ``sections`` option from the default of: + +.. code-block:: ini + + FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER + +to your preference: + +.. code-block:: ini + + sections=FUTURE,STDLIB,FIRSTPARTY,THIRDPARTY,LOCALFOLDER + +You also can define your own sections and their order. + +Example: + +.. code-block:: ini + + known_django=django + known_pandas=pandas,numpy + sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,PANDAS,FIRSTPARTY,LOCALFOLDER + +would create two new sections with the specified known modules. + +The ``no_lines_before`` option will prevent the listed sections from being split from the previous section by an empty line. + +Example: + +.. code-block:: ini + + sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER + no_lines_before=LOCALFOLDER + +would produce a section with both FIRSTPARTY and LOCALFOLDER modules combined. + +Auto-comment import sections +============================ + +Some projects prefer to have import sections uniquely titled to aid in identifying the sections quickly +when visually scanning. isort can automate this as well. To do this simply set the ``import_heading_{section_name}`` +setting for each section you wish to have auto commented - to the desired comment. + +For Example: + +.. code-block:: ini + + import_heading_stdlib=Standard Library + import_heading_firstparty=My Stuff + +Would lead to output looking like the following: + +.. code-block:: python + + # Standard Library + import os + import sys + + import django.settings + + # My Stuff + import myproject.test + +Ordering by import length +========================= + +isort also makes it easy to sort your imports by length, simply by setting the ``length_sort`` option to ``True``. +This will result in the following output style: + +.. code-block:: python + + from evn.util import ( + Pool, + Dict, + Options, + Constant, + DecayDict, + UnexpectedCodePath, + ) + +Skip processing of imports (outside of configuration) +===================================================== + +To make isort ignore a single import simply add a comment at the end of the import line containing the text ``isort:skip``: + +.. code-block:: python + + import module # isort:skip + +or: + +.. code-block:: python + + from xyz import (abc, # isort:skip + yo, + hey) + +To make isort skip an entire file simply add ``isort:skip_file`` to the module's doc string: + +.. code-block:: python + + """ my_module.py + Best module ever + + isort:skip_file + """ + + import b + import a + +Adding an import to multiple files +================================== + +isort makes it easy to add an import statement across multiple files, while being assured it's correctly placed. + +From the command line: + +.. code-block:: bash + + isort -a "from __future__ import print_function" *.py + +from within Kate: + +.. code-block:: + + ctrl+] + +or: + +.. code-block:: + + menu > Python > Add Import + +Removing an import from multiple files +====================================== + +isort also makes it easy to remove an import from multiple files, without having to be concerned with how it was originally +formatted. + +From the command line: + +.. code-block:: bash + + isort -r "os.system" *.py + +from within Kate: + +.. code-block:: + + ctrl+shift+] + +or: + +.. code-block:: + + menu > Python > Remove Import + +Using isort to verify code +========================== + +The ``--check-only`` option +--------------------------- + +isort can also be used to used to verify that code is correctly formatted by running it with ``-c``. +Any files that contain incorrectly sorted and/or formatted imports will be outputted to ``stderr``. + +.. code-block:: bash + + isort **/*.py -c -vb + + SUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good! + ERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted. + +One great place this can be used is with a pre-commit git hook, such as this one by @acdha: + +https://gist.github.com/acdha/8717683 + +This can help to ensure a certain level of code quality throughout a project. + + +Git hook +-------- + +isort provides a hook function that can be integrated into your Git pre-commit script to check +Python code before committing. + +To cause the commit to fail if there are isort errors (strict mode), include the following in +``.git/hooks/pre-commit``: + +.. code-block:: python + + #!/usr/bin/env python + import sys + from isort.hooks import git_hook + + sys.exit(git_hook(strict=True)) + +If you just want to display warnings, but allow the commit to happen anyway, call ``git_hook`` without +the `strict` parameter. + +Setuptools integration +---------------------- + +Upon installation, isort enables a ``setuptools`` command that checks Python files +declared by your project. + +Running ``python setup.py isort`` on the command line will check the files +listed in your ``py_modules`` and ``packages``. If any warning is found, +the command will exit with an error code: + +.. code-block:: bash + + $ python setup.py isort + +Also, to allow users to be able to use the command without having to install +isort themselves, add isort to the setup_requires of your ``setup()`` like so: + +.. code-block:: python + + setup( + name="project", + packages=["project"], + + setup_requires=[ + "isort" + ] + ) + + +Why isort? +========== + +isort simply stands for import sort. It was originally called "sortImports" however I got tired of typing the extra +characters and came to the realization camelCase is not pythonic. + +I wrote isort because in an organization I used to work in the manager came in one day and decided all code must +have alphabetically sorted imports. The code base was huge - and he meant for us to do it by hand. However, being a +programmer - I'm too lazy to spend 8 hours mindlessly performing a function, but not too lazy to spend 16 +hours automating it. I was given permission to open source sortImports and here we are :) + +-------------------------------------------- + +Thanks and I hope you find isort useful! + +~Timothy Crosley + + diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/RECORD b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/RECORD new file mode 100644 index 0000000..76d17ad --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/RECORD @@ -0,0 +1,28 @@ +isort/__init__.py,sha256=JEPtRdsZdle6TV8ZHxBj73OuD2iLUY4PXDn71QBVwQc,1379 +isort/__main__.py,sha256=8bohcK5XCQlgF4HhXQhhPJBmaC2S4GqzqFwhdAui3QI,76 +isort/hooks.py,sha256=WzFb8eSZAh2feC5HpHDA5MjibzrtRlM93ZVgNX6k4LY,2808 +isort/isort.py,sha256=Lf1izswgqyjV-AdIozRT4_XPbqKQ8b6zU0_P-jiBB34,52773 +isort/main.py,sha256=ZRUF2J7brqdk7V0s7u0rrZ_MKJbjthOZPbKvGP67rc0,20087 +isort/natural.py,sha256=hlcWsGKfIUC4Atjp5IIqDCmg1madY6ave9oNiTGjJ0Q,1794 +isort/pie_slice.py,sha256=HOfK4ZHA2j1bqVSGzefhcT5jP64_Ldl4x6vNSRUNdT4,13181 +isort/pylama_isort.py,sha256=wF6NOEVuibme0l-5pH9pCW1j4vGaFamuwll494TnzDI,785 +isort/settings.py,sha256=nDQoyLEHXAwD_MmanHUgVvCwAcLYmQcHUeU4cenkMew,14224 +isort-4.3.4.dist-info/DESCRIPTION.rst,sha256=ES1jpOSviMvMyLAONgeXykr1dK-R3PpH9pbvtXirHDo,16693 +isort-4.3.4.dist-info/LICENSE.txt,sha256=BjKUABw9Uj26y6ud1UrCKZgnVsyvWSylMkCysM3YIGU,1089 +isort-4.3.4.dist-info/METADATA,sha256=7xVP3DP8g0U3EvDrtEe7yGoJ82-IjCAurOUKQnhHaYA,17908 +isort-4.3.4.dist-info/RECORD,, +isort-4.3.4.dist-info/WHEEL,sha256=8Lm45v9gcYRm70DrgFGVe4WsUtUMi1_0Tso1hqPGMjA,92 +isort-4.3.4.dist-info/entry_points.txt,sha256=2M99eSFpnteDm3ekW8jya2a3A0-vFntKdT1fP93Tyks,148 +isort-4.3.4.dist-info/metadata.json,sha256=JSIp2xtf3zDjLBPcoutZHMKenMu4rM4ysDS_ZF79U8I,1694 +isort-4.3.4.dist-info/top_level.txt,sha256=mrBLoVpJnQWBbnMOSdzkjN1E9Z-e3Zd-MRlo88bstUk,6 +../../Scripts/isort.exe,sha256=WKb0quMRKVt6ideI7Em69fknsXnXYsLh9_wYJYUqfo4,102752 +isort-4.3.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +isort/__pycache__/hooks.cpython-37.pyc,, +isort/__pycache__/isort.cpython-37.pyc,, +isort/__pycache__/main.cpython-37.pyc,, +isort/__pycache__/natural.cpython-37.pyc,, +isort/__pycache__/pie_slice.cpython-37.pyc,, +isort/__pycache__/pylama_isort.cpython-37.pyc,, +isort/__pycache__/settings.cpython-37.pyc,, +isort/__pycache__/__init__.cpython-37.pyc,, +isort/__pycache__/__main__.cpython-37.pyc,, diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/WHEEL b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/WHEEL new file mode 100644 index 0000000..6261a26 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/entry_points.txt b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/entry_points.txt new file mode 100644 index 0000000..3a77a18 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/entry_points.txt @@ -0,0 +1,9 @@ +[console_scripts] +isort = isort.main:main + +[distutils.commands] +isort = isort.main:ISortCommand + +[pylama.linter] +isort = isort.pylama_isort:Linter + diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/metadata.json b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/metadata.json new file mode 100644 index 0000000..9b0b662 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 6 - Mature", "Intended Audience :: Developers", "Natural Language :: English", "Environment :: Console", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries", "Topic :: Utilities"], "extensions": {"python.commands": {"wrap_console": {"isort": "isort.main:main"}}, "python.details": {"contacts": [{"email": "timothy.crosley@gmail.com", "name": "Timothy Crosley", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://github.com/timothycrosley/isort"}}, "python.exports": {"console_scripts": {"isort": "isort.main:main"}, "distutils.commands": {"isort": "isort.main:ISortCommand"}, "pylama.linter": {"isort": "isort.pylama_isort:Linter"}}}, "extras": [], "generator": "bdist_wheel (0.30.0)", "keywords": ["Refactor", "Python", "Python2", "Python3", "Refactoring", "Imports", "Sort", "Clean"], "license": "MIT", "metadata_version": "2.0", "name": "isort", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", "run_requires": [{"environment": "python_version==\"2.7\"", "requires": ["futures"]}], "summary": "A Python utility / library to sort Python imports.", "test_requires": [{"requires": ["mock", "pytest"]}], "version": "4.3.4"} \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/top_level.txt new file mode 100644 index 0000000..2a79243 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort-4.3.4.dist-info/top_level.txt @@ -0,0 +1 @@ +isort diff --git a/basic python programmes/venv/Lib/site-packages/isort/__init__.py b/basic python programmes/venv/Lib/site-packages/isort/__init__.py new file mode 100644 index 0000000..4f1adaa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/__init__.py @@ -0,0 +1,28 @@ +"""__init__.py. + +Defines the isort module to include the SortImports utility class as well as any defined settings. + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" + +from __future__ import absolute_import, division, print_function, unicode_literals + +from . import settings # noqa: F401 +from .isort import SortImports # noqa: F401 + +__version__ = "4.3.4" diff --git a/basic python programmes/venv/Lib/site-packages/isort/__main__.py b/basic python programmes/venv/Lib/site-packages/isort/__main__.py new file mode 100644 index 0000000..186c98e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/__main__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from isort.main import main + +main() diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..0d2f237 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/__main__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000..61ea1aa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/__main__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/hooks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/hooks.cpython-37.pyc new file mode 100644 index 0000000..41d8b04 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/hooks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/isort.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/isort.cpython-37.pyc new file mode 100644 index 0000000..1262e96 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/isort.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/main.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/main.cpython-37.pyc new file mode 100644 index 0000000..499409b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/main.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/natural.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/natural.cpython-37.pyc new file mode 100644 index 0000000..4f9e67a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/natural.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/pie_slice.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/pie_slice.cpython-37.pyc new file mode 100644 index 0000000..d7ec994 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/pie_slice.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/pylama_isort.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/pylama_isort.cpython-37.pyc new file mode 100644 index 0000000..081506b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/pylama_isort.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/__pycache__/settings.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/settings.cpython-37.pyc new file mode 100644 index 0000000..126ac35 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/isort/__pycache__/settings.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/isort/hooks.py b/basic python programmes/venv/Lib/site-packages/isort/hooks.py new file mode 100644 index 0000000..15b6d40 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/hooks.py @@ -0,0 +1,82 @@ +"""isort.py. + +Defines a git hook to allow pre-commit warnings and errors about import order. + +usage: + exit_code = git_hook(strict=True) + +Copyright (C) 2015 Helen Sherwood-Taylor + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +import subprocess + +from isort import SortImports + + +def get_output(command): + """ + Run a command and return raw output + + :param str command: the command to run + :returns: the stdout output of the command + """ + return subprocess.check_output(command.split()) + + +def get_lines(command): + """ + Run a command and return lines of output + + :param str command: the command to run + :returns: list of whitespace-stripped lines output by command + """ + stdout = get_output(command) + return [line.strip().decode('utf-8') for line in stdout.splitlines()] + + +def git_hook(strict=False): + """ + Git pre-commit hook to check staged files for isort errors + + :param bool strict - if True, return number of errors on exit, + causing the hook to fail. If False, return zero so it will + just act as a warning. + + :return number of errors if in strict mode, 0 otherwise. + """ + + # Get list of files modified and staged + diff_cmd = "git diff-index --cached --name-only --diff-filter=ACMRTUXB HEAD" + files_modified = get_lines(diff_cmd) + + errors = 0 + for filename in files_modified: + if filename.endswith('.py'): + # Get the staged contents of the file + staged_cmd = "git show :%s" % filename + staged_contents = get_output(staged_cmd) + + sort = SortImports( + file_path=filename, + file_contents=staged_contents.decode(), + check=True + ) + + if sort.incorrectly_sorted: + errors += 1 + + return errors if strict else 0 diff --git a/basic python programmes/venv/Lib/site-packages/isort/isort.py b/basic python programmes/venv/Lib/site-packages/isort/isort.py new file mode 100644 index 0000000..3ba3e7d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/isort.py @@ -0,0 +1,1037 @@ +"""isort.py. + +Exposes a simple library to sort through imports within Python code + +usage: + SortImports(file_name) +or: + sorted = SortImports(file_contents=file_contents).output + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +from __future__ import absolute_import, division, print_function, unicode_literals + +import copy +import io +import itertools +import os +import re +import sys +import sysconfig +from collections import OrderedDict, namedtuple +from datetime import datetime +from difflib import unified_diff +from fnmatch import fnmatch +from glob import glob + +from . import settings +from .natural import nsorted +from .pie_slice import OrderedSet, input, itemsview + +KNOWN_SECTION_MAPPING = { + 'STDLIB': 'STANDARD_LIBRARY', + 'FUTURE': 'FUTURE_LIBRARY', + 'FIRSTPARTY': 'FIRST_PARTY', + 'THIRDPARTY': 'THIRD_PARTY', +} + + +class SortImports(object): + incorrectly_sorted = False + skipped = False + + def __init__(self, file_path=None, file_contents=None, write_to_stdout=False, check=False, + show_diff=False, settings_path=None, ask_to_apply=False, **setting_overrides): + if not settings_path and file_path: + settings_path = os.path.dirname(os.path.abspath(file_path)) + settings_path = settings_path or os.getcwd() + + self.config = settings.from_path(settings_path).copy() + for key, value in itemsview(setting_overrides): + access_key = key.replace('not_', '').lower() + # The sections config needs to retain order and can't be converted to a set. + if access_key != 'sections' and type(self.config.get(access_key)) in (list, tuple): + if key.startswith('not_'): + self.config[access_key] = list(set(self.config[access_key]).difference(value)) + else: + self.config[access_key] = list(set(self.config[access_key]).union(value)) + else: + self.config[key] = value + + if self.config['force_alphabetical_sort']: + self.config.update({'force_alphabetical_sort_within_sections': True, + 'no_sections': True, + 'lines_between_types': 1, + 'from_first': True}) + + indent = str(self.config['indent']) + if indent.isdigit(): + indent = " " * int(indent) + else: + indent = indent.strip("'").strip('"') + if indent.lower() == "tab": + indent = "\t" + self.config['indent'] = indent + + self.config['comment_prefix'] = self.config['comment_prefix'].strip("'").strip('"') + + self.place_imports = {} + self.import_placements = {} + self.remove_imports = [self._format_simplified(removal) for removal in self.config['remove_imports']] + self.add_imports = [self._format_natural(addition) for addition in self.config['add_imports']] + self._section_comments = ["# " + value for key, value in itemsview(self.config) if + key.startswith('import_heading') and value] + + self.file_encoding = 'utf-8' + file_name = file_path + self.file_path = file_path or "" + if file_path: + file_path = os.path.abspath(file_path) + if settings.should_skip(file_path, self.config): + self.skipped = True + if self.config['verbose']: + print("WARNING: {0} was skipped as it's listed in 'skip' setting" + " or matches a glob in 'skip_glob' setting".format(file_path)) + file_contents = None + elif not file_contents: + self.file_path = file_path + self.file_encoding = coding_check(file_path) + with io.open(file_path, encoding=self.file_encoding, newline='') as file_to_import_sort: + file_contents = file_to_import_sort.read() + + if file_contents is None or ("isort:" + "skip_file") in file_contents: + self.skipped = True + self.output = None + return + + if self.config['line_ending']: + self.line_separator = self.config['line_ending'] + else: + if '\r\n' in file_contents: + self.line_separator = '\r\n' + elif '\r' in file_contents: + self.line_separator = '\r' + else: + self.line_separator = '\n' + self.in_lines = file_contents.split(self.line_separator) + self.original_length = len(self.in_lines) + if (self.original_length > 1 or self.in_lines[:1] not in ([], [""])) or self.config['force_adds']: + for add_import in self.add_imports: + self.in_lines.append(add_import) + self.number_of_lines = len(self.in_lines) + + self.out_lines = [] + self.comments = {'from': {}, 'straight': {}, 'nested': {}, 'above': {'straight': {}, 'from': {}}} + self.imports = OrderedDict() + self.as_map = {} + + section_names = self.config['sections'] + self.sections = namedtuple('Sections', section_names)(*[name for name in section_names]) + for section in itertools.chain(self.sections, self.config['forced_separate']): + self.imports[section] = {'straight': OrderedSet(), 'from': OrderedDict()} + + self.known_patterns = [] + for placement in reversed(self.sections): + known_placement = KNOWN_SECTION_MAPPING.get(placement, placement) + config_key = 'known_{0}'.format(known_placement.lower()) + known_patterns = self.config.get(config_key, []) + for known_pattern in known_patterns: + self.known_patterns.append((re.compile('^' + known_pattern.replace('*', '.*').replace('?', '.?') + '$'), + placement)) + + self.index = 0 + self.import_index = -1 + self._first_comment_index_start = -1 + self._first_comment_index_end = -1 + self._parse() + if self.import_index != -1: + self._add_formatted_imports() + self.length_change = len(self.out_lines) - self.original_length + while self.out_lines and self.out_lines[-1].strip() == "": + self.out_lines.pop(-1) + self.out_lines.append("") + self.output = self.line_separator.join(self.out_lines) + if self.config['atomic']: + try: + compile(self._strip_top_comments(self.out_lines, self.line_separator), self.file_path, 'exec', 0, 1) + except SyntaxError: + self.output = file_contents + self.incorrectly_sorted = True + try: + compile(self._strip_top_comments(self.in_lines, self.line_separator), self.file_path, 'exec', 0, 1) + print("ERROR: {0} isort would have introduced syntax errors, please report to the project!". + format(self.file_path)) + except SyntaxError: + print("ERROR: {0} File contains syntax errors.".format(self.file_path)) + + return + if check: + check_output = self.output + check_against = file_contents + if self.config['ignore_whitespace']: + check_output = check_output.replace(self.line_separator, "").replace(" ", "") + check_against = check_against.replace(self.line_separator, "").replace(" ", "") + + if check_output == check_against: + if self.config['verbose']: + print("SUCCESS: {0} Everything Looks Good!".format(self.file_path)) + return + + print("ERROR: {0} Imports are incorrectly sorted.".format(self.file_path)) + self.incorrectly_sorted = True + if show_diff or self.config['show_diff']: + self._show_diff(file_contents) + elif write_to_stdout: + sys.stdout.write(self.output) + elif file_name and not check: + if self.output == file_contents: + return + + if ask_to_apply: + self._show_diff(file_contents) + answer = None + while answer not in ('yes', 'y', 'no', 'n', 'quit', 'q'): + answer = input("Apply suggested changes to '{0}' [y/n/q]? ".format(self.file_path)).lower() + if answer in ('no', 'n'): + return + if answer in ('quit', 'q'): + sys.exit(1) + with io.open(self.file_path, encoding=self.file_encoding, mode='w', newline='') as output_file: + print("Fixing {0}".format(self.file_path)) + output_file.write(self.output) + + def _show_diff(self, file_contents): + for line in unified_diff( + file_contents.splitlines(1), + self.output.splitlines(1), + fromfile=self.file_path + ':before', + tofile=self.file_path + ':after', + fromfiledate=str(datetime.fromtimestamp(os.path.getmtime(self.file_path)) + if self.file_path else datetime.now()), + tofiledate=str(datetime.now()) + ): + sys.stdout.write(line) + + @staticmethod + def _strip_top_comments(lines, line_separator): + """Strips # comments that exist at the top of the given lines""" + lines = copy.copy(lines) + while lines and lines[0].startswith("#"): + lines = lines[1:] + return line_separator.join(lines) + + def place_module(self, module_name): + """Tries to determine if a module is a python std import, third party import, or project code: + + if it can't determine - it assumes it is project code + + """ + for forced_separate in self.config['forced_separate']: + # Ensure all forced_separate patterns will match to end of string + path_glob = forced_separate + if not forced_separate.endswith('*'): + path_glob = '%s*' % forced_separate + + if fnmatch(module_name, path_glob) or fnmatch(module_name, '.' + path_glob): + return forced_separate + + if module_name.startswith("."): + return self.sections.LOCALFOLDER + + # Try to find most specific placement instruction match (if any) + parts = module_name.split('.') + module_names_to_check = ['.'.join(parts[:first_k]) for first_k in range(len(parts), 0, -1)] + for module_name_to_check in module_names_to_check: + for pattern, placement in self.known_patterns: + if pattern.match(module_name_to_check): + return placement + + # Use a copy of sys.path to avoid any unintended modifications + # to it - e.g. `+=` used below will change paths in place and + # if not copied, consequently sys.path, which will grow unbounded + # with duplicates on every call to this method. + paths = list(sys.path) + virtual_env = self.config.get('virtual_env') or os.environ.get('VIRTUAL_ENV') + virtual_env_src = False + if virtual_env: + paths += [path for path in glob('{0}/lib/python*/site-packages'.format(virtual_env)) + if path not in paths] + paths += [path for path in glob('{0}/src/*'.format(virtual_env)) if os.path.isdir(path)] + virtual_env_src = '{0}/src/'.format(virtual_env) + + # handle case-insensitive paths on windows + stdlib_lib_prefix = os.path.normcase(sysconfig.get_paths()['stdlib']) + + for prefix in paths: + package_path = "/".join((prefix, module_name.split(".")[0])) + is_module = (exists_case_sensitive(package_path + ".py") or + exists_case_sensitive(package_path + ".so")) + is_package = exists_case_sensitive(package_path) and os.path.isdir(package_path) + if is_module or is_package: + if ('site-packages' in prefix or 'dist-packages' in prefix or + (virtual_env and virtual_env_src in prefix)): + return self.sections.THIRDPARTY + elif os.path.normcase(prefix).startswith(stdlib_lib_prefix): + return self.sections.STDLIB + else: + return self.config['default_section'] + + return self.config['default_section'] + + def _get_line(self): + """Returns the current line from the file while incrementing the index.""" + line = self.in_lines[self.index] + self.index += 1 + return line + + @staticmethod + def _import_type(line): + """If the current line is an import line it will return its type (from or straight)""" + if "isort:skip" in line: + return + elif line.startswith('import '): + return "straight" + elif line.startswith('from '): + return "from" + + def _at_end(self): + """returns True if we are at the end of the file.""" + return self.index == self.number_of_lines + + @staticmethod + def _module_key(module_name, config, sub_imports=False, ignore_case=False): + prefix = "" + if ignore_case: + module_name = str(module_name).lower() + else: + module_name = str(module_name) + + if sub_imports and config['order_by_type']: + if module_name.isupper() and len(module_name) > 1: + prefix = "A" + elif module_name[0:1].isupper(): + prefix = "B" + else: + prefix = "C" + module_name = module_name.lower() + return "{0}{1}{2}".format(module_name in config['force_to_top'] and "A" or "B", prefix, + config['length_sort'] and (str(len(module_name)) + ":" + module_name) or module_name) + + def _add_comments(self, comments, original_string=""): + """ + Returns a string with comments added + """ + return comments and "{0}{1} {2}".format(self._strip_comments(original_string)[0], + self.config['comment_prefix'], + "; ".join(comments)) or original_string + + def _wrap(self, line): + """ + Returns an import wrapped to the specified line-length, if possible. + """ + wrap_mode = self.config['multi_line_output'] + if len(line) > self.config['line_length'] and wrap_mode != settings.WrapModes.NOQA: + line_without_comment = line + comment = None + if '#' in line: + line_without_comment, comment = line.split('#', 1) + for splitter in ("import ", ".", "as "): + exp = r"\b" + re.escape(splitter) + r"\b" + if re.search(exp, line_without_comment) and not line_without_comment.strip().startswith(splitter): + line_parts = re.split(exp, line_without_comment) + if comment: + line_parts[-1] = '{0}#{1}'.format(line_parts[-1], comment) + next_line = [] + while (len(line) + 2) > (self.config['wrap_length'] or self.config['line_length']) and line_parts: + next_line.append(line_parts.pop()) + line = splitter.join(line_parts) + if not line: + line = next_line.pop() + + cont_line = self._wrap(self.config['indent'] + splitter.join(next_line).lstrip()) + if self.config['use_parentheses']: + output = "{0}{1}({2}{3}{4}{5})".format( + line, splitter, self.line_separator, cont_line, + "," if self.config['include_trailing_comma'] else "", + self.line_separator if wrap_mode in ( + settings.WrapModes.VERTICAL_HANGING_INDENT, + settings.WrapModes.VERTICAL_GRID_GROUPED, + ) else "") + lines = output.split(self.line_separator) + if self.config['comment_prefix'] in lines[-1] and lines[-1].endswith(')'): + line, comment = lines[-1].split(self.config['comment_prefix'], 1) + lines[-1] = line + ')' + self.config['comment_prefix'] + comment[:-1] + return self.line_separator.join(lines) + return "{0}{1}\\{2}{3}".format(line, splitter, self.line_separator, cont_line) + elif len(line) > self.config['line_length'] and wrap_mode == settings.WrapModes.NOQA: + if "# NOQA" not in line: + return "{0}{1} NOQA".format(line, self.config['comment_prefix']) + + return line + + def _add_straight_imports(self, straight_modules, section, section_output): + for module in straight_modules: + if module in self.remove_imports: + continue + + if module in self.as_map: + import_definition = '' + if self.config['keep_direct_and_as_imports']: + import_definition = "import {0}\n".format(module) + import_definition += "import {0} as {1}".format(module, self.as_map[module]) + else: + import_definition = "import {0}".format(module) + + comments_above = self.comments['above']['straight'].pop(module, None) + if comments_above: + section_output.extend(comments_above) + section_output.append(self._add_comments(self.comments['straight'].get(module), import_definition)) + + def _add_from_imports(self, from_modules, section, section_output, ignore_case): + for module in from_modules: + if module in self.remove_imports: + continue + + import_start = "from {0} import ".format(module) + from_imports = list(self.imports[section]['from'][module]) + if not self.config['no_inline_sort'] or self.config['force_single_line']: + from_imports = nsorted(from_imports, key=lambda key: self._module_key(key, self.config, True, ignore_case)) + if self.remove_imports: + from_imports = [line for line in from_imports if not "{0}.{1}".format(module, line) in + self.remove_imports] + + sub_modules = ['{0}.{1}'.format(module, from_import) for from_import in from_imports] + as_imports = dict((from_import, "{0} as {1}".format(from_import, self.as_map[sub_module])) for + from_import, sub_module in zip(from_imports, sub_modules) if sub_module in self.as_map) + if self.config['combine_as_imports'] and not ("*" in from_imports and self.config['combine_star']): + for from_import in copy.copy(from_imports): + if from_import in as_imports: + from_imports[from_imports.index(from_import)] = as_imports.pop(from_import) + + while from_imports: + comments = self.comments['from'].pop(module, ()) + if "*" in from_imports and self.config['combine_star']: + import_statement = self._wrap(self._add_comments(comments, "{0}*".format(import_start))) + from_imports = None + elif self.config['force_single_line']: + import_statements = [] + while from_imports: + from_import = from_imports.pop(0) + if from_import in as_imports: + from_comments = self.comments['straight'].get('{}.{}'.format(module, from_import)) + import_statements.append(self._add_comments(from_comments, + self._wrap(import_start + as_imports[from_import]))) + continue + single_import_line = self._add_comments(comments, import_start + from_import) + comment = self.comments['nested'].get(module, {}).pop(from_import, None) + if comment: + single_import_line += "{0} {1}".format(comments and ";" or self.config['comment_prefix'], + comment) + import_statements.append(self._wrap(single_import_line)) + comments = None + import_statement = self.line_separator.join(import_statements) + else: + while from_imports and from_imports[0] in as_imports: + from_import = from_imports.pop(0) + from_comments = self.comments['straight'].get('{}.{}'.format(module, from_import)) + section_output.append(self._add_comments(from_comments, + self._wrap(import_start + as_imports[from_import]))) + + star_import = False + if "*" in from_imports: + section_output.append(self._add_comments(comments, "{0}*".format(import_start))) + from_imports.remove('*') + star_import = True + comments = None + + for from_import in copy.copy(from_imports): + if from_import in as_imports: + continue + comment = self.comments['nested'].get(module, {}).pop(from_import, None) + if comment: + single_import_line = self._add_comments(comments, import_start + from_import) + single_import_line += "{0} {1}".format(comments and ";" or self.config['comment_prefix'], + comment) + above_comments = self.comments['above']['from'].pop(module, None) + if above_comments: + section_output.extend(above_comments) + section_output.append(self._wrap(single_import_line)) + from_imports.remove(from_import) + comments = None + + from_import_section = [] + while from_imports and from_imports[0] not in as_imports: + from_import_section.append(from_imports.pop(0)) + if star_import: + import_statement = import_start + (", ").join(from_import_section) + else: + import_statement = self._add_comments(comments, import_start + (", ").join(from_import_section)) + if not from_import_section: + import_statement = "" + + do_multiline_reformat = False + + force_grid_wrap = self.config['force_grid_wrap'] + if force_grid_wrap and len(from_import_section) >= force_grid_wrap: + do_multiline_reformat = True + + if len(import_statement) > self.config['line_length'] and len(from_import_section) > 1: + do_multiline_reformat = True + + # If line too long AND have imports AND we are NOT using GRID or VERTICAL wrap modes + if (len(import_statement) > self.config['line_length'] and len(from_import_section) > 0 and + self.config['multi_line_output'] not in (1, 0)): + do_multiline_reformat = True + + if do_multiline_reformat: + import_statement = self._multi_line_reformat(import_start, from_import_section, comments) + if not do_multiline_reformat and len(import_statement) > self.config['line_length']: + import_statement = self._wrap(import_statement) + + if import_statement: + above_comments = self.comments['above']['from'].pop(module, None) + if above_comments: + section_output.extend(above_comments) + section_output.append(import_statement) + + def _multi_line_reformat(self, import_start, from_imports, comments): + output_mode = settings.WrapModes._fields[self.config['multi_line_output']].lower() + formatter = getattr(self, "_output_" + output_mode, self._output_grid) + dynamic_indent = " " * (len(import_start) + 1) + indent = self.config['indent'] + line_length = self.config['wrap_length'] or self.config['line_length'] + import_statement = formatter(import_start, copy.copy(from_imports), + dynamic_indent, indent, line_length, comments) + if self.config['balanced_wrapping']: + lines = import_statement.split(self.line_separator) + line_count = len(lines) + if len(lines) > 1: + minimum_length = min(len(line) for line in lines[:-1]) + else: + minimum_length = 0 + new_import_statement = import_statement + while (len(lines[-1]) < minimum_length and + len(lines) == line_count and line_length > 10): + import_statement = new_import_statement + line_length -= 1 + new_import_statement = formatter(import_start, copy.copy(from_imports), + dynamic_indent, indent, line_length, comments) + lines = new_import_statement.split(self.line_separator) + if import_statement.count(self.line_separator) == 0: + return self._wrap(import_statement) + return import_statement + + def _add_formatted_imports(self): + """Adds the imports back to the file. + + (at the index of the first import) sorted alphabetically and split between groups + + """ + sort_ignore_case = self.config['force_alphabetical_sort_within_sections'] + sections = itertools.chain(self.sections, self.config['forced_separate']) + + if self.config['no_sections']: + self.imports['no_sections'] = {'straight': [], 'from': {}} + for section in sections: + self.imports['no_sections']['straight'].extend(self.imports[section].get('straight', [])) + self.imports['no_sections']['from'].update(self.imports[section].get('from', {})) + sections = ('no_sections', ) + + output = [] + prev_section_has_imports = False + for section in sections: + straight_modules = self.imports[section]['straight'] + straight_modules = nsorted(straight_modules, key=lambda key: self._module_key(key, self.config)) + from_modules = self.imports[section]['from'] + from_modules = nsorted(from_modules, key=lambda key: self._module_key(key, self.config)) + + section_output = [] + if self.config['from_first']: + self._add_from_imports(from_modules, section, section_output, sort_ignore_case) + if self.config['lines_between_types'] and from_modules and straight_modules: + section_output.extend([''] * self.config['lines_between_types']) + self._add_straight_imports(straight_modules, section, section_output) + else: + self._add_straight_imports(straight_modules, section, section_output) + if self.config['lines_between_types'] and from_modules and straight_modules: + section_output.extend([''] * self.config['lines_between_types']) + self._add_from_imports(from_modules, section, section_output, sort_ignore_case) + + if self.config['force_sort_within_sections']: + def by_module(line): + section = 'B' + if line.startswith('#'): + return 'AA' + + line = re.sub('^from ', '', line) + line = re.sub('^import ', '', line) + if line.split(' ')[0] in self.config['force_to_top']: + section = 'A' + if not self.config['order_by_type']: + line = line.lower() + return '{0}{1}'.format(section, line) + section_output = nsorted(section_output, key=by_module) + if section_output: + section_name = section + if section_name in self.place_imports: + self.place_imports[section_name] = section_output + continue + + section_title = self.config.get('import_heading_' + str(section_name).lower(), '') + if section_title: + section_comment = "# {0}".format(section_title) + if section_comment not in self.out_lines[0:1] and section_comment not in self.in_lines[0:1]: + section_output.insert(0, section_comment) + if prev_section_has_imports and section_name in self.config['no_lines_before']: + while output and output[-1].strip() == '': + output.pop() + output += section_output + ([''] * self.config['lines_between_sections']) + prev_section_has_imports = bool(section_output) + while output and output[-1].strip() == '': + output.pop() + while output and output[0].strip() == '': + output.pop(0) + + output_at = 0 + if self.import_index < self.original_length: + output_at = self.import_index + elif self._first_comment_index_end != -1 and self._first_comment_index_start <= 2: + output_at = self._first_comment_index_end + self.out_lines[output_at:0] = output + + imports_tail = output_at + len(output) + while [character.strip() for character in self.out_lines[imports_tail: imports_tail + 1]] == [""]: + self.out_lines.pop(imports_tail) + + if len(self.out_lines) > imports_tail: + next_construct = "" + self._in_quote = False + tail = self.out_lines[imports_tail:] + + for index, line in enumerate(tail): + in_quote = self._in_quote + if not self._skip_line(line) and line.strip(): + if line.strip().startswith("#") and len(tail) > (index + 1) and tail[index + 1].strip(): + continue + next_construct = line + break + elif not in_quote: + parts = line.split() + if len(parts) >= 3 and parts[1] == '=' and "'" not in parts[0] and '"' not in parts[0]: + next_construct = line + break + + if self.config['lines_after_imports'] != -1: + self.out_lines[imports_tail:0] = ["" for line in range(self.config['lines_after_imports'])] + elif next_construct.startswith("def ") or next_construct.startswith("class ") or \ + next_construct.startswith("@") or next_construct.startswith("async def"): + self.out_lines[imports_tail:0] = ["", ""] + else: + self.out_lines[imports_tail:0] = [""] + + if self.place_imports: + new_out_lines = [] + for index, line in enumerate(self.out_lines): + new_out_lines.append(line) + if line in self.import_placements: + new_out_lines.extend(self.place_imports[self.import_placements[line]]) + if len(self.out_lines) <= index or self.out_lines[index + 1].strip() != "": + new_out_lines.append("") + self.out_lines = new_out_lines + + def _output_grid(self, statement, imports, white_space, indent, line_length, comments): + statement += "(" + imports.pop(0) + while imports: + next_import = imports.pop(0) + next_statement = self._add_comments(comments, statement + ", " + next_import) + if len(next_statement.split(self.line_separator)[-1]) + 1 > line_length: + lines = ['{0}{1}'.format(white_space, next_import.split(" ")[0])] + for part in next_import.split(" ")[1:]: + new_line = '{0} {1}'.format(lines[-1], part) + if len(new_line) + 1 > line_length: + lines.append('{0}{1}'.format(white_space, part)) + else: + lines[-1] = new_line + next_import = self.line_separator.join(lines) + statement = (self._add_comments(comments, "{0},".format(statement)) + + "{0}{1}".format(self.line_separator, next_import)) + comments = None + else: + statement += ", " + next_import + return statement + ("," if self.config['include_trailing_comma'] else "") + ")" + + def _output_vertical(self, statement, imports, white_space, indent, line_length, comments): + first_import = self._add_comments(comments, imports.pop(0) + ",") + self.line_separator + white_space + return "{0}({1}{2}{3})".format( + statement, + first_import, + ("," + self.line_separator + white_space).join(imports), + "," if self.config['include_trailing_comma'] else "", + ) + + def _output_hanging_indent(self, statement, imports, white_space, indent, line_length, comments): + statement += imports.pop(0) + while imports: + next_import = imports.pop(0) + next_statement = self._add_comments(comments, statement + ", " + next_import) + if len(next_statement.split(self.line_separator)[-1]) + 3 > line_length: + next_statement = (self._add_comments(comments, "{0}, \\".format(statement)) + + "{0}{1}{2}".format(self.line_separator, indent, next_import)) + comments = None + statement = next_statement + return statement + + def _output_vertical_hanging_indent(self, statement, imports, white_space, indent, line_length, comments): + return "{0}({1}{2}{3}{4}{5}{2})".format( + statement, + self._add_comments(comments), + self.line_separator, + indent, + ("," + self.line_separator + indent).join(imports), + "," if self.config['include_trailing_comma'] else "", + ) + + def _output_vertical_grid_common(self, statement, imports, white_space, indent, line_length, comments, + need_trailing_char): + statement += self._add_comments(comments, "(") + self.line_separator + indent + imports.pop(0) + while imports: + next_import = imports.pop(0) + next_statement = "{0}, {1}".format(statement, next_import) + current_line_length = len(next_statement.split(self.line_separator)[-1]) + if imports or need_trailing_char: + # If we have more imports we need to account for a comma after this import + # We might also need to account for a closing ) we're going to add. + current_line_length += 1 + if current_line_length > line_length: + next_statement = "{0},{1}{2}{3}".format(statement, self.line_separator, indent, next_import) + statement = next_statement + if self.config['include_trailing_comma']: + statement += ',' + return statement + + def _output_vertical_grid(self, statement, imports, white_space, indent, line_length, comments): + return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments, + True) + ")" + + def _output_vertical_grid_grouped(self, statement, imports, white_space, indent, line_length, comments): + return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments, + True) + self.line_separator + ")" + + def _output_vertical_grid_grouped_no_comma(self, statement, imports, white_space, indent, line_length, comments): + return self._output_vertical_grid_common(statement, imports, white_space, indent, line_length, comments, + False) + self.line_separator + ")" + + def _output_noqa(self, statement, imports, white_space, indent, line_length, comments): + retval = '{0}{1}'.format(statement, ', '.join(imports)) + comment_str = ' '.join(comments) + if comments: + if len(retval) + len(self.config['comment_prefix']) + 1 + len(comment_str) <= line_length: + return '{0}{1} {2}'.format(retval, self.config['comment_prefix'], comment_str) + else: + if len(retval) <= line_length: + return retval + if comments: + if "NOQA" in comments: + return '{0}{1} {2}'.format(retval, self.config['comment_prefix'], comment_str) + else: + return '{0}{1} NOQA {2}'.format(retval, self.config['comment_prefix'], comment_str) + else: + return '{0}{1} NOQA'.format(retval, self.config['comment_prefix']) + + @staticmethod + def _strip_comments(line, comments=None): + """Removes comments from import line.""" + if comments is None: + comments = [] + + new_comments = False + comment_start = line.find("#") + if comment_start != -1: + comments.append(line[comment_start + 1:].strip()) + new_comments = True + line = line[:comment_start] + + return line, comments, new_comments + + @staticmethod + def _format_simplified(import_line): + import_line = import_line.strip() + if import_line.startswith("from "): + import_line = import_line.replace("from ", "") + import_line = import_line.replace(" import ", ".") + elif import_line.startswith("import "): + import_line = import_line.replace("import ", "") + + return import_line + + @staticmethod + def _format_natural(import_line): + import_line = import_line.strip() + if not import_line.startswith("from ") and not import_line.startswith("import "): + if "." not in import_line: + return "import {0}".format(import_line) + parts = import_line.split(".") + end = parts.pop(-1) + return "from {0} import {1}".format(".".join(parts), end) + + return import_line + + def _skip_line(self, line): + skip_line = self._in_quote + if self.index == 1 and line.startswith("#"): + self._in_top_comment = True + return True + elif self._in_top_comment: + if not line.startswith("#"): + self._in_top_comment = False + self._first_comment_index_end = self.index - 1 + + if '"' in line or "'" in line: + index = 0 + if self._first_comment_index_start == -1 and (line.startswith('"') or line.startswith("'")): + self._first_comment_index_start = self.index + while index < len(line): + if line[index] == "\\": + index += 1 + elif self._in_quote: + if line[index:index + len(self._in_quote)] == self._in_quote: + self._in_quote = False + if self._first_comment_index_end < self._first_comment_index_start: + self._first_comment_index_end = self.index + elif line[index] in ("'", '"'): + long_quote = line[index:index + 3] + if long_quote in ('"""', "'''"): + self._in_quote = long_quote + index += 2 + else: + self._in_quote = line[index] + elif line[index] == "#": + break + index += 1 + + return skip_line or self._in_quote or self._in_top_comment + + def _strip_syntax(self, import_string): + import_string = import_string.replace("_import", "[[i]]") + for remove_syntax in ['\\', '(', ')', ',']: + import_string = import_string.replace(remove_syntax, " ") + import_list = import_string.split() + for key in ('from', 'import'): + if key in import_list: + import_list.remove(key) + import_string = ' '.join(import_list) + import_string = import_string.replace("[[i]]", "_import") + return import_string.replace("{ ", "{|").replace(" }", "|}") + + def _parse(self): + """Parses a python file taking out and categorizing imports.""" + self._in_quote = False + self._in_top_comment = False + while not self._at_end(): + raw_line = line = self._get_line() + line = line.replace("from.import ", "from . import ") + line = line.replace("\t", " ").replace('import*', 'import *') + line = line.replace(" .import ", " . import ") + statement_index = self.index + skip_line = self._skip_line(line) + + if line in self._section_comments and not skip_line: + if self.import_index == -1: + self.import_index = self.index - 1 + continue + + if "isort:imports-" in line and line.startswith("#"): + section = line.split("isort:imports-")[-1].split()[0].upper() + self.place_imports[section] = [] + self.import_placements[line] = section + + if ";" in line: + for part in (part.strip() for part in line.split(";")): + if part and not part.startswith("from ") and not part.startswith("import "): + skip_line = True + + import_type = self._import_type(line) + if not import_type or skip_line: + self.out_lines.append(raw_line) + continue + + for line in (line.strip() for line in line.split(";")): + import_type = self._import_type(line) + if not import_type: + self.out_lines.append(line) + continue + + if self.import_index == -1: + self.import_index = self.index - 1 + + nested_comments = {} + import_string, comments, new_comments = self._strip_comments(line) + stripped_line = [part for part in self._strip_syntax(import_string).strip().split(" ") if part] + if import_type == "from" and len(stripped_line) == 2 and stripped_line[1] != "*" and new_comments: + nested_comments[stripped_line[-1]] = comments[0] + + if "(" in line.split("#")[0] and not self._at_end(): + while not line.strip().endswith(")") and not self._at_end(): + line, comments, new_comments = self._strip_comments(self._get_line(), comments) + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + import_string += self.line_separator + line + else: + while line.strip().endswith("\\"): + line, comments, new_comments = self._strip_comments(self._get_line(), comments) + + # Still need to check for parentheses after an escaped line + if "(" in line.split("#")[0] and not self._at_end(): + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + import_string += self.line_separator + line + + while not line.strip().endswith(")") and not self._at_end(): + line, comments, new_comments = self._strip_comments(self._get_line(), comments) + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + import_string += self.line_separator + line + + stripped_line = self._strip_syntax(line).strip() + if import_type == "from" and stripped_line and " " not in stripped_line and new_comments: + nested_comments[stripped_line] = comments[-1] + if import_string.strip().endswith(" import") or line.strip().startswith("import "): + import_string += self.line_separator + line + else: + import_string = import_string.rstrip().rstrip("\\") + " " + line.lstrip() + + if import_type == "from": + import_string = import_string.replace("import(", "import (") + parts = import_string.split(" import ") + from_import = parts[0].split(" ") + import_string = " import ".join([from_import[0] + " " + "".join(from_import[1:])] + parts[1:]) + + imports = [item.replace("{|", "{ ").replace("|}", " }") for item in + self._strip_syntax(import_string).split()] + if "as" in imports and (imports.index('as') + 1) < len(imports): + while "as" in imports: + index = imports.index('as') + if import_type == "from": + module = imports[0] + "." + imports[index - 1] + self.as_map[module] = imports[index + 1] + else: + module = imports[index - 1] + self.as_map[module] = imports[index + 1] + if not self.config['combine_as_imports']: + self.comments['straight'][module] = comments + comments = [] + del imports[index:index + 2] + if import_type == "from": + import_from = imports.pop(0) + placed_module = self.place_module(import_from) + if self.config['verbose']: + print("from-type place_module for %s returned %s" % (import_from, placed_module)) + if placed_module == '': + print( + "WARNING: could not place module {0} of line {1} --" + " Do you need to define a default section?".format(import_from, line) + ) + root = self.imports[placed_module][import_type] + for import_name in imports: + associated_comment = nested_comments.get(import_name) + if associated_comment: + self.comments['nested'].setdefault(import_from, {})[import_name] = associated_comment + comments.pop(comments.index(associated_comment)) + if comments: + self.comments['from'].setdefault(import_from, []).extend(comments) + + if len(self.out_lines) > max(self.import_index, self._first_comment_index_end + 1, 1) - 1: + last = self.out_lines and self.out_lines[-1].rstrip() or "" + while (last.startswith("#") and not last.endswith('"""') and not last.endswith("'''") and + 'isort:imports-' not in last): + self.comments['above']['from'].setdefault(import_from, []).insert(0, self.out_lines.pop(-1)) + if len(self.out_lines) > max(self.import_index - 1, self._first_comment_index_end + 1, 1) - 1: + last = self.out_lines[-1].rstrip() + else: + last = "" + if statement_index - 1 == self.import_index: + self.import_index -= len(self.comments['above']['from'].get(import_from, [])) + + if root.get(import_from, False): + root[import_from].update(imports) + else: + root[import_from] = OrderedSet(imports) + else: + for module in imports: + if comments: + self.comments['straight'][module] = comments + comments = None + + if len(self.out_lines) > max(self.import_index, self._first_comment_index_end + 1, 1) - 1: + + last = self.out_lines and self.out_lines[-1].rstrip() or "" + while (last.startswith("#") and not last.endswith('"""') and not last.endswith("'''") and + 'isort:imports-' not in last): + self.comments['above']['straight'].setdefault(module, []).insert(0, + self.out_lines.pop(-1)) + if len(self.out_lines) > 0: + last = self.out_lines[-1].rstrip() + else: + last = "" + if self.index - 1 == self.import_index: + self.import_index -= len(self.comments['above']['straight'].get(module, [])) + placed_module = self.place_module(module) + if self.config['verbose']: + print("else-type place_module for %s returned %s" % (module, placed_module)) + if placed_module == '': + print( + "WARNING: could not place module {0} of line {1} --" + " Do you need to define a default section?".format(import_from, line) + ) + self.imports[placed_module][import_type].add(module) + + +def coding_check(fname, default='utf-8'): + + # see https://www.python.org/dev/peps/pep-0263/ + pattern = re.compile(br'coding[:=]\s*([-\w.]+)') + + coding = default + with io.open(fname, 'rb') as f: + for line_number, line in enumerate(f, 1): + groups = re.findall(pattern, line) + if groups: + coding = groups[0].decode('ascii') + break + if line_number > 2: + break + + return coding + + +def exists_case_sensitive(path): + """ + Returns if the given path exists and also matches the case on Windows. + + When finding files that can be imported, it is important for the cases to match because while + file os.path.exists("module.py") and os.path.exists("MODULE.py") both return True on Windows, Python + can only import using the case of the real file. + """ + result = os.path.exists(path) + if (sys.platform.startswith('win') or sys.platform == 'darwin') and result: + directory, basename = os.path.split(path) + result = basename in os.listdir(directory) + return result diff --git a/basic python programmes/venv/Lib/site-packages/isort/main.py b/basic python programmes/venv/Lib/site-packages/isort/main.py new file mode 100644 index 0000000..efb3793 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/main.py @@ -0,0 +1,364 @@ +#!/usr/bin/env python +''' Tool for sorting imports alphabetically, and automatically separated into sections. + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +''' +from __future__ import absolute_import, division, print_function, unicode_literals + +import argparse +import glob +import os +import re +import sys +from concurrent.futures import ProcessPoolExecutor +import functools + +import setuptools + +from isort import SortImports, __version__ +from isort.settings import DEFAULT_SECTIONS, default, from_path, should_skip + +from .pie_slice import itemsview + +INTRO = r""" +/#######################################################################\ + + `sMMy` + .yyyy- ` + ##soos## ./o. + ` ``..-..` ``...`.`` ` ```` ``-ssso``` + .s:-y- .+osssssso/. ./ossss+:so+:` :+o-`/osso:+sssssssso/ + .s::y- osss+.``.`` -ssss+-.`-ossso` ssssso/::..::+ssss:::. + .s::y- /ssss+//:-.` `ssss+ `ssss+ sssso` :ssss` + .s::y- `-/+oossssso/ `ssss/ sssso ssss/ :ssss` + .y-/y- ````:ssss` ossso. :ssss: ssss/ :ssss. + `/so:` `-//::/osss+ `+ssss+-/ossso: /sso- `osssso/. + \/ `-/oooo++/- .:/++:/++/-` .. `://++/. + + + isort your Python imports for you so you don't have to + + VERSION {0} + +\########################################################################/ +""".format(__version__) + +shebang_re = re.compile(br'^#!.*\bpython[23w]?\b') + + +def is_python_file(path): + if path.endswith('.py'): + return True + + try: + with open(path, 'rb') as fp: + line = fp.readline(100) + except IOError: + return False + else: + return bool(shebang_re.match(line)) + + +class SortAttempt(object): + def __init__(self, incorrectly_sorted, skipped): + self.incorrectly_sorted = incorrectly_sorted + self.skipped = skipped + + +def sort_imports(file_name, **arguments): + try: + result = SortImports(file_name, **arguments) + return SortAttempt(result.incorrectly_sorted, result.skipped) + except IOError as e: + print("WARNING: Unable to parse file {0} due to {1}".format(file_name, e)) + return None + + +def iter_source_code(paths, config, skipped): + """Iterate over all Python source files defined in paths.""" + for path in paths: + if os.path.isdir(path): + if should_skip(path, config, os.getcwd()): + skipped.append(path) + continue + + for dirpath, dirnames, filenames in os.walk(path, topdown=True): + for dirname in list(dirnames): + if should_skip(dirname, config, dirpath): + skipped.append(dirname) + dirnames.remove(dirname) + for filename in filenames: + filepath = os.path.join(dirpath, filename) + if is_python_file(filepath): + if should_skip(filename, config, dirpath): + skipped.append(filename) + else: + yield filepath + else: + yield path + + +class ISortCommand(setuptools.Command): + """The :class:`ISortCommand` class is used by setuptools to perform + imports checks on registered modules. + """ + + description = "Run isort on modules registered in setuptools" + user_options = [] + + def initialize_options(self): + default_settings = default.copy() + for (key, value) in itemsview(default_settings): + setattr(self, key, value) + + def finalize_options(self): + "Get options from config files." + self.arguments = {} + computed_settings = from_path(os.getcwd()) + for (key, value) in itemsview(computed_settings): + self.arguments[key] = value + + def distribution_files(self): + """Find distribution packages.""" + # This is verbatim from flake8 + if self.distribution.packages: + package_dirs = self.distribution.package_dir or {} + for package in self.distribution.packages: + pkg_dir = package + if package in package_dirs: + pkg_dir = package_dirs[package] + elif '' in package_dirs: + pkg_dir = package_dirs[''] + os.path.sep + pkg_dir + yield pkg_dir.replace('.', os.path.sep) + + if self.distribution.py_modules: + for filename in self.distribution.py_modules: + yield "%s.py" % filename + # Don't miss the setup.py file itself + yield "setup.py" + + def run(self): + arguments = self.arguments + wrong_sorted_files = False + arguments['check'] = True + for path in self.distribution_files(): + for python_file in glob.iglob(os.path.join(path, '*.py')): + try: + incorrectly_sorted = SortImports(python_file, **arguments).incorrectly_sorted + if incorrectly_sorted: + wrong_sorted_files = True + except IOError as e: + print("WARNING: Unable to parse file {0} due to {1}".format(python_file, e)) + if wrong_sorted_files: + exit(1) + + +def create_parser(): + parser = argparse.ArgumentParser(description='Sort Python import definitions alphabetically ' + 'within logical sections.') + inline_args_group = parser.add_mutually_exclusive_group() + parser.add_argument('-a', '--add-import', dest='add_imports', action='append', + help='Adds the specified import line to all files, ' + 'automatically determining correct placement.') + parser.add_argument('-ac', '--atomic', dest='atomic', action='store_true', + help="Ensures the output doesn't save if the resulting file contains syntax errors.") + parser.add_argument('-af', '--force-adds', dest='force_adds', action='store_true', + help='Forces import adds even if the original file is empty.') + parser.add_argument('-b', '--builtin', dest='known_standard_library', action='append', + help='Force sortImports to recognize a module as part of the python standard library.') + parser.add_argument('-c', '--check-only', action='store_true', dest="check", + help='Checks the file for unsorted / unformatted imports and prints them to the ' + 'command line without modifying the file.') + parser.add_argument('-ca', '--combine-as', dest='combine_as_imports', action='store_true', + help="Combines as imports on the same line.") + parser.add_argument('-cs', '--combine-star', dest='combine_star', action='store_true', + help="Ensures that if a star import is present, nothing else is imported from that namespace.") + parser.add_argument('-d', '--stdout', help='Force resulting output to stdout, instead of in-place.', + dest='write_to_stdout', action='store_true') + parser.add_argument('-df', '--diff', dest='show_diff', action='store_true', + help="Prints a diff of all the changes isort would make to a file, instead of " + "changing it in place") + parser.add_argument('-ds', '--no-sections', help='Put all imports into the same section bucket', dest='no_sections', + action='store_true') + parser.add_argument('-dt', '--dont-order-by-type', dest='dont_order_by_type', + action='store_true', help='Only order imports alphabetically, do not attempt type ordering') + parser.add_argument('-e', '--balanced', dest='balanced_wrapping', action='store_true', + help='Balances wrapping to produce the most consistent line length possible') + parser.add_argument('-f', '--future', dest='known_future_library', action='append', + help='Force sortImports to recognize a module as part of the future compatibility libraries.') + parser.add_argument('-fas', '--force-alphabetical-sort', action='store_true', dest="force_alphabetical_sort", + help='Force all imports to be sorted as a single section') + parser.add_argument('-fass', '--force-alphabetical-sort-within-sections', action='store_true', + dest="force_alphabetical_sort", help='Force all imports to be sorted alphabetically within a ' + 'section') + parser.add_argument('-ff', '--from-first', dest='from_first', + help="Switches the typical ordering preference, showing from imports first then straight ones.") + parser.add_argument('-fgw', '--force-grid-wrap', nargs='?', const=2, type=int, dest="force_grid_wrap", + help='Force number of from imports (defaults to 2) to be grid wrapped regardless of line ' + 'length') + parser.add_argument('-fss', '--force-sort-within-sections', action='store_true', dest="force_sort_within_sections", + help='Force imports to be sorted by module, independent of import_type') + parser.add_argument('-i', '--indent', help='String to place for indents defaults to " " (4 spaces).', + dest='indent', type=str) + parser.add_argument('-j', '--jobs', help='Number of files to process in parallel.', + dest='jobs', type=int) + parser.add_argument('-k', '--keep-direct-and-as', dest='keep_direct_and_as_imports', action='store_true', + help="Turns off default behavior that removes direct imports when as imports exist.") + parser.add_argument('-l', '--lines', help='[Deprecated] The max length of an import line (used for wrapping ' + 'long imports).', + dest='line_length', type=int) + parser.add_argument('-lai', '--lines-after-imports', dest='lines_after_imports', type=int) + parser.add_argument('-lbt', '--lines-between-types', dest='lines_between_types', type=int) + parser.add_argument('-le', '--line-ending', dest='line_ending', + help="Forces line endings to the specified value. If not set, values will be guessed per-file.") + parser.add_argument('-ls', '--length-sort', help='Sort imports by their string length.', + dest='length_sort', action='store_true') + parser.add_argument('-m', '--multi-line', dest='multi_line_output', type=int, choices=[0, 1, 2, 3, 4, 5], + help='Multi line output (0-grid, 1-vertical, 2-hanging, 3-vert-hanging, 4-vert-grid, ' + '5-vert-grid-grouped, 6-vert-grid-grouped-no-comma).') + inline_args_group.add_argument('-nis', '--no-inline-sort', dest='no_inline_sort', action='store_true', + help='Leaves `from` imports with multiple imports \'as-is\' (e.g. `from foo import a, c ,b`).') + parser.add_argument('-nlb', '--no-lines-before', help='Sections which should not be split with previous by empty lines', + dest='no_lines_before', action='append') + parser.add_argument('-ns', '--dont-skip', help='Files that sort imports should never skip over.', + dest='not_skip', action='append') + parser.add_argument('-o', '--thirdparty', dest='known_third_party', action='append', + help='Force sortImports to recognize a module as being part of a third party library.') + parser.add_argument('-ot', '--order-by-type', dest='order_by_type', + action='store_true', help='Order imports by type in addition to alphabetically') + parser.add_argument('-p', '--project', dest='known_first_party', action='append', + help='Force sortImports to recognize a module as being part of the current python project.') + parser.add_argument('-q', '--quiet', action='store_true', dest="quiet", + help='Shows extra quiet output, only errors are outputted.') + parser.add_argument('-r', '--remove-import', dest='remove_imports', action='append', + help='Removes the specified import from all files.') + parser.add_argument('-rc', '--recursive', dest='recursive', action='store_true', + help='Recursively look for Python files of which to sort imports') + parser.add_argument('-s', '--skip', help='Files that sort imports should skip over. If you want to skip multiple ' + 'files you should specify twice: --skip file1 --skip file2.', dest='skip', action='append') + parser.add_argument('-sd', '--section-default', dest='default_section', + help='Sets the default section for imports (by default FIRSTPARTY) options: ' + + str(DEFAULT_SECTIONS)) + parser.add_argument('-sg', '--skip-glob', help='Files that sort imports should skip over.', dest='skip_glob', + action='append') + inline_args_group.add_argument('-sl', '--force-single-line-imports', dest='force_single_line', action='store_true', + help='Forces all from imports to appear on their own line') + parser.add_argument('-sp', '--settings-path', dest="settings_path", + help='Explicitly set the settings path instead of auto determining based on file location.') + parser.add_argument('-t', '--top', help='Force specific imports to the top of their appropriate section.', + dest='force_to_top', action='append') + parser.add_argument('-tc', '--trailing-comma', dest='include_trailing_comma', action='store_true', + help='Includes a trailing comma on multi line imports that include parentheses.') + parser.add_argument('-up', '--use-parentheses', dest='use_parentheses', action='store_true', + help='Use parenthesis for line continuation on length limit instead of slashes.') + parser.add_argument('-v', '--version', action='store_true', dest='show_version') + parser.add_argument('-vb', '--verbose', action='store_true', dest="verbose", + help='Shows verbose output, such as when files are skipped or when a check is successful.') + parser.add_argument('--virtual-env', dest='virtual_env', + help='Virtual environment to use for determining whether a package is third-party') + parser.add_argument('-vn', '--version-number', action='version', version=__version__, + help='Returns just the current version number without the logo') + parser.add_argument('-w', '--line-width', help='The max length of an import line (used for wrapping long imports).', + dest='line_length', type=int) + parser.add_argument('-wl', '--wrap-length', dest='wrap_length', + help="Specifies how long lines that are wrapped should be, if not set line_length is used.") + parser.add_argument('-ws', '--ignore-whitespace', action='store_true', dest="ignore_whitespace", + help='Tells isort to ignore whitespace differences when --check-only is being used.') + parser.add_argument('-y', '--apply', dest='apply', action='store_true', + help='Tells isort to apply changes recursively without asking') + parser.add_argument('files', nargs='*', help='One or more Python source files that need their imports sorted.') + + arguments = {key: value for key, value in itemsview(vars(parser.parse_args())) if value} + if 'dont_order_by_type' in arguments: + arguments['order_by_type'] = False + return arguments + + +def main(): + arguments = create_parser() + if arguments.get('show_version'): + print(INTRO) + return + + if 'settings_path' in arguments: + sp = arguments['settings_path'] + arguments['settings_path'] = os.path.abspath(sp) if os.path.isdir(sp) else os.path.dirname(os.path.abspath(sp)) + if not os.path.isdir(arguments['settings_path']): + print("WARNING: settings_path dir does not exist: {0}".format(arguments['settings_path'])) + + if 'virtual_env' in arguments: + venv = arguments['virtual_env'] + arguments['virtual_env'] = os.path.abspath(venv) + if not os.path.isdir(arguments['virtual_env']): + print("WARNING: virtual_env dir does not exist: {0}".format(arguments['virtual_env'])) + + file_names = arguments.pop('files', []) + if file_names == ['-']: + SortImports(file_contents=sys.stdin.read(), write_to_stdout=True, **arguments) + else: + if not file_names: + file_names = ['.'] + arguments['recursive'] = True + if not arguments.get('apply', False): + arguments['ask_to_apply'] = True + config = from_path(os.path.abspath(file_names[0]) or os.getcwd()).copy() + config.update(arguments) + wrong_sorted_files = False + skipped = [] + if arguments.get('recursive', False): + file_names = iter_source_code(file_names, config, skipped) + num_skipped = 0 + if config['verbose'] or config.get('show_logo', False): + print(INTRO) + jobs = arguments.get('jobs') + if jobs: + executor = ProcessPoolExecutor(max_workers=jobs) + + for sort_attempt in executor.map(functools.partial(sort_imports, **arguments), file_names): + if not sort_attempt: + continue + incorrectly_sorted = sort_attempt.incorrectly_sorted + if arguments.get('check', False) and incorrectly_sorted: + wrong_sorted_files = True + if sort_attempt.skipped: + num_skipped += 1 + else: + for file_name in file_names: + try: + sort_attempt = SortImports(file_name, **arguments) + incorrectly_sorted = sort_attempt.incorrectly_sorted + if arguments.get('check', False) and incorrectly_sorted: + wrong_sorted_files = True + if sort_attempt.skipped: + num_skipped += 1 + except IOError as e: + print("WARNING: Unable to parse file {0} due to {1}".format(file_name, e)) + if wrong_sorted_files: + exit(1) + + num_skipped += len(skipped) + if num_skipped and not arguments.get('quiet', False): + if config['verbose']: + for was_skipped in skipped: + print("WARNING: {0} was skipped as it's listed in 'skip' setting" + " or matches a glob in 'skip_glob' setting".format(was_skipped)) + print("Skipped {0} files".format(num_skipped)) + + +if __name__ == "__main__": + main() diff --git a/basic python programmes/venv/Lib/site-packages/isort/natural.py b/basic python programmes/venv/Lib/site-packages/isort/natural.py new file mode 100644 index 0000000..c02b42c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/natural.py @@ -0,0 +1,47 @@ +"""isort/natural.py. + +Enables sorting strings that contain numbers naturally + +usage: + natural.nsorted(list) + +Copyright (C) 2013 Timothy Edmund Crosley + +Implementation originally from @HappyLeapSecond stack overflow user in response to: + https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +import re + + +def _atoi(text): + return int(text) if text.isdigit() else text + + +def _natural_keys(text): + return [_atoi(c) for c in re.split(r'(\d+)', text)] + + +def nsorted(to_sort, key=None): + """Returns a naturally sorted list""" + if key is None: + key_callback = _natural_keys + else: + def key_callback(item): + return _natural_keys(key(item)) + + return sorted(to_sort, key=key_callback) diff --git a/basic python programmes/venv/Lib/site-packages/isort/pie_slice.py b/basic python programmes/venv/Lib/site-packages/isort/pie_slice.py new file mode 100644 index 0000000..178cf33 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/pie_slice.py @@ -0,0 +1,422 @@ +"""pie_slice/overrides.py. + +Overrides Python syntax to conform to the Python3 version as much as possible using a '*' import + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +from __future__ import absolute_import + +import collections +import sys + +__version__ = "1.1.0" + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +VERSION = sys.version_info + +native_dict = dict +native_round = round +native_filter = filter +native_map = map +native_zip = zip +native_range = range +native_str = str +native_chr = chr +native_input = input +native_next = next +native_object = object + +common = ['native_dict', 'native_round', 'native_filter', 'native_map', 'native_range', 'native_str', 'native_chr', + 'native_input', 'PY2', 'PY3', 'u', 'itemsview', 'valuesview', 'keysview', 'execute', 'integer_types', + 'native_next', 'native_object', 'with_metaclass', 'lru_cache'] + + +def with_metaclass(meta, *bases): + """Enables use of meta classes across Python Versions. taken from jinja2/_compat.py. + + Use it like this:: + + class BaseForm(object): + pass + + class FormType(type): + pass + + class Form(with_metaclass(FormType, BaseForm)): + pass + + """ + class metaclass(meta): + __call__ = type.__call__ + __init__ = type.__init__ + + def __new__(cls, name, this_bases, d): + if this_bases is None: + return type.__new__(cls, name, (), d) + return meta(name, bases, d) + return metaclass('temporary_class', None, {}) + + +def unmodified_isinstance(*bases): + """When called in the form + + MyOverrideClass(unmodified_isinstance(BuiltInClass)) + + it allows calls against passed in built in instances to pass even if there not a subclass + + """ + class UnmodifiedIsInstance(type): + @classmethod + def __instancecheck__(cls, instance): + if cls.__name__ in (str(base.__name__) for base in bases): + return isinstance(instance, bases) + + return type.__instancecheck__(cls, instance) + + return with_metaclass(UnmodifiedIsInstance, *bases) + + +if PY3: + import urllib + import builtins + from urllib import parse + + input = input + integer_types = (int, ) + + def u(string): + return string + + def itemsview(collection): + return collection.items() + + def valuesview(collection): + return collection.values() + + def keysview(collection): + return collection.keys() + + urllib.quote = parse.quote + urllib.quote_plus = parse.quote_plus + urllib.unquote = parse.unquote + urllib.unquote_plus = parse.unquote_plus + urllib.urlencode = parse.urlencode + execute = getattr(builtins, 'exec') + if VERSION[1] < 2: + def callable(entity): + return hasattr(entity, '__call__') + common.append('callable') + + __all__ = common + ['urllib'] +else: + from itertools import ifilter as filter # noqa: F401 + from itertools import imap as map # noqa: F401 + from itertools import izip as zip # noqa: F401 + from decimal import Decimal, ROUND_HALF_EVEN + + str = unicode + chr = unichr + input = raw_input + range = xrange + integer_types = (int, long) + + import sys + stdout = sys.stdout + stderr = sys.stderr + reload(sys) + sys.stdout = stdout + sys.stderr = stderr + sys.setdefaultencoding('utf-8') + + def _create_not_allowed(name): + def _not_allow(*args, **kwargs): + raise NameError("name '{0}' is not defined".format(name)) + _not_allow.__name__ = name + return _not_allow + + for removed in ('apply', 'cmp', 'coerce', 'execfile', 'raw_input', 'unpacks'): + globals()[removed] = _create_not_allowed(removed) + + def u(s): + if isinstance(s, unicode): + return s + else: + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + + def execute(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + class _dict_view_base(object): + __slots__ = ('_dictionary', ) + + def __init__(self, dictionary): + self._dictionary = dictionary + + def __repr__(self): + return "{0}({1})".format(self.__class__.__name__, str(list(self.__iter__()))) + + def __unicode__(self): + return str(self.__repr__()) + + def __str__(self): + return str(self.__unicode__()) + + class dict_keys(_dict_view_base): + __slots__ = () + + def __iter__(self): + return self._dictionary.iterkeys() + + class dict_values(_dict_view_base): + __slots__ = () + + def __iter__(self): + return self._dictionary.itervalues() + + class dict_items(_dict_view_base): + __slots__ = () + + def __iter__(self): + return self._dictionary.iteritems() + + def itemsview(collection): + return dict_items(collection) + + def valuesview(collection): + return dict_values(collection) + + def keysview(collection): + return dict_keys(collection) + + class dict(unmodified_isinstance(native_dict)): + def has_key(self, *args, **kwargs): + return AttributeError("'dict' object has no attribute 'has_key'") + + def items(self): + return dict_items(self) + + def keys(self): + return dict_keys(self) + + def values(self): + return dict_values(self) + + def round(number, ndigits=None): + return_int = False + if ndigits is None: + return_int = True + ndigits = 0 + if hasattr(number, '__round__'): + return number.__round__(ndigits) + + if ndigits < 0: + raise NotImplementedError('negative ndigits not supported yet') + exponent = Decimal('10') ** (-ndigits) + d = Decimal.from_float(number).quantize(exponent, + rounding=ROUND_HALF_EVEN) + if return_int: + return int(d) + else: + return float(d) + + def next(iterator): + try: + iterator.__next__() + except Exception: + native_next(iterator) + + class FixStr(type): + def __new__(cls, name, bases, dct): + if '__str__' in dct: + dct['__unicode__'] = dct['__str__'] + dct['__str__'] = lambda self: self.__unicode__().encode('utf-8') + return type.__new__(cls, name, bases, dct) + + def __instancecheck__(cls, instance): + if cls.__name__ == "object": + return isinstance(instance, native_object) + return type.__instancecheck__(cls, instance) + + class object(with_metaclass(FixStr, object)): + pass + + __all__ = common + ['round', 'dict', 'apply', 'cmp', 'coerce', 'execfile', 'raw_input', 'unpacks', 'str', 'chr', + 'input', 'range', 'filter', 'map', 'zip', 'object'] + + +if sys.version_info < (3, 2): + try: + from threading import Lock + except ImportError: + from dummy_threading import Lock + + from functools import wraps + + _CacheInfo = collections.namedtuple("CacheInfo", "hits misses maxsize currsize") + + def lru_cache(maxsize=100): + """Least-recently-used cache decorator. + Taking from: https://github.com/MiCHiLU/python-functools32/blob/master/functools32/functools32.py + with slight modifications. + If *maxsize* is set to None, the LRU features are disabled and the cache + can grow without bound. + Arguments to the cached function must be hashable. + View the cache statistics named tuple (hits, misses, maxsize, currsize) with + f.cache_info(). Clear the cache and statistics with f.cache_clear(). + Access the underlying function with f.__wrapped__. + See: https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used + + """ + def decorating_function(user_function, tuple=tuple, sorted=sorted, len=len, KeyError=KeyError): + hits, misses = [0], [0] + kwd_mark = (object(),) # separates positional and keyword args + lock = Lock() + + if maxsize is None: + CACHE = {} + + @wraps(user_function) + def wrapper(*args, **kwds): + key = args + if kwds: + key += kwd_mark + tuple(sorted(kwds.items())) + try: + result = CACHE[key] + hits[0] += 1 + return result + except KeyError: + pass + result = user_function(*args, **kwds) + CACHE[key] = result + misses[0] += 1 + return result + else: + CACHE = collections.OrderedDict() + + @wraps(user_function) + def wrapper(*args, **kwds): + key = args + if kwds: + key += kwd_mark + tuple(sorted(kwds.items())) + with lock: + cached = CACHE.get(key, None) + if cached: + del CACHE[key] + CACHE[key] = cached + hits[0] += 1 + return cached + result = user_function(*args, **kwds) + with lock: + CACHE[key] = result # record recent use of this key + misses[0] += 1 + while len(CACHE) > maxsize: + CACHE.popitem(last=False) + return result + + def cache_info(): + """Report CACHE statistics.""" + with lock: + return _CacheInfo(hits[0], misses[0], maxsize, len(CACHE)) + + def cache_clear(): + """Clear the CACHE and CACHE statistics.""" + with lock: + CACHE.clear() + hits[0] = misses[0] = 0 + + wrapper.cache_info = cache_info + wrapper.cache_clear = cache_clear + return wrapper + + return decorating_function + +else: + from functools import lru_cache # noqa: F401 + + +class OrderedSet(collections.MutableSet): + + def __init__(self, iterable=None): + self.end = end = [] + end += [None, end, end] + self.map = {} + if iterable is not None: + self |= iterable + + def __len__(self): + return len(self.map) + + def __contains__(self, key): + return key in self.map + + def add(self, key): + if key not in self.map: + end = self.end + curr = end[1] + curr[2] = end[1] = self.map[key] = [key, curr, end] + + def discard(self, key): + if key in self.map: + key, prev, next = self.map.pop(key) + prev[2] = next + next[1] = prev + + def __iter__(self): + end = self.end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + def pop(self, last=True): + if not self: + raise KeyError('set is empty') + key = self.end[1][0] if last else self.end[2][0] + self.discard(key) + return key + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self)) + + def __eq__(self, other): + if isinstance(other, OrderedSet): + return len(self) == len(other) and list(self) == list(other) + return set(self) == set(other) + + def update(self, other): + for item in other: + self.add(item) diff --git a/basic python programmes/venv/Lib/site-packages/isort/pylama_isort.py b/basic python programmes/venv/Lib/site-packages/isort/pylama_isort.py new file mode 100644 index 0000000..6fa235f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/pylama_isort.py @@ -0,0 +1,29 @@ +import os +import sys + +from pylama.lint import Linter as BaseLinter + +from .isort import SortImports + + +class Linter(BaseLinter): + + def allow(self, path): + """Determine if this path should be linted.""" + return path.endswith('.py') + + def run(self, path, **meta): + """Lint the file. Return an array of error dicts if appropriate.""" + with open(os.devnull, 'w') as devnull: + # Suppress isort messages + sys.stdout = devnull + + if SortImports(path, check=True).incorrectly_sorted: + return [{ + 'lnum': 0, + 'col': 0, + 'text': 'Incorrectly sorted imports.', + 'type': 'ISORT' + }] + else: + return [] diff --git a/basic python programmes/venv/Lib/site-packages/isort/settings.py b/basic python programmes/venv/Lib/site-packages/isort/settings.py new file mode 100644 index 0000000..dd0a711 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/isort/settings.py @@ -0,0 +1,269 @@ +"""isort/settings.py. + +Defines how the default settings for isort should be loaded + +(First from the default setting dictionary at the top of the file, then overridden by any settings + in ~/.isort.cfg if there are any) + +Copyright (C) 2013 Timothy Edmund Crosley + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +""" +from __future__ import absolute_import, division, print_function, unicode_literals + +import fnmatch +import io +import os +import posixpath +import sys +from collections import namedtuple + +from .pie_slice import itemsview, lru_cache, native_str + +try: + import configparser +except ImportError: + import ConfigParser as configparser + +MAX_CONFIG_SEARCH_DEPTH = 25 # The number of parent directories isort will look for a config file within +DEFAULT_SECTIONS = ('FUTURE', 'STDLIB', 'THIRDPARTY', 'FIRSTPARTY', 'LOCALFOLDER') + +WrapModes = ('GRID', 'VERTICAL', 'HANGING_INDENT', 'VERTICAL_HANGING_INDENT', 'VERTICAL_GRID', 'VERTICAL_GRID_GROUPED', + 'VERTICAL_GRID_GROUPED_NO_COMMA', 'NOQA') +WrapModes = namedtuple('WrapModes', WrapModes)(*range(len(WrapModes))) + +# Note that none of these lists must be complete as they are simply fallbacks for when included auto-detection fails. +default = {'force_to_top': [], + 'skip': ['__init__.py', ], + 'skip_glob': [], + 'line_length': 79, + 'wrap_length': 0, + 'line_ending': None, + 'sections': DEFAULT_SECTIONS, + 'no_sections': False, + 'known_future_library': ['__future__'], + 'known_standard_library': ['AL', 'BaseHTTPServer', 'Bastion', 'CGIHTTPServer', 'Carbon', 'ColorPicker', + 'ConfigParser', 'Cookie', 'DEVICE', 'DocXMLRPCServer', 'EasyDialogs', 'FL', + 'FrameWork', 'GL', 'HTMLParser', 'MacOS', 'MimeWriter', 'MiniAEFrame', 'Nav', + 'PixMapWrapper', 'Queue', 'SUNAUDIODEV', 'ScrolledText', 'SimpleHTTPServer', + 'SimpleXMLRPCServer', 'SocketServer', 'StringIO', 'Tix', 'Tkinter', 'UserDict', + 'UserList', 'UserString', 'W', '__builtin__', 'abc', 'aepack', 'aetools', + 'aetypes', 'aifc', 'al', 'anydbm', 'applesingle', 'argparse', 'array', 'ast', + 'asynchat', 'asyncio', 'asyncore', 'atexit', 'audioop', 'autoGIL', 'base64', + 'bdb', 'binascii', 'binhex', 'bisect', 'bsddb', 'buildtools', 'builtins', + 'bz2', 'cPickle', 'cProfile', 'cStringIO', 'calendar', 'cd', 'cfmfile', 'cgi', + 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop', 'collections', + 'colorsys', 'commands', 'compileall', 'compiler', 'concurrent', 'configparser', + 'contextlib', 'cookielib', 'copy', 'copy_reg', 'copyreg', 'crypt', 'csv', + 'ctypes', 'curses', 'datetime', 'dbhash', 'dbm', 'decimal', 'difflib', + 'dircache', 'dis', 'distutils', 'dl', 'doctest', 'dumbdbm', 'dummy_thread', + 'dummy_threading', 'email', 'encodings', 'ensurepip', 'enum', 'errno', + 'exceptions', 'faulthandler', 'fcntl', 'filecmp', 'fileinput', 'findertools', + 'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl', 'fpformat', 'fractions', + 'ftplib', 'functools', 'future_builtins', 'gc', 'gdbm', 'gensuitemodule', + 'getopt', 'getpass', 'gettext', 'gl', 'glob', 'grp', 'gzip', 'hashlib', + 'heapq', 'hmac', 'hotshot', 'html', 'htmlentitydefs', 'htmllib', 'http', + 'httplib', 'ic', 'icopen', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp', + 'importlib', 'imputil', 'inspect', 'io', 'ipaddress', 'itertools', 'jpeg', + 'json', 'keyword', 'lib2to3', 'linecache', 'locale', 'logging', 'lzma', + 'macerrors', 'macostools', 'macpath', 'macresource', 'mailbox', 'mailcap', + 'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'mimify', 'mmap', + 'modulefinder', 'msilib', 'msvcrt', 'multifile', 'multiprocessing', 'mutex', + 'netrc', 'new', 'nis', 'nntplib', 'numbers', 'operator', 'optparse', 'os', + 'ossaudiodev', 'parser', 'pathlib', 'pdb', 'pickle', 'pickletools', 'pipes', + 'pkgutil', 'platform', 'plistlib', 'popen2', 'poplib', 'posix', 'posixfile', + 'pprint', 'profile', 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', + 'queue', 'quopri', 'random', 're', 'readline', 'reprlib', 'resource', 'rexec', + 'rfc822', 'rlcompleter', 'robotparser', 'runpy', 'sched', 'secrets', 'select', + 'selectors', 'sets', 'sgmllib', 'sha', 'shelve', 'shlex', 'shutil', 'signal', + 'site', 'sitecustomize', 'smtpd', 'smtplib', 'sndhdr', 'socket', 'socketserver', + 'spwd', 'sqlite3', 'ssl', 'stat', 'statistics', 'statvfs', 'string', 'stringprep', + 'struct', 'subprocess', 'sunau', 'sunaudiodev', 'symbol', 'symtable', 'sys', + 'sysconfig', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios', + 'test', 'textwrap', 'this', 'thread', 'threading', 'time', 'timeit', 'tkinter', + 'token', 'tokenize', 'trace', 'traceback', 'tracemalloc', 'ttk', 'tty', 'turtle', + 'turtledemo', 'types', 'typing', 'unicodedata', 'unittest', 'urllib', 'urllib2', + 'urlparse', 'user', 'usercustomize', 'uu', 'uuid', 'venv', 'videoreader', + 'warnings', 'wave', 'weakref', 'webbrowser', 'whichdb', 'winreg', 'winsound', + 'wsgiref', 'xdrlib', 'xml', 'xmlrpc', 'xmlrpclib', 'zipapp', 'zipfile', + 'zipimport', 'zlib'], + 'known_third_party': ['google.appengine.api'], + 'known_first_party': [], + 'multi_line_output': WrapModes.GRID, + 'forced_separate': [], + 'indent': ' ' * 4, + 'comment_prefix': ' #', + 'length_sort': False, + 'add_imports': [], + 'remove_imports': [], + 'force_single_line': False, + 'default_section': 'FIRSTPARTY', + 'import_heading_future': '', + 'import_heading_stdlib': '', + 'import_heading_thirdparty': '', + 'import_heading_firstparty': '', + 'import_heading_localfolder': '', + 'balanced_wrapping': False, + 'use_parentheses': False, + 'order_by_type': True, + 'atomic': False, + 'lines_after_imports': -1, + 'lines_between_sections': 1, + 'lines_between_types': 0, + 'combine_as_imports': False, + 'combine_star': False, + 'keep_direct_and_as_imports': False, + 'include_trailing_comma': False, + 'from_first': False, + 'verbose': False, + 'quiet': False, + 'force_adds': False, + 'force_alphabetical_sort_within_sections': False, + 'force_alphabetical_sort': False, + 'force_grid_wrap': 0, + 'force_sort_within_sections': False, + 'show_diff': False, + 'ignore_whitespace': False, + 'no_lines_before': [], + 'no_inline_sort': False} + + +@lru_cache() +def from_path(path): + computed_settings = default.copy() + _update_settings_with_config(path, '.editorconfig', '~/.editorconfig', ('*', '*.py', '**.py'), computed_settings) + _update_settings_with_config(path, '.isort.cfg', '~/.isort.cfg', ('settings', 'isort'), computed_settings) + _update_settings_with_config(path, 'setup.cfg', None, ('isort', ), computed_settings) + _update_settings_with_config(path, 'tox.ini', None, ('isort', ), computed_settings) + return computed_settings + + +def _update_settings_with_config(path, name, default, sections, computed_settings): + editor_config_file = default and os.path.expanduser(default) + tries = 0 + current_directory = path + while current_directory and tries < MAX_CONFIG_SEARCH_DEPTH: + potential_path = os.path.join(current_directory, native_str(name)) + if os.path.exists(potential_path): + editor_config_file = potential_path + break + + new_directory = os.path.split(current_directory)[0] + if current_directory == new_directory: + break + current_directory = new_directory + tries += 1 + + if editor_config_file and os.path.exists(editor_config_file): + _update_with_config_file(editor_config_file, sections, computed_settings) + + +def _update_with_config_file(file_path, sections, computed_settings): + settings = _get_config_data(file_path, sections).copy() + if not settings: + return + + if file_path.endswith('.editorconfig'): + indent_style = settings.pop('indent_style', '').strip() + indent_size = settings.pop('indent_size', '').strip() + if indent_style == 'space': + computed_settings['indent'] = ' ' * (indent_size and int(indent_size) or 4) + elif indent_style == 'tab': + computed_settings['indent'] = '\t' * (indent_size and int(indent_size) or 1) + + max_line_length = settings.pop('max_line_length', '').strip() + if max_line_length: + computed_settings['line_length'] = float('inf') if max_line_length == 'off' else int(max_line_length) + + for key, value in itemsview(settings): + access_key = key.replace('not_', '').lower() + existing_value_type = type(default.get(access_key, '')) + if existing_value_type in (list, tuple): + # sections has fixed order values; no adding or substraction from any set + if access_key == 'sections': + computed_settings[access_key] = tuple(_as_list(value)) + else: + existing_data = set(computed_settings.get(access_key, default.get(access_key))) + if key.startswith('not_'): + computed_settings[access_key] = list(existing_data.difference(_as_list(value))) + else: + computed_settings[access_key] = list(existing_data.union(_as_list(value))) + elif existing_value_type == bool and value.lower().strip() == 'false': + computed_settings[access_key] = False + elif key.startswith('known_'): + computed_settings[access_key] = list(_as_list(value)) + elif key == 'force_grid_wrap': + try: + result = existing_value_type(value) + except ValueError: + # backwards compat + result = default.get(access_key) if value.lower().strip() == 'false' else 2 + computed_settings[access_key] = result + else: + computed_settings[access_key] = existing_value_type(value) + + +def _as_list(value): + return filter(bool, [item.strip() for item in value.replace('\n', ',').split(',')]) + + +@lru_cache() +def _get_config_data(file_path, sections): + with io.open(file_path, 'r') as config_file: + if file_path.endswith('.editorconfig'): + line = '\n' + last_position = config_file.tell() + while line: + line = config_file.readline() + if '[' in line: + config_file.seek(last_position) + break + last_position = config_file.tell() + + if sys.version_info >= (3, 2): + config = configparser.ConfigParser() + config.read_file(config_file) + else: + config = configparser.SafeConfigParser() + config.readfp(config_file) + + settings = {} + for section in sections: + if config.has_section(section): + settings.update(dict(config.items(section))) + + return settings + + return {} + + +def should_skip(filename, config, path='/'): + """Returns True if the file should be skipped based on the passed in settings.""" + for skip_path in config['skip']: + if posixpath.abspath(posixpath.join(path, filename)) == posixpath.abspath(skip_path.replace('\\', '/')): + return True + + position = os.path.split(filename) + while position[1]: + if position[1] in config['skip']: + return True + position = os.path.split(position[0]) + + for glob in config['skip_glob']: + if fnmatch.fnmatch(filename, glob): + return True + + return False diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/PKG-INFO b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/PKG-INFO new file mode 100644 index 0000000..256974c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/PKG-INFO @@ -0,0 +1,123 @@ +Metadata-Version: 1.1 +Name: lazy-object-proxy +Version: 1.3.1 +Summary: A fast and thorough lazy object proxy. +Home-page: https://github.com/ionelmc/python-lazy-object-proxy +Author: Ionel Cristian Mărieș +Author-email: contact@ionelmc.ro +License: BSD +Description: ======== + Overview + ======== + + + + A fast and thorough lazy object proxy. + + * Free software: BSD license + + Note that this is based on `wrapt`_'s ObjectProxy with one big change: it calls a function the first time the proxy object is + used, while `wrapt.ObjectProxy` just forwards the method calls to the target object. + + In other words, you use `lazy-object-proxy` when you only have the object way later and you use `wrapt.ObjectProxy` when you + want to override few methods (by subclassing) and forward everything else to the target object. + + Example:: + + def expensive_func(): + # create expensive object + return stuff + + obj = lazy_object_proxy.Proxy(expensive_func) + # function is called only when object is actually used + print(obj.foobar) # now expensive_func is called + + Installation + ============ + + :: + + pip install lazy-object-proxy + + Documentation + ============= + + https://python-lazy-object-proxy.readthedocs.io/ + + Development + =========== + + To run the all tests run:: + + tox + + Acknowledgements + ================ + + This project is based on some code from `wrapt`_ as you can see in the git history. + + .. _wrapt: https://github.com/GrahamDumpleton/wrapt + + + Changelog + ========= + + 1.3.1 (2017-05-05) + ------------------ + + * Fix broken release (``sdist`` had a broken ``MANIFEST.in``). + + 1.3.0 (2017-05-02) + ------------------ + + * Speed up arithmetic operations involving ``cext.Proxy`` subclasses. + + 1.2.2 (2016-04-14) + ------------------ + + * Added `manylinux `_ wheels. + * Minor cleanup in readme. + + 1.2.1 (2015-08-18) + ------------------ + + * Fix a memory leak (the wrapped object would get bogus references). Contributed by Astrum Kuo in + `#10 `_. + + 1.2.0 (2015-07-06) + ------------------ + + * Don't instantiate the object when __repr__ is called. This aids with debugging (allows one to see exactly in + what state the proxy is). + + 1.1.0 (2015-07-05) + ------------------ + + * Added support for pickling. The pickled value is going to be the wrapped object *without* any Proxy container. + * Fixed a memory management issue in the C extension (reference cycles weren't garbage collected due to improper + handling in the C extension). Contributed by Alvin Chow in + `#8 `_. + + 1.0.2 (2015-04-11) + ----------------------------------------- + + * First release on PyPI. + +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: Unix +Classifier: Operating System :: POSIX +Classifier: Operating System :: Microsoft :: Windows +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Utilities diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/SOURCES.txt b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/SOURCES.txt new file mode 100644 index 0000000..f7f490c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/SOURCES.txt @@ -0,0 +1,47 @@ +.bumpversion.cfg +.cookiecutterrc +.coveragerc +.editorconfig +.travis.yml +AUTHORS.rst +CHANGELOG.rst +CONTRIBUTING.rst +LICENSE +MANIFEST.in +README.rst +appveyor.yml +setup.cfg +setup.py +tox.ini +ci/appveyor-bootstrap.py +ci/appveyor-download.py +ci/appveyor-with-compiler.cmd +ci/bootstrap.py +ci/templates/.travis.yml +ci/templates/appveyor.yml +ci/templates/tox.ini +docs/authors.rst +docs/changelog.rst +docs/conf.py +docs/contributing.rst +docs/index.rst +docs/installation.rst +docs/readme.rst +docs/requirements.txt +docs/spelling_wordlist.txt +docs/usage.rst +docs/reference/index.rst +docs/reference/lazy_object_proxy.rst +src/lazy_object_proxy/__init__.py +src/lazy_object_proxy/cext.c +src/lazy_object_proxy/compat.py +src/lazy_object_proxy/simple.py +src/lazy_object_proxy/slots.py +src/lazy_object_proxy/utils.py +src/lazy_object_proxy.egg-info/PKG-INFO +src/lazy_object_proxy.egg-info/SOURCES.txt +src/lazy_object_proxy.egg-info/dependency_links.txt +src/lazy_object_proxy.egg-info/not-zip-safe +src/lazy_object_proxy.egg-info/top_level.txt +tests/compat.py +tests/test_lazy_object_proxy.py \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/dependency_links.txt b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/installed-files.txt b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/installed-files.txt new file mode 100644 index 0000000..ee5587a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/installed-files.txt @@ -0,0 +1,16 @@ +..\lazy_object_proxy\__init__.py +..\lazy_object_proxy\__pycache__\__init__.cpython-37.pyc +..\lazy_object_proxy\__pycache__\compat.cpython-37.pyc +..\lazy_object_proxy\__pycache__\simple.cpython-37.pyc +..\lazy_object_proxy\__pycache__\slots.cpython-37.pyc +..\lazy_object_proxy\__pycache__\utils.cpython-37.pyc +..\lazy_object_proxy\cext.c +..\lazy_object_proxy\compat.py +..\lazy_object_proxy\simple.py +..\lazy_object_proxy\slots.py +..\lazy_object_proxy\utils.py +PKG-INFO +SOURCES.txt +dependency_links.txt +not-zip-safe +top_level.txt diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/not-zip-safe b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/top_level.txt new file mode 100644 index 0000000..bdf032e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy-1.3.1-py3.7.egg-info/top_level.txt @@ -0,0 +1 @@ +lazy_object_proxy diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__init__.py b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__init__.py new file mode 100644 index 0000000..1fd4f87 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__init__.py @@ -0,0 +1,20 @@ +try: + import copy_reg as copyreg +except ImportError: + import copyreg + +from .utils import identity + +copyreg.constructor(identity) + +try: + from .cext import Proxy + from .cext import identity +except ImportError: + from .slots import Proxy +else: + copyreg.constructor(identity) + +__version__ = "1.3.1" + +__all__ = "Proxy", diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..e3c2d74 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000..97d4215 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/simple.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/simple.cpython-37.pyc new file mode 100644 index 0000000..c32b734 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/simple.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/slots.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/slots.cpython-37.pyc new file mode 100644 index 0000000..053dc97 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/slots.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000..c13ac24 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/__pycache__/utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/cext.c b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/cext.c new file mode 100644 index 0000000..9808657 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/cext.c @@ -0,0 +1,1421 @@ +/* ------------------------------------------------------------------------- */ + +#include "Python.h" + +#include "structmember.h" + +#ifndef PyVarObject_HEAD_INIT +#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, +#endif + +#define Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(object) \ + if (PyObject_TypeCheck(object, &Proxy_Type)) { \ + object = Proxy__ensure_wrapped((ProxyObject *)object); \ + if (!object) return NULL; \ + } + +#define Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self) if (!Proxy__ensure_wrapped(self)) return NULL; +#define Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self) if (!Proxy__ensure_wrapped(self)) return -1; + +#if PY_MAJOR_VERSION < 3 +#define Py_hash_t long +#endif + +/* ------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + + PyObject *dict; + PyObject *wrapped; + PyObject *factory; +} ProxyObject; + +PyTypeObject Proxy_Type; + + +/* ------------------------------------------------------------------------- */ + +static PyObject *identity_ref = NULL; +static PyObject * +identity(PyObject *self, PyObject *value) +{ + Py_INCREF(value); + return value; +} + +/* ------------------------------------------------------------------------- */ + +PyDoc_STRVAR(identity_doc, "Indentity function: returns the single argument."); + +static struct PyMethodDef module_functions[] = { + {"identity", identity, METH_O, identity_doc}, + {NULL, NULL} +}; + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy__ensure_wrapped(ProxyObject *self) +{ + PyObject *wrapped; + + if (self->wrapped) { + return self->wrapped; + } else { + if (self->factory) { + wrapped = PyObject_CallFunctionObjArgs(self->factory, NULL); + if (wrapped) { + self->wrapped = wrapped; + return wrapped; + } else { + return NULL; + } + } else { + PyErr_SetString(PyExc_ValueError, "Proxy hasn't been initiated: __factory__ is missing."); + return NULL; + } + } +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_new(PyTypeObject *type, + PyObject *args, PyObject *kwds) +{ + ProxyObject *self; + + self = (ProxyObject *)type->tp_alloc(type, 0); + + if (!self) + return NULL; + + self->dict = PyDict_New(); + self->wrapped = NULL; + self->factory = NULL; + + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_raw_init(ProxyObject *self, + PyObject *factory) +{ + Py_INCREF(factory); + Py_XDECREF(self->wrapped); + Py_XDECREF(self->factory); + self->factory = factory; + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_init(ProxyObject *self, + PyObject *args, PyObject *kwds) +{ + PyObject *wrapped = NULL; + + static char *kwlist[] = { "wrapped", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:ObjectProxy", + kwlist, &wrapped)) { + return -1; + } + + return Proxy_raw_init(self, wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_traverse(ProxyObject *self, + visitproc visit, void *arg) +{ + Py_VISIT(self->dict); + Py_VISIT(self->wrapped); + Py_VISIT(self->factory); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_clear(ProxyObject *self) +{ + Py_CLEAR(self->dict); + Py_CLEAR(self->wrapped); + Py_CLEAR(self->factory); + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static void Proxy_dealloc(ProxyObject *self) +{ + PyObject_GC_UnTrack(self); + + Proxy_clear(self); + + Py_TYPE(self)->tp_free(self); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_repr(ProxyObject *self) +{ + +#if PY_MAJOR_VERSION < 3 + PyObject *factory_repr; + + factory_repr = PyObject_Repr(self->factory); + if (factory_repr == NULL) + return NULL; +#endif + + if (self->wrapped) { +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("<%s at %p wrapping %R at %p with factory %R>", + Py_TYPE(self)->tp_name, self, + self->wrapped, self->wrapped, + self->factory); +#else + PyObject *wrapped_repr; + + wrapped_repr = PyObject_Repr(self->wrapped); + if (wrapped_repr == NULL) + return NULL; + + return PyString_FromFormat("<%s at %p wrapping %s at %p with factory %s>", + Py_TYPE(self)->tp_name, self, + PyString_AS_STRING(wrapped_repr), self->wrapped, + PyString_AS_STRING(factory_repr)); +#endif + } else { +#if PY_MAJOR_VERSION >= 3 + return PyUnicode_FromFormat("<%s at %p with factory %R>", + Py_TYPE(self)->tp_name, self, + self->factory); +#else + return PyString_FromFormat("<%s at %p with factory %s>", + Py_TYPE(self)->tp_name, self, + PyString_AS_STRING(factory_repr)); +#endif + } +} + +/* ------------------------------------------------------------------------- */ + +static Py_hash_t Proxy_hash(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PyObject_Hash(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_str(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_Str(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_add(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Add(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_subtract(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Subtract(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_multiply(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Multiply(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION < 3 +static PyObject *Proxy_divide(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Divide(o1, o2); +} +#endif + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_remainder(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Remainder(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_divmod(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Divmod(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_power(PyObject *o1, PyObject *o2, + PyObject *modulo) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Power(o1, o2, modulo); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_negative(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Negative(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_positive(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Positive(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_absolute(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Absolute(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_bool(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PyObject_IsTrue(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_invert(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Invert(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_lshift(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Lshift(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_rshift(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Rshift(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_and(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_And(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_xor(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Xor(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_or(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_Or(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION < 3 +static PyObject *Proxy_int(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Int(self->wrapped); +} +#endif + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_long(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Long(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_float(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Float(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION < 3 +static PyObject *Proxy_oct(ProxyObject *self) +{ + PyNumberMethods *nb; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + if ((nb = self->wrapped->ob_type->tp_as_number) == NULL || + nb->nb_oct == NULL) { + PyErr_SetString(PyExc_TypeError, + "oct() argument can't be converted to oct"); + return NULL; + } + + return (*nb->nb_oct)(self->wrapped); +} +#endif + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION < 3 +static PyObject *Proxy_hex(ProxyObject *self) +{ + PyNumberMethods *nb; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + if ((nb = self->wrapped->ob_type->tp_as_number) == NULL || + nb->nb_hex == NULL) { + PyErr_SetString(PyExc_TypeError, + "hex() argument can't be converted to hex"); + return NULL; + } + + return (*nb->nb_hex)(self->wrapped); +} +#endif + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_add(ProxyObject *self, + PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceAdd(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_subtract( + ProxyObject *self, PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceSubtract(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_multiply( + ProxyObject *self, PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceMultiply(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION < 3 +static PyObject *Proxy_inplace_divide( + ProxyObject *self, PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceDivide(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} +#endif + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_remainder( + ProxyObject *self, PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceRemainder(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_power(ProxyObject *self, + PyObject *other, PyObject *modulo) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlacePower(self->wrapped, other, modulo); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_lshift(ProxyObject *self, + PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceLshift(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_rshift(ProxyObject *self, + PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceRshift(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_and(ProxyObject *self, + PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceAnd(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_xor(ProxyObject *self, + PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceXor(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_or(ProxyObject *self, + PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceOr(self->wrapped, other); + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_floor_divide(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_FloorDivide(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_true_divide(PyObject *o1, PyObject *o2) +{ + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); + + return PyNumber_TrueDivide(o1, o2); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_floor_divide( + ProxyObject *self, PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceFloorDivide(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_inplace_true_divide( + ProxyObject *self, PyObject *other) +{ + PyObject *object = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(other); + + object = PyNumber_InPlaceTrueDivide(self->wrapped, other); + + if (!object) + return NULL; + + Py_DECREF(self->wrapped); + self->wrapped = object; + + Py_INCREF(self); + return (PyObject *)self; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_index(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyNumber_Index(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static Py_ssize_t Proxy_length(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PyObject_Length(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_contains(ProxyObject *self, + PyObject *value) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PySequence_Contains(self->wrapped, value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_getitem(ProxyObject *self, + PyObject *key) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetItem(self->wrapped, key); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_setitem(ProxyObject *self, + PyObject *key, PyObject* value) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + if (value == NULL) + return PyObject_DelItem(self->wrapped, key); + else + return PyObject_SetItem(self->wrapped, key, value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_dir( + ProxyObject *self, PyObject *args) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_Dir(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_enter( + ProxyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *method = NULL; + PyObject *result = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + method = PyObject_GetAttrString(self->wrapped, "__enter__"); + + if (!method) + return NULL; + + result = PyObject_Call(method, args, kwds); + + Py_DECREF(method); + + return result; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_exit( + ProxyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *method = NULL; + PyObject *result = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + method = PyObject_GetAttrString(self->wrapped, "__exit__"); + + if (!method) + return NULL; + + result = PyObject_Call(method, args, kwds); + + Py_DECREF(method); + + return result; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_bytes( + ProxyObject *self, PyObject *args) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_Bytes(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_reversed( + ProxyObject *self, PyObject *args) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_CallFunctionObjArgs((PyObject *)&PyReversed_Type, + self->wrapped, NULL); +} + +/* ------------------------------------------------------------------------- */ +static PyObject *Proxy_reduce( + ProxyObject *self, PyObject *args) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return Py_BuildValue("(O(O))", identity_ref, self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION >= 3 +static PyObject *Proxy_round( + ProxyObject *self, PyObject *args) +{ + PyObject *module = NULL; + PyObject *dict = NULL; + PyObject *round = NULL; + + PyObject *result = NULL; + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + module = PyImport_ImportModule("builtins"); + + if (!module) + return NULL; + + dict = PyModule_GetDict(module); + round = PyDict_GetItemString(dict, "round"); + + if (!round) { + Py_DECREF(module); + return NULL; + } + + Py_INCREF(round); + Py_DECREF(module); + + result = PyObject_CallFunctionObjArgs(round, self->wrapped, NULL); + + Py_DECREF(round); + + return result; +} +#endif + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_name( + ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetAttrString(self->wrapped, "__name__"); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_set_name(ProxyObject *self, + PyObject *value) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PyObject_SetAttrString(self->wrapped, "__name__", value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_qualname( + ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetAttrString(self->wrapped, "__qualname__"); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_set_qualname(ProxyObject *self, + PyObject *value) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PyObject_SetAttrString(self->wrapped, "__qualname__", value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_module( + ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetAttrString(self->wrapped, "__module__"); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_set_module(ProxyObject *self, + PyObject *value) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + if (PyObject_SetAttrString(self->wrapped, "__module__", value) == -1) + return -1; + + return PyDict_SetItemString(self->dict, "__module__", value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_doc( + ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetAttrString(self->wrapped, "__doc__"); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_set_doc(ProxyObject *self, + PyObject *value) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + if (PyObject_SetAttrString(self->wrapped, "__doc__", value) == -1) + return -1; + + return PyDict_SetItemString(self->dict, "__doc__", value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_class( + ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetAttrString(self->wrapped, "__class__"); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_annotations( + ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetAttrString(self->wrapped, "__annotations__"); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_set_annotations(ProxyObject *self, + PyObject *value) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PyObject_SetAttrString(self->wrapped, "__annotations__", value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_wrapped( + ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + Py_INCREF(self->wrapped); + return self->wrapped; +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_set_wrapped(ProxyObject *self, + PyObject *value) +{ + if (value) Py_INCREF(value); + Py_XDECREF(self->wrapped); + + self->wrapped = value; + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_get_factory( + ProxyObject *self) +{ + Py_INCREF(self->factory); + return self->factory; +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_set_factory(ProxyObject *self, + PyObject *value) +{ + if (value) Py_INCREF(value); + Py_XDECREF(self->factory); + + self->factory = value; + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_getattro( + ProxyObject *self, PyObject *name) +{ + PyObject *object = NULL; + PyObject *result = NULL; + + static PyObject *getattr_str = NULL; + + object = PyObject_GenericGetAttr((PyObject *)self, name); + + if (object) + return object; + + PyErr_Clear(); + + if (!getattr_str) { +#if PY_MAJOR_VERSION >= 3 + getattr_str = PyUnicode_InternFromString("__getattr__"); +#else + getattr_str = PyString_InternFromString("__getattr__"); +#endif + } + + object = PyObject_GenericGetAttr((PyObject *)self, getattr_str); + + if (!object) + return NULL; + + result = PyObject_CallFunctionObjArgs(object, name, NULL); + + Py_DECREF(object); + + return result; +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_getattr( + ProxyObject *self, PyObject *args) +{ + PyObject *name = NULL; + +#if PY_MAJOR_VERSION >= 3 + if (!PyArg_ParseTuple(args, "U:__getattr__", &name)) + return NULL; +#else + if (!PyArg_ParseTuple(args, "S:__getattr__", &name)) + return NULL; +#endif + + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetAttr(self->wrapped, name); +} + +/* ------------------------------------------------------------------------- */ + +static int Proxy_setattro( + ProxyObject *self, PyObject *name, PyObject *value) +{ + if (PyObject_HasAttr((PyObject *)Py_TYPE(self), name)) + return PyObject_GenericSetAttr((PyObject *)self, name, value); + + Proxy__ENSURE_WRAPPED_OR_RETURN_MINUS1(self); + + return PyObject_SetAttr(self->wrapped, name, value); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_richcompare(ProxyObject *self, + PyObject *other, int opcode) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_RichCompare(self->wrapped, other, opcode); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_iter(ProxyObject *self) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_GetIter(self->wrapped); +} + +/* ------------------------------------------------------------------------- */ + +static PyObject *Proxy_call( + ProxyObject *self, PyObject *args, PyObject *kwds) +{ + Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); + + return PyObject_Call(self->wrapped, args, kwds); +} + +/* ------------------------------------------------------------------------- */; + +static PyNumberMethods Proxy_as_number = { + (binaryfunc)Proxy_add, /*nb_add*/ + (binaryfunc)Proxy_subtract, /*nb_subtract*/ + (binaryfunc)Proxy_multiply, /*nb_multiply*/ +#if PY_MAJOR_VERSION < 3 + (binaryfunc)Proxy_divide, /*nb_divide*/ +#endif + (binaryfunc)Proxy_remainder, /*nb_remainder*/ + (binaryfunc)Proxy_divmod, /*nb_divmod*/ + (ternaryfunc)Proxy_power, /*nb_power*/ + (unaryfunc)Proxy_negative, /*nb_negative*/ + (unaryfunc)Proxy_positive, /*nb_positive*/ + (unaryfunc)Proxy_absolute, /*nb_absolute*/ + (inquiry)Proxy_bool, /*nb_nonzero/nb_bool*/ + (unaryfunc)Proxy_invert, /*nb_invert*/ + (binaryfunc)Proxy_lshift, /*nb_lshift*/ + (binaryfunc)Proxy_rshift, /*nb_rshift*/ + (binaryfunc)Proxy_and, /*nb_and*/ + (binaryfunc)Proxy_xor, /*nb_xor*/ + (binaryfunc)Proxy_or, /*nb_or*/ +#if PY_MAJOR_VERSION < 3 + 0, /*nb_coerce*/ +#endif +#if PY_MAJOR_VERSION < 3 + (unaryfunc)Proxy_int, /*nb_int*/ + (unaryfunc)Proxy_long, /*nb_long*/ +#else + (unaryfunc)Proxy_long, /*nb_int*/ + 0, /*nb_long/nb_reserved*/ +#endif + (unaryfunc)Proxy_float, /*nb_float*/ +#if PY_MAJOR_VERSION < 3 + (unaryfunc)Proxy_oct, /*nb_oct*/ + (unaryfunc)Proxy_hex, /*nb_hex*/ +#endif + (binaryfunc)Proxy_inplace_add, /*nb_inplace_add*/ + (binaryfunc)Proxy_inplace_subtract, /*nb_inplace_subtract*/ + (binaryfunc)Proxy_inplace_multiply, /*nb_inplace_multiply*/ +#if PY_MAJOR_VERSION < 3 + (binaryfunc)Proxy_inplace_divide, /*nb_inplace_divide*/ +#endif + (binaryfunc)Proxy_inplace_remainder, /*nb_inplace_remainder*/ + (ternaryfunc)Proxy_inplace_power, /*nb_inplace_power*/ + (binaryfunc)Proxy_inplace_lshift, /*nb_inplace_lshift*/ + (binaryfunc)Proxy_inplace_rshift, /*nb_inplace_rshift*/ + (binaryfunc)Proxy_inplace_and, /*nb_inplace_and*/ + (binaryfunc)Proxy_inplace_xor, /*nb_inplace_xor*/ + (binaryfunc)Proxy_inplace_or, /*nb_inplace_or*/ + (binaryfunc)Proxy_floor_divide, /*nb_floor_divide*/ + (binaryfunc)Proxy_true_divide, /*nb_true_divide*/ + (binaryfunc)Proxy_inplace_floor_divide, /*nb_inplace_floor_divide*/ + (binaryfunc)Proxy_inplace_true_divide, /*nb_inplace_true_divide*/ + (unaryfunc)Proxy_index, /*nb_index*/ +}; + +static PySequenceMethods Proxy_as_sequence = { + (lenfunc)Proxy_length, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + 0, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + (objobjproc)Proxy_contains, /* sq_contains */ +}; + +static PyMappingMethods Proxy_as_mapping = { + (lenfunc)Proxy_length, /*mp_length*/ + (binaryfunc)Proxy_getitem, /*mp_subscript*/ + (objobjargproc)Proxy_setitem, /*mp_ass_subscript*/ +}; + +static PyMethodDef Proxy_methods[] = { + { "__dir__", (PyCFunction)Proxy_dir, METH_NOARGS, 0 }, + { "__enter__", (PyCFunction)Proxy_enter, + METH_VARARGS | METH_KEYWORDS, 0 }, + { "__exit__", (PyCFunction)Proxy_exit, + METH_VARARGS | METH_KEYWORDS, 0 }, + { "__getattr__", (PyCFunction)Proxy_getattr, + METH_VARARGS , 0 }, + { "__bytes__", (PyCFunction)Proxy_bytes, METH_NOARGS, 0 }, + { "__reversed__", (PyCFunction)Proxy_reversed, METH_NOARGS, 0 }, + { "__reduce__", (PyCFunction)Proxy_reduce, METH_NOARGS, 0 }, + { "__reduce_ex__", (PyCFunction)Proxy_reduce, METH_O, 0 }, +#if PY_MAJOR_VERSION >= 3 + { "__round__", (PyCFunction)Proxy_round, METH_NOARGS, 0 }, +#endif + { NULL, NULL }, +}; + +static PyGetSetDef Proxy_getset[] = { + { "__name__", (getter)Proxy_get_name, + (setter)Proxy_set_name, 0 }, + { "__qualname__", (getter)Proxy_get_qualname, + (setter)Proxy_set_qualname, 0 }, + { "__module__", (getter)Proxy_get_module, + (setter)Proxy_set_module, 0 }, + { "__doc__", (getter)Proxy_get_doc, + (setter)Proxy_set_doc, 0 }, + { "__class__", (getter)Proxy_get_class, + NULL, 0 }, + { "__annotations__", (getter)Proxy_get_annotations, + (setter)Proxy_set_annotations, 0 }, + { "__wrapped__", (getter)Proxy_get_wrapped, + (setter)Proxy_set_wrapped, 0 }, + { "__factory__", (getter)Proxy_get_factory, + (setter)Proxy_set_factory, 0 }, + { NULL }, +}; + +PyTypeObject Proxy_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "Proxy", /*tp_name*/ + sizeof(ProxyObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)Proxy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (unaryfunc)Proxy_repr, /*tp_repr*/ + &Proxy_as_number, /*tp_as_number*/ + &Proxy_as_sequence, /*tp_as_sequence*/ + &Proxy_as_mapping, /*tp_as_mapping*/ + (hashfunc)Proxy_hash, /*tp_hash*/ + (ternaryfunc)Proxy_call, /*tp_call*/ + (unaryfunc)Proxy_str, /*tp_str*/ + (getattrofunc)Proxy_getattro, /*tp_getattro*/ + (setattrofunc)Proxy_setattro, /*tp_setattro*/ + 0, /*tp_as_buffer*/ +#if PY_MAJOR_VERSION < 3 + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES, + /*tp_flags*/ +#else + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + /*tp_flags*/ +#endif + 0, /*tp_doc*/ + (traverseproc)Proxy_traverse, /*tp_traverse*/ + (inquiry)Proxy_clear, /*tp_clear*/ + (richcmpfunc)Proxy_richcompare, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + (getiterfunc)Proxy_iter, /*tp_iter*/ + 0, /*tp_iternext*/ + Proxy_methods, /*tp_methods*/ + 0, /*tp_members*/ + Proxy_getset, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + offsetof(ProxyObject, dict), /*tp_dictoffset*/ + (initproc)Proxy_init, /*tp_init*/ + PyType_GenericAlloc, /*tp_alloc*/ + Proxy_new, /*tp_new*/ + PyObject_GC_Del, /*tp_free*/ + 0, /*tp_is_gc*/ +}; + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "lazy_object_proxy.cext", /* m_name */ + NULL, /* m_doc */ + -1, /* m_size */ + module_functions, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; +#endif + +static PyObject * +moduleinit(void) +{ + PyObject *module; + PyObject *dict; + +#if PY_MAJOR_VERSION >= 3 + module = PyModule_Create(&moduledef); +#else + module = Py_InitModule3("lazy_object_proxy.cext", module_functions, NULL); +#endif + + if (module == NULL) + return NULL; + + if (PyType_Ready(&Proxy_Type) < 0) + return NULL; + + dict = PyModule_GetDict(module); + if (dict == NULL) + return NULL; + identity_ref = PyDict_GetItemString(dict, "identity"); + if (identity_ref == NULL) + return NULL; + Py_INCREF(identity_ref); + + Py_INCREF(&Proxy_Type); + PyModule_AddObject(module, "Proxy", + (PyObject *)&Proxy_Type); + return module; +} + +#if PY_MAJOR_VERSION < 3 +PyMODINIT_FUNC initcext(void) +{ + moduleinit(); +} +#else +PyMODINIT_FUNC PyInit_cext(void) +{ + return moduleinit(); +} +#endif + +/* ------------------------------------------------------------------------- */ diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/compat.py b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/compat.py new file mode 100644 index 0000000..dc6edfa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/compat.py @@ -0,0 +1,9 @@ +import sys + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + return meta("NewBase", bases, {}) diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/simple.py b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/simple.py new file mode 100644 index 0000000..cbf05a9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/simple.py @@ -0,0 +1,246 @@ +import operator + +from .compat import PY2 +from .compat import PY3 +from .compat import with_metaclass +from .utils import cached_property +from .utils import identity + + +def make_proxy_method(code): + def proxy_wrapper(self, *args): + return code(self.__wrapped__, *args) + + return proxy_wrapper + + +class _ProxyMethods(object): + # We use properties to override the values of __module__ and + # __doc__. If we add these in ObjectProxy, the derived class + # __dict__ will still be setup to have string variants of these + # attributes and the rules of descriptors means that they appear to + # take precedence over the properties in the base class. To avoid + # that, we copy the properties into the derived class type itself + # via a meta class. In that way the properties will always take + # precedence. + + @property + def __module__(self): + return self.__wrapped__.__module__ + + @__module__.setter + def __module__(self, value): + self.__wrapped__.__module__ = value + + @property + def __doc__(self): + return self.__wrapped__.__doc__ + + @__doc__.setter + def __doc__(self, value): + self.__wrapped__.__doc__ = value + + # Need to also propagate the special __weakref__ attribute for case + # where decorating classes which will define this. If do not define + # it and use a function like inspect.getmembers() on a decorator + # class it will fail. This can't be in the derived classes. + + @property + def __weakref__(self): + return self.__wrapped__.__weakref__ + + +class _ProxyMetaType(type): + def __new__(cls, name, bases, dictionary): + # Copy our special properties into the class so that they + # always take precedence over attributes of the same name added + # during construction of a derived class. This is to save + # duplicating the implementation for them in all derived classes. + + dictionary.update(vars(_ProxyMethods)) + dictionary.pop('__dict__') + + return type.__new__(cls, name, bases, dictionary) + + +class Proxy(with_metaclass(_ProxyMetaType)): + __factory__ = None + + def __init__(self, factory): + self.__dict__['__factory__'] = factory + + @cached_property + def __wrapped__(self): + self = self.__dict__ + if '__factory__' in self: + factory = self['__factory__'] + return factory() + else: + raise ValueError("Proxy hasn't been initiated: __factory__ is missing.") + + __name__ = property(make_proxy_method(operator.attrgetter('__name__'))) + __class__ = property(make_proxy_method(operator.attrgetter('__class__'))) + __annotations__ = property(make_proxy_method(operator.attrgetter('__anotations__'))) + __dir__ = make_proxy_method(dir) + __str__ = make_proxy_method(str) + + if PY3: + __bytes__ = make_proxy_method(bytes) + + def __repr__(self, __getattr__=object.__getattribute__): + if '__wrapped__' in self.__dict__: + return '<%s at 0x%x wrapping %r at 0x%x with factory %r>' % ( + type(self).__name__, id(self), + self.__wrapped__, id(self.__wrapped__), + self.__factory__ + ) + else: + return '<%s at 0x%x with factory %r>' % ( + type(self).__name__, id(self), + self.__factory__ + ) + + __reversed__ = make_proxy_method(reversed) + + if PY3: + __round__ = make_proxy_method(round) + + __lt__ = make_proxy_method(operator.lt) + __le__ = make_proxy_method(operator.le) + __eq__ = make_proxy_method(operator.eq) + __ne__ = make_proxy_method(operator.ne) + __gt__ = make_proxy_method(operator.gt) + __ge__ = make_proxy_method(operator.ge) + __hash__ = make_proxy_method(hash) + __nonzero__ = make_proxy_method(bool) + __bool__ = make_proxy_method(bool) + + def __setattr__(self, name, value): + if hasattr(type(self), name): + self.__dict__[name] = value + else: + setattr(self.__wrapped__, name, value) + + def __getattr__(self, name): + if name in ('__wrapped__', '__factory__'): + raise AttributeError(name) + else: + return getattr(self.__wrapped__, name) + + def __delattr__(self, name): + if hasattr(type(self), name): + del self.__dict__[name] + else: + delattr(self.__wrapped__, name) + + __add__ = make_proxy_method(operator.add) + __sub__ = make_proxy_method(operator.sub) + __mul__ = make_proxy_method(operator.mul) + __div__ = make_proxy_method(operator.div if PY2 else operator.truediv) + __truediv__ = make_proxy_method(operator.truediv) + __floordiv__ = make_proxy_method(operator.floordiv) + __mod__ = make_proxy_method(operator.mod) + __divmod__ = make_proxy_method(divmod) + __pow__ = make_proxy_method(pow) + __lshift__ = make_proxy_method(operator.lshift) + __rshift__ = make_proxy_method(operator.rshift) + __and__ = make_proxy_method(operator.and_) + __xor__ = make_proxy_method(operator.xor) + __or__ = make_proxy_method(operator.or_) + + def __radd__(self, other): + return other + self.__wrapped__ + + def __rsub__(self, other): + return other - self.__wrapped__ + + def __rmul__(self, other): + return other * self.__wrapped__ + + def __rdiv__(self, other): + return operator.div(other, self.__wrapped__) + + def __rtruediv__(self, other): + return operator.truediv(other, self.__wrapped__) + + def __rfloordiv__(self, other): + return other // self.__wrapped__ + + def __rmod__(self, other): + return other % self.__wrapped__ + + def __rdivmod__(self, other): + return divmod(other, self.__wrapped__) + + def __rpow__(self, other, *args): + return pow(other, self.__wrapped__, *args) + + def __rlshift__(self, other): + return other << self.__wrapped__ + + def __rrshift__(self, other): + return other >> self.__wrapped__ + + def __rand__(self, other): + return other & self.__wrapped__ + + def __rxor__(self, other): + return other ^ self.__wrapped__ + + def __ror__(self, other): + return other | self.__wrapped__ + + __iadd__ = make_proxy_method(operator.iadd) + __isub__ = make_proxy_method(operator.isub) + __imul__ = make_proxy_method(operator.imul) + __idiv__ = make_proxy_method(operator.idiv if PY2 else operator.itruediv) + __itruediv__ = make_proxy_method(operator.itruediv) + __ifloordiv__ = make_proxy_method(operator.ifloordiv) + __imod__ = make_proxy_method(operator.imod) + __ipow__ = make_proxy_method(operator.ipow) + __ilshift__ = make_proxy_method(operator.ilshift) + __irshift__ = make_proxy_method(operator.irshift) + __iand__ = make_proxy_method(operator.iand) + __ixor__ = make_proxy_method(operator.ixor) + __ior__ = make_proxy_method(operator.ior) + __neg__ = make_proxy_method(operator.neg) + __pos__ = make_proxy_method(operator.pos) + __abs__ = make_proxy_method(operator.abs) + __invert__ = make_proxy_method(operator.invert) + + __int__ = make_proxy_method(int) + + if PY2: + __long__ = make_proxy_method(long) # flake8: noqa + + __float__ = make_proxy_method(float) + __oct__ = make_proxy_method(oct) + __hex__ = make_proxy_method(hex) + __index__ = make_proxy_method(operator.index) + __len__ = make_proxy_method(len) + __contains__ = make_proxy_method(operator.contains) + __getitem__ = make_proxy_method(operator.getitem) + __setitem__ = make_proxy_method(operator.setitem) + __delitem__ = make_proxy_method(operator.delitem) + + if PY2: + __getslice__ = make_proxy_method(operator.getslice) + __setslice__ = make_proxy_method(operator.setslice) + __delslice__ = make_proxy_method(operator.delslice) + + def __enter__(self): + return self.__wrapped__.__enter__() + + def __exit__(self, *args, **kwargs): + return self.__wrapped__.__exit__(*args, **kwargs) + + __iter__ = make_proxy_method(iter) + + def __call__(self, *args, **kwargs): + return self.__wrapped__(*args, **kwargs) + + def __reduce__(self): + return identity, (self.__wrapped__,) + + def __reduce_ex__(self, protocol): + return identity, (self.__wrapped__,) diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/slots.py b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/slots.py new file mode 100644 index 0000000..2586de4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/slots.py @@ -0,0 +1,414 @@ +import operator + +from .compat import PY2 +from .compat import PY3 +from .compat import with_metaclass +from .utils import identity + + +class _ProxyMethods(object): + # We use properties to override the values of __module__ and + # __doc__. If we add these in ObjectProxy, the derived class + # __dict__ will still be setup to have string variants of these + # attributes and the rules of descriptors means that they appear to + # take precedence over the properties in the base class. To avoid + # that, we copy the properties into the derived class type itself + # via a meta class. In that way the properties will always take + # precedence. + + @property + def __module__(self): + return self.__wrapped__.__module__ + + @__module__.setter + def __module__(self, value): + self.__wrapped__.__module__ = value + + @property + def __doc__(self): + return self.__wrapped__.__doc__ + + @__doc__.setter + def __doc__(self, value): + self.__wrapped__.__doc__ = value + + # We similar use a property for __dict__. We need __dict__ to be + # explicit to ensure that vars() works as expected. + + @property + def __dict__(self): + return self.__wrapped__.__dict__ + + # Need to also propagate the special __weakref__ attribute for case + # where decorating classes which will define this. If do not define + # it and use a function like inspect.getmembers() on a decorator + # class it will fail. This can't be in the derived classes. + + @property + def __weakref__(self): + return self.__wrapped__.__weakref__ + + +class _ProxyMetaType(type): + def __new__(cls, name, bases, dictionary): + # Copy our special properties into the class so that they + # always take precedence over attributes of the same name added + # during construction of a derived class. This is to save + # duplicating the implementation for them in all derived classes. + + dictionary.update(vars(_ProxyMethods)) + + return type.__new__(cls, name, bases, dictionary) + + +class Proxy(with_metaclass(_ProxyMetaType)): + """ + A proxy implementation in pure Python, using slots. You can subclass this to add + local methods or attributes, or enable __dict__. + + The most important internals: + + * ``__factory__`` is the callback that "materializes" the object we proxy to. + * ``__target__`` will contain the object we proxy to, once it's "materialized". + * ``__wrapped__`` is a property that does either: + + * return ``__target__`` if it's set. + * calls ``__factory__``, saves result to ``__target__`` and returns said result. + """ + + __slots__ = '__target__', '__factory__' + + def __init__(self, factory): + object.__setattr__(self, '__factory__', factory) + + @property + def __wrapped__(self, __getattr__=object.__getattribute__, __setattr__=object.__setattr__, + __delattr__=object.__delattr__): + try: + return __getattr__(self, '__target__') + except AttributeError: + try: + factory = __getattr__(self, '__factory__') + except AttributeError: + raise ValueError("Proxy hasn't been initiated: __factory__ is missing.") + target = factory() + __setattr__(self, '__target__', target) + return target + + @__wrapped__.deleter + def __wrapped__(self, __delattr__=object.__delattr__): + __delattr__(self, '__target__') + + @__wrapped__.setter + def __wrapped__(self, target, __setattr__=object.__setattr__): + __setattr__(self, '__target__', target) + + @property + def __name__(self): + return self.__wrapped__.__name__ + + @__name__.setter + def __name__(self, value): + self.__wrapped__.__name__ = value + + @property + def __class__(self): + return self.__wrapped__.__class__ + + @__class__.setter + def __class__(self, value): + self.__wrapped__.__class__ = value + + @property + def __annotations__(self): + return self.__wrapped__.__anotations__ + + @__annotations__.setter + def __annotations__(self, value): + self.__wrapped__.__annotations__ = value + + def __dir__(self): + return dir(self.__wrapped__) + + def __str__(self): + return str(self.__wrapped__) + + if PY3: + def __bytes__(self): + return bytes(self.__wrapped__) + + def __repr__(self, __getattr__=object.__getattribute__): + try: + target = __getattr__(self, '__target__') + except AttributeError: + return '<%s at 0x%x with factory %r>' % ( + type(self).__name__, id(self), + self.__factory__ + ) + else: + return '<%s at 0x%x wrapping %r at 0x%x with factory %r>' % ( + type(self).__name__, id(self), + target, id(target), + self.__factory__ + ) + + def __reversed__(self): + return reversed(self.__wrapped__) + + if PY3: + def __round__(self): + return round(self.__wrapped__) + + def __lt__(self, other): + return self.__wrapped__ < other + + def __le__(self, other): + return self.__wrapped__ <= other + + def __eq__(self, other): + return self.__wrapped__ == other + + def __ne__(self, other): + return self.__wrapped__ != other + + def __gt__(self, other): + return self.__wrapped__ > other + + def __ge__(self, other): + return self.__wrapped__ >= other + + def __hash__(self): + return hash(self.__wrapped__) + + def __nonzero__(self): + return bool(self.__wrapped__) + + def __bool__(self): + return bool(self.__wrapped__) + + def __setattr__(self, name, value, __setattr__=object.__setattr__): + if hasattr(type(self), name): + __setattr__(self, name, value) + else: + setattr(self.__wrapped__, name, value) + + def __getattr__(self, name): + if name in ('__wrapped__', '__factory__'): + raise AttributeError(name) + else: + return getattr(self.__wrapped__, name) + + def __delattr__(self, name, __delattr__=object.__delattr__): + if hasattr(type(self), name): + __delattr__(self, name) + else: + delattr(self.__wrapped__, name) + + def __add__(self, other): + return self.__wrapped__ + other + + def __sub__(self, other): + return self.__wrapped__ - other + + def __mul__(self, other): + return self.__wrapped__ * other + + def __div__(self, other): + return operator.div(self.__wrapped__, other) + + def __truediv__(self, other): + return operator.truediv(self.__wrapped__, other) + + def __floordiv__(self, other): + return self.__wrapped__ // other + + def __mod__(self, other): + return self.__wrapped__ ^ other + + def __divmod__(self, other): + return divmod(self.__wrapped__, other) + + def __pow__(self, other, *args): + return pow(self.__wrapped__, other, *args) + + def __lshift__(self, other): + return self.__wrapped__ << other + + def __rshift__(self, other): + return self.__wrapped__ >> other + + def __and__(self, other): + return self.__wrapped__ & other + + def __xor__(self, other): + return self.__wrapped__ ^ other + + def __or__(self, other): + return self.__wrapped__ | other + + def __radd__(self, other): + return other + self.__wrapped__ + + def __rsub__(self, other): + return other - self.__wrapped__ + + def __rmul__(self, other): + return other * self.__wrapped__ + + def __rdiv__(self, other): + return operator.div(other, self.__wrapped__) + + def __rtruediv__(self, other): + return operator.truediv(other, self.__wrapped__) + + def __rfloordiv__(self, other): + return other // self.__wrapped__ + + def __rmod__(self, other): + return other % self.__wrapped__ + + def __rdivmod__(self, other): + return divmod(other, self.__wrapped__) + + def __rpow__(self, other, *args): + return pow(other, self.__wrapped__, *args) + + def __rlshift__(self, other): + return other << self.__wrapped__ + + def __rrshift__(self, other): + return other >> self.__wrapped__ + + def __rand__(self, other): + return other & self.__wrapped__ + + def __rxor__(self, other): + return other ^ self.__wrapped__ + + def __ror__(self, other): + return other | self.__wrapped__ + + def __iadd__(self, other): + self.__wrapped__ += other + return self + + def __isub__(self, other): + self.__wrapped__ -= other + return self + + def __imul__(self, other): + self.__wrapped__ *= other + return self + + def __idiv__(self, other): + self.__wrapped__ = operator.idiv(self.__wrapped__, other) + return self + + def __itruediv__(self, other): + self.__wrapped__ = operator.itruediv(self.__wrapped__, other) + return self + + def __ifloordiv__(self, other): + self.__wrapped__ //= other + return self + + def __imod__(self, other): + self.__wrapped__ %= other + return self + + def __ipow__(self, other): + self.__wrapped__ **= other + return self + + def __ilshift__(self, other): + self.__wrapped__ <<= other + return self + + def __irshift__(self, other): + self.__wrapped__ >>= other + return self + + def __iand__(self, other): + self.__wrapped__ &= other + return self + + def __ixor__(self, other): + self.__wrapped__ ^= other + return self + + def __ior__(self, other): + self.__wrapped__ |= other + return self + + def __neg__(self): + return -self.__wrapped__ + + def __pos__(self): + return +self.__wrapped__ + + def __abs__(self): + return abs(self.__wrapped__) + + def __invert__(self): + return ~self.__wrapped__ + + def __int__(self): + return int(self.__wrapped__) + + if PY2: + def __long__(self): + return long(self.__wrapped__) # flake8: noqa + + def __float__(self): + return float(self.__wrapped__) + + def __oct__(self): + return oct(self.__wrapped__) + + def __hex__(self): + return hex(self.__wrapped__) + + def __index__(self): + return operator.index(self.__wrapped__) + + def __len__(self): + return len(self.__wrapped__) + + def __contains__(self, value): + return value in self.__wrapped__ + + def __getitem__(self, key): + return self.__wrapped__[key] + + def __setitem__(self, key, value): + self.__wrapped__[key] = value + + def __delitem__(self, key): + del self.__wrapped__[key] + + def __getslice__(self, i, j): + return self.__wrapped__[i:j] + + def __setslice__(self, i, j, value): + self.__wrapped__[i:j] = value + + def __delslice__(self, i, j): + del self.__wrapped__[i:j] + + def __enter__(self): + return self.__wrapped__.__enter__() + + def __exit__(self, *args, **kwargs): + return self.__wrapped__.__exit__(*args, **kwargs) + + def __iter__(self): + return iter(self.__wrapped__) + + def __call__(self, *args, **kwargs): + return self.__wrapped__(*args, **kwargs) + + def __reduce__(self): + return identity, (self.__wrapped__,) + + def __reduce_ex__(self, protocol): + return identity, (self.__wrapped__,) diff --git a/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/utils.py b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/utils.py new file mode 100644 index 0000000..ceb3050 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/lazy_object_proxy/utils.py @@ -0,0 +1,13 @@ +def identity(obj): + return obj + + +class cached_property(object): + def __init__(self, func): + self.func = func + + def __get__(self, obj, cls): + if obj is None: + return self + value = obj.__dict__[self.func.__name__] = self.func(obj) + return value diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..de61068 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/DESCRIPTION.rst @@ -0,0 +1,152 @@ +McCabe complexity checker +========================= + +Ned's script to check McCabe complexity. + +This module provides a plugin for ``flake8``, the Python code checker. + + +Installation +------------ + +You can install, upgrade, uninstall ``mccabe`` with these commands:: + + $ pip install mccabe + $ pip install --upgrade mccabe + $ pip uninstall mccabe + + +Standalone script +----------------- + +The complexity checker can be used directly:: + + $ python -m mccabe --min 5 mccabe.py + ("185:1: 'PathGraphingAstVisitor.visitIf'", 5) + ("71:1: 'PathGraph.to_dot'", 5) + ("245:1: 'McCabeChecker.run'", 5) + ("283:1: 'main'", 7) + ("203:1: 'PathGraphingAstVisitor.visitTryExcept'", 5) + ("257:1: 'get_code_complexity'", 5) + + +Plugin for Flake8 +----------------- + +When both ``flake8 2.0`` and ``mccabe`` are installed, the plugin is +available in ``flake8``:: + + $ flake8 --version + 2.0 (pep8: 1.4.2, pyflakes: 0.6.1, mccabe: 0.2) + +By default the plugin is disabled. Use the ``--max-complexity`` switch to +enable it. It will emit a warning if the McCabe complexity of a function is +higher that the value:: + + $ flake8 --max-complexity 10 coolproject + ... + coolproject/mod.py:1204:1: C901 'CoolFactory.prepare' is too complex (14) + +This feature is quite useful to detect over-complex code. According to McCabe, +anything that goes beyond 10 is too complex. + + +Links +----- + +* Feedback and ideas: http://mail.python.org/mailman/listinfo/code-quality + +* Cyclomatic complexity: http://en.wikipedia.org/wiki/Cyclomatic_complexity. + +* Ned Batchelder's script: + http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html + + +Changes +------- + +0.6.1 - 2017-01-26 +`````````````````` + +* Fix signature for ``PathGraphingAstVisitor.default`` to match the signature + for ``ASTVisitor`` + +0.6.0 - 2017-01-23 +`````````````````` + +* Add support for Python 3.6 + +* Fix handling for missing statement types + +0.5.3 - 2016-12-14 +`````````````````` + +* Report actual column number of violation instead of the start of the line + +0.5.2 - 2016-07-31 +`````````````````` + +* When opening files ourselves, make sure we always name the file variable + +0.5.1 - 2016-07-28 +`````````````````` + +* Set default maximum complexity to -1 on the class itself + +0.5.0 - 2016-05-30 +`````````````````` + +* PyCon 2016 PDX release + +* Add support for Flake8 3.0 + +0.4.0 - 2016-01-27 +`````````````````` + +* Stop testing on Python 3.2 + +* Add support for async/await keywords on Python 3.5 from PEP 0492 + +0.3.1 - 2015-06-14 +`````````````````` + +* Include ``test_mccabe.py`` in releases. + +* Always coerce the ``max_complexity`` value from Flake8's entry-point to an + integer. + +0.3 - 2014-12-17 +```````````````` + +* Computation was wrong: the mccabe complexity starts at 1, not 2. + +* The ``max-complexity`` value is now inclusive. E.g.: if the + value is 10 and the reported complexity is 10, then it passes. + +* Add tests. + + +0.2.1 - 2013-04-03 +`````````````````` + +* Do not require ``setuptools`` in setup.py. It works around an issue + with ``pip`` and Python 3. + + +0.2 - 2013-02-22 +```````````````` + +* Rename project to ``mccabe``. + +* Provide ``flake8.extension`` setuptools entry point. + +* Read ``max-complexity`` from the configuration file. + +* Rename argument ``min_complexity`` to ``threshold``. + + +0.1 - 2013-02-11 +```````````````` +* First release + + diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/INSTALLER b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/METADATA b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/METADATA new file mode 100644 index 0000000..f22645f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/METADATA @@ -0,0 +1,178 @@ +Metadata-Version: 2.0 +Name: mccabe +Version: 0.6.1 +Summary: McCabe checker, plugin for flake8 +Home-page: https://github.com/pycqa/mccabe +Author: Ian Cordasco +Author-email: graffatcolmingov@gmail.com +License: Expat license +Keywords: flake8 mccabe +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Software Development :: Quality Assurance + +McCabe complexity checker +========================= + +Ned's script to check McCabe complexity. + +This module provides a plugin for ``flake8``, the Python code checker. + + +Installation +------------ + +You can install, upgrade, uninstall ``mccabe`` with these commands:: + + $ pip install mccabe + $ pip install --upgrade mccabe + $ pip uninstall mccabe + + +Standalone script +----------------- + +The complexity checker can be used directly:: + + $ python -m mccabe --min 5 mccabe.py + ("185:1: 'PathGraphingAstVisitor.visitIf'", 5) + ("71:1: 'PathGraph.to_dot'", 5) + ("245:1: 'McCabeChecker.run'", 5) + ("283:1: 'main'", 7) + ("203:1: 'PathGraphingAstVisitor.visitTryExcept'", 5) + ("257:1: 'get_code_complexity'", 5) + + +Plugin for Flake8 +----------------- + +When both ``flake8 2.0`` and ``mccabe`` are installed, the plugin is +available in ``flake8``:: + + $ flake8 --version + 2.0 (pep8: 1.4.2, pyflakes: 0.6.1, mccabe: 0.2) + +By default the plugin is disabled. Use the ``--max-complexity`` switch to +enable it. It will emit a warning if the McCabe complexity of a function is +higher that the value:: + + $ flake8 --max-complexity 10 coolproject + ... + coolproject/mod.py:1204:1: C901 'CoolFactory.prepare' is too complex (14) + +This feature is quite useful to detect over-complex code. According to McCabe, +anything that goes beyond 10 is too complex. + + +Links +----- + +* Feedback and ideas: http://mail.python.org/mailman/listinfo/code-quality + +* Cyclomatic complexity: http://en.wikipedia.org/wiki/Cyclomatic_complexity. + +* Ned Batchelder's script: + http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html + + +Changes +------- + +0.6.1 - 2017-01-26 +`````````````````` + +* Fix signature for ``PathGraphingAstVisitor.default`` to match the signature + for ``ASTVisitor`` + +0.6.0 - 2017-01-23 +`````````````````` + +* Add support for Python 3.6 + +* Fix handling for missing statement types + +0.5.3 - 2016-12-14 +`````````````````` + +* Report actual column number of violation instead of the start of the line + +0.5.2 - 2016-07-31 +`````````````````` + +* When opening files ourselves, make sure we always name the file variable + +0.5.1 - 2016-07-28 +`````````````````` + +* Set default maximum complexity to -1 on the class itself + +0.5.0 - 2016-05-30 +`````````````````` + +* PyCon 2016 PDX release + +* Add support for Flake8 3.0 + +0.4.0 - 2016-01-27 +`````````````````` + +* Stop testing on Python 3.2 + +* Add support for async/await keywords on Python 3.5 from PEP 0492 + +0.3.1 - 2015-06-14 +`````````````````` + +* Include ``test_mccabe.py`` in releases. + +* Always coerce the ``max_complexity`` value from Flake8's entry-point to an + integer. + +0.3 - 2014-12-17 +```````````````` + +* Computation was wrong: the mccabe complexity starts at 1, not 2. + +* The ``max-complexity`` value is now inclusive. E.g.: if the + value is 10 and the reported complexity is 10, then it passes. + +* Add tests. + + +0.2.1 - 2013-04-03 +`````````````````` + +* Do not require ``setuptools`` in setup.py. It works around an issue + with ``pip`` and Python 3. + + +0.2 - 2013-02-22 +```````````````` + +* Rename project to ``mccabe``. + +* Provide ``flake8.extension`` setuptools entry point. + +* Read ``max-complexity`` from the configuration file. + +* Rename argument ``min_complexity`` to ``threshold``. + + +0.1 - 2013-02-11 +```````````````` +* First release + + diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/RECORD b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/RECORD new file mode 100644 index 0000000..3f5af85 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/RECORD @@ -0,0 +1,10 @@ +mccabe.py,sha256=XPMywdQshG_5nSjckb-OzNqnCQuXQvy3FTClspKwGQA,10693 +mccabe-0.6.1.dist-info/DESCRIPTION.rst,sha256=lGHJ-Y3IviuP3DRqLL_TXPUr3wJ2GZ8XJkAV6ve3O58,3302 +mccabe-0.6.1.dist-info/METADATA,sha256=jawnTfTVrlzBSmeI-cTXSRIwIlijODtZdj-padBqIv0,4324 +mccabe-0.6.1.dist-info/RECORD,, +mccabe-0.6.1.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +mccabe-0.6.1.dist-info/entry_points.txt,sha256=N2NH182GXTUyTm8r8XMgadb9C-CRa5dUr1k8OC91uGE,47 +mccabe-0.6.1.dist-info/metadata.json,sha256=e508OR4t6_G7h7eO2C6NHlHQqVpPZZH1_DlAPrVECYM,1218 +mccabe-0.6.1.dist-info/top_level.txt,sha256=21cXuqZE-lpcfAqqANvX9EjI1ED1p8zcViv064u3RKA,7 +mccabe-0.6.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +__pycache__/mccabe.cpython-37.pyc,, diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/WHEEL b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/WHEEL new file mode 100644 index 0000000..8b6dd1b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/entry_points.txt b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/entry_points.txt new file mode 100644 index 0000000..cc6645b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[flake8.extension] +C90 = mccabe:McCabeChecker + diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/metadata.json b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/metadata.json new file mode 100644 index 0000000..ae04d8f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Quality Assurance"], "extensions": {"python.details": {"contacts": [{"email": "graffatcolmingov@gmail.com", "name": "Ian Cordasco", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/pycqa/mccabe"}}, "python.exports": {"flake8.extension": {"C90": "mccabe:McCabeChecker"}}}, "generator": "bdist_wheel (0.29.0)", "keywords": ["flake8", "mccabe"], "license": "Expat license", "metadata_version": "2.0", "name": "mccabe", "summary": "McCabe checker, plugin for flake8", "test_requires": [{"requires": ["pytest"]}], "version": "0.6.1"} \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/top_level.txt new file mode 100644 index 0000000..8831b36 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe-0.6.1.dist-info/top_level.txt @@ -0,0 +1 @@ +mccabe diff --git a/basic python programmes/venv/Lib/site-packages/mccabe.py b/basic python programmes/venv/Lib/site-packages/mccabe.py new file mode 100644 index 0000000..c0cda75 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/mccabe.py @@ -0,0 +1,347 @@ +""" Meager code path measurement tool. + Ned Batchelder + http://nedbatchelder.com/blog/200803/python_code_complexity_microtool.html + MIT License. +""" +from __future__ import with_statement + +import optparse +import sys +import tokenize + +from collections import defaultdict +try: + import ast + from ast import iter_child_nodes +except ImportError: # Python 2.5 + from flake8.util import ast, iter_child_nodes + +__version__ = '0.6.1' + + +class ASTVisitor(object): + """Performs a depth-first walk of the AST.""" + + def __init__(self): + self.node = None + self._cache = {} + + def default(self, node, *args): + for child in iter_child_nodes(node): + self.dispatch(child, *args) + + def dispatch(self, node, *args): + self.node = node + klass = node.__class__ + meth = self._cache.get(klass) + if meth is None: + className = klass.__name__ + meth = getattr(self.visitor, 'visit' + className, self.default) + self._cache[klass] = meth + return meth(node, *args) + + def preorder(self, tree, visitor, *args): + """Do preorder walk of tree using visitor""" + self.visitor = visitor + visitor.visit = self.dispatch + self.dispatch(tree, *args) # XXX *args make sense? + + +class PathNode(object): + def __init__(self, name, look="circle"): + self.name = name + self.look = look + + def to_dot(self): + print('node [shape=%s,label="%s"] %d;' % ( + self.look, self.name, self.dot_id())) + + def dot_id(self): + return id(self) + + +class PathGraph(object): + def __init__(self, name, entity, lineno, column=0): + self.name = name + self.entity = entity + self.lineno = lineno + self.column = column + self.nodes = defaultdict(list) + + def connect(self, n1, n2): + self.nodes[n1].append(n2) + # Ensure that the destination node is always counted. + self.nodes[n2] = [] + + def to_dot(self): + print('subgraph {') + for node in self.nodes: + node.to_dot() + for node, nexts in self.nodes.items(): + for next in nexts: + print('%s -- %s;' % (node.dot_id(), next.dot_id())) + print('}') + + def complexity(self): + """ Return the McCabe complexity for the graph. + V-E+2 + """ + num_edges = sum([len(n) for n in self.nodes.values()]) + num_nodes = len(self.nodes) + return num_edges - num_nodes + 2 + + +class PathGraphingAstVisitor(ASTVisitor): + """ A visitor for a parsed Abstract Syntax Tree which finds executable + statements. + """ + + def __init__(self): + super(PathGraphingAstVisitor, self).__init__() + self.classname = "" + self.graphs = {} + self.reset() + + def reset(self): + self.graph = None + self.tail = None + + def dispatch_list(self, node_list): + for node in node_list: + self.dispatch(node) + + def visitFunctionDef(self, node): + + if self.classname: + entity = '%s%s' % (self.classname, node.name) + else: + entity = node.name + + name = '%d:%d: %r' % (node.lineno, node.col_offset, entity) + + if self.graph is not None: + # closure + pathnode = self.appendPathNode(name) + self.tail = pathnode + self.dispatch_list(node.body) + bottom = PathNode("", look='point') + self.graph.connect(self.tail, bottom) + self.graph.connect(pathnode, bottom) + self.tail = bottom + else: + self.graph = PathGraph(name, entity, node.lineno, node.col_offset) + pathnode = PathNode(name) + self.tail = pathnode + self.dispatch_list(node.body) + self.graphs["%s%s" % (self.classname, node.name)] = self.graph + self.reset() + + visitAsyncFunctionDef = visitFunctionDef + + def visitClassDef(self, node): + old_classname = self.classname + self.classname += node.name + "." + self.dispatch_list(node.body) + self.classname = old_classname + + def appendPathNode(self, name): + if not self.tail: + return + pathnode = PathNode(name) + self.graph.connect(self.tail, pathnode) + self.tail = pathnode + return pathnode + + def visitSimpleStatement(self, node): + if node.lineno is None: + lineno = 0 + else: + lineno = node.lineno + name = "Stmt %d" % lineno + self.appendPathNode(name) + + def default(self, node, *args): + if isinstance(node, ast.stmt): + self.visitSimpleStatement(node) + else: + super(PathGraphingAstVisitor, self).default(node, *args) + + def visitLoop(self, node): + name = "Loop %d" % node.lineno + self._subgraph(node, name) + + visitAsyncFor = visitFor = visitWhile = visitLoop + + def visitIf(self, node): + name = "If %d" % node.lineno + self._subgraph(node, name) + + def _subgraph(self, node, name, extra_blocks=()): + """create the subgraphs representing any `if` and `for` statements""" + if self.graph is None: + # global loop + self.graph = PathGraph(name, name, node.lineno, node.col_offset) + pathnode = PathNode(name) + self._subgraph_parse(node, pathnode, extra_blocks) + self.graphs["%s%s" % (self.classname, name)] = self.graph + self.reset() + else: + pathnode = self.appendPathNode(name) + self._subgraph_parse(node, pathnode, extra_blocks) + + def _subgraph_parse(self, node, pathnode, extra_blocks): + """parse the body and any `else` block of `if` and `for` statements""" + loose_ends = [] + self.tail = pathnode + self.dispatch_list(node.body) + loose_ends.append(self.tail) + for extra in extra_blocks: + self.tail = pathnode + self.dispatch_list(extra.body) + loose_ends.append(self.tail) + if node.orelse: + self.tail = pathnode + self.dispatch_list(node.orelse) + loose_ends.append(self.tail) + else: + loose_ends.append(pathnode) + if pathnode: + bottom = PathNode("", look='point') + for le in loose_ends: + self.graph.connect(le, bottom) + self.tail = bottom + + def visitTryExcept(self, node): + name = "TryExcept %d" % node.lineno + self._subgraph(node, name, extra_blocks=node.handlers) + + visitTry = visitTryExcept + + def visitWith(self, node): + name = "With %d" % node.lineno + self.appendPathNode(name) + self.dispatch_list(node.body) + + visitAsyncWith = visitWith + + +class McCabeChecker(object): + """McCabe cyclomatic complexity checker.""" + name = 'mccabe' + version = __version__ + _code = 'C901' + _error_tmpl = "C901 %r is too complex (%d)" + max_complexity = -1 + + def __init__(self, tree, filename): + self.tree = tree + + @classmethod + def add_options(cls, parser): + flag = '--max-complexity' + kwargs = { + 'default': -1, + 'action': 'store', + 'type': 'int', + 'help': 'McCabe complexity threshold', + 'parse_from_config': 'True', + } + config_opts = getattr(parser, 'config_options', None) + if isinstance(config_opts, list): + # Flake8 2.x + kwargs.pop('parse_from_config') + parser.add_option(flag, **kwargs) + parser.config_options.append('max-complexity') + else: + parser.add_option(flag, **kwargs) + + @classmethod + def parse_options(cls, options): + cls.max_complexity = int(options.max_complexity) + + def run(self): + if self.max_complexity < 0: + return + visitor = PathGraphingAstVisitor() + visitor.preorder(self.tree, visitor) + for graph in visitor.graphs.values(): + if graph.complexity() > self.max_complexity: + text = self._error_tmpl % (graph.entity, graph.complexity()) + yield graph.lineno, graph.column, text, type(self) + + +def get_code_complexity(code, threshold=7, filename='stdin'): + try: + tree = compile(code, filename, "exec", ast.PyCF_ONLY_AST) + except SyntaxError: + e = sys.exc_info()[1] + sys.stderr.write("Unable to parse %s: %s\n" % (filename, e)) + return 0 + + complx = [] + McCabeChecker.max_complexity = threshold + for lineno, offset, text, check in McCabeChecker(tree, filename).run(): + complx.append('%s:%d:1: %s' % (filename, lineno, text)) + + if len(complx) == 0: + return 0 + print('\n'.join(complx)) + return len(complx) + + +def get_module_complexity(module_path, threshold=7): + """Returns the complexity of a module""" + with open(module_path, "rU") as mod: + code = mod.read() + return get_code_complexity(code, threshold, filename=module_path) + + +def _read(filename): + if (2, 5) < sys.version_info < (3, 0): + with open(filename, 'rU') as f: + return f.read() + elif (3, 0) <= sys.version_info < (4, 0): + """Read the source code.""" + try: + with open(filename, 'rb') as f: + (encoding, _) = tokenize.detect_encoding(f.readline) + except (LookupError, SyntaxError, UnicodeError): + # Fall back if file encoding is improperly declared + with open(filename, encoding='latin-1') as f: + return f.read() + with open(filename, 'r', encoding=encoding) as f: + return f.read() + + +def main(argv=None): + if argv is None: + argv = sys.argv[1:] + opar = optparse.OptionParser() + opar.add_option("-d", "--dot", dest="dot", + help="output a graphviz dot file", action="store_true") + opar.add_option("-m", "--min", dest="threshold", + help="minimum complexity for output", type="int", + default=1) + + options, args = opar.parse_args(argv) + + code = _read(args[0]) + tree = compile(code, args[0], "exec", ast.PyCF_ONLY_AST) + visitor = PathGraphingAstVisitor() + visitor.preorder(tree, visitor) + + if options.dot: + print('graph {') + for graph in visitor.graphs.values(): + if (not options.threshold or + graph.complexity() >= options.threshold): + graph.to_dot() + print('}') + else: + for graph in visitor.graphs.values(): + if graph.complexity() >= options.threshold: + print(graph.name, graph.complexity()) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO new file mode 100644 index 0000000..c91d709 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,69 @@ +Metadata-Version: 2.1 +Name: pip +Version: 10.0.1 +Summary: The PyPA recommended tool for installing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: python-virtualenv@groups.google.com +License: MIT +Description: pip + === + + The `PyPA recommended`_ tool for installing Python packages. + + .. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + + .. image:: https://img.shields.io/travis/pypa/pip/master.svg + :target: http://travis-ci.org/pypa/pip + + .. image:: https://img.shields.io/appveyor/ci/pypa/pip.svg + :target: https://ci.appveyor.com/project/pypa/pip/history + + .. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + + * `Installation`_ + * `Documentation`_ + * `Changelog`_ + * `GitHub Page`_ + * `Issue Tracking`_ + * `User mailing list`_ + * `Dev mailing list`_ + * User IRC: #pypa on Freenode. + * Dev IRC: #pypa-dev on Freenode. + + Code of Conduct + --------------- + + Everyone interacting in the pip project's codebases, issue trackers, chat + rooms and mailing lists is expected to follow the `PyPA Code of Conduct`_. + + .. _PyPA recommended: https://packaging.python.org/en/latest/current/ + .. _Installation: https://pip.pypa.io/en/stable/installing.html + .. _Documentation: https://pip.pypa.io/en/stable/ + .. _Changelog: https://pip.pypa.io/en/stable/news.html + .. _GitHub Page: https://github.com/pypa/pip + .. _Issue Tracking: https://github.com/pypa/pip/issues + .. _User mailing list: http://groups.google.com/group/python-virtualenv + .. _Dev mailing list: http://groups.google.com/group/pypa-dev + .. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + +Keywords: easy_install distutils setuptools egg virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.* +Provides-Extra: testing diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt new file mode 100644 index 0000000..5a15329 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/SOURCES.txt @@ -0,0 +1,347 @@ +AUTHORS.txt +LICENSE.txt +MANIFEST.in +NEWS.rst +README.rst +pyproject.toml +setup.cfg +setup.py +docs/Makefile +docs/__init__.py +docs/conf.py +docs/configuration.rst +docs/cookbook.rst +docs/development.rst +docs/docutils.conf +docs/index.rst +docs/installing.rst +docs/logic.rst +docs/make.bat +docs/news.rst +docs/pipext.py +docs/quickstart.rst +docs/usage.rst +docs/user_guide.rst +docs/man/pip.rst +docs/man/commands/check.rst +docs/man/commands/config.rst +docs/man/commands/download.rst +docs/man/commands/freeze.rst +docs/man/commands/hash.rst +docs/man/commands/help.rst +docs/man/commands/install.rst +docs/man/commands/list.rst +docs/man/commands/search.rst +docs/man/commands/show.rst +docs/man/commands/uninstall.rst +docs/man/commands/wheel.rst +docs/reference/index.rst +docs/reference/pip.rst +docs/reference/pip_check.rst +docs/reference/pip_config.rst +docs/reference/pip_download.rst +docs/reference/pip_freeze.rst +docs/reference/pip_hash.rst +docs/reference/pip_install.rst +docs/reference/pip_list.rst +docs/reference/pip_search.rst +docs/reference/pip_show.rst +docs/reference/pip_uninstall.rst +docs/reference/pip_wheel.rst +src/pip/__init__.py +src/pip/__main__.py +src/pip.egg-info/PKG-INFO +src/pip.egg-info/SOURCES.txt +src/pip.egg-info/dependency_links.txt +src/pip.egg-info/entry_points.txt +src/pip.egg-info/not-zip-safe +src/pip.egg-info/requires.txt +src/pip.egg-info/top_level.txt +src/pip/_internal/__init__.py +src/pip/_internal/basecommand.py +src/pip/_internal/baseparser.py +src/pip/_internal/build_env.py +src/pip/_internal/cache.py +src/pip/_internal/cmdoptions.py +src/pip/_internal/compat.py +src/pip/_internal/configuration.py +src/pip/_internal/download.py +src/pip/_internal/exceptions.py +src/pip/_internal/index.py +src/pip/_internal/locations.py +src/pip/_internal/pep425tags.py +src/pip/_internal/resolve.py +src/pip/_internal/status_codes.py +src/pip/_internal/wheel.py +src/pip/_internal/commands/__init__.py +src/pip/_internal/commands/check.py +src/pip/_internal/commands/completion.py +src/pip/_internal/commands/configuration.py +src/pip/_internal/commands/download.py +src/pip/_internal/commands/freeze.py +src/pip/_internal/commands/hash.py +src/pip/_internal/commands/help.py +src/pip/_internal/commands/install.py +src/pip/_internal/commands/list.py +src/pip/_internal/commands/search.py +src/pip/_internal/commands/show.py +src/pip/_internal/commands/uninstall.py +src/pip/_internal/commands/wheel.py +src/pip/_internal/models/__init__.py +src/pip/_internal/models/index.py +src/pip/_internal/operations/__init__.py +src/pip/_internal/operations/check.py +src/pip/_internal/operations/freeze.py +src/pip/_internal/operations/prepare.py +src/pip/_internal/req/__init__.py +src/pip/_internal/req/req_file.py +src/pip/_internal/req/req_install.py +src/pip/_internal/req/req_set.py +src/pip/_internal/req/req_uninstall.py +src/pip/_internal/utils/__init__.py +src/pip/_internal/utils/appdirs.py +src/pip/_internal/utils/deprecation.py +src/pip/_internal/utils/encoding.py +src/pip/_internal/utils/filesystem.py +src/pip/_internal/utils/glibc.py +src/pip/_internal/utils/hashes.py +src/pip/_internal/utils/logging.py +src/pip/_internal/utils/misc.py +src/pip/_internal/utils/outdated.py +src/pip/_internal/utils/packaging.py +src/pip/_internal/utils/setuptools_build.py +src/pip/_internal/utils/temp_dir.py +src/pip/_internal/utils/typing.py +src/pip/_internal/utils/ui.py +src/pip/_internal/vcs/__init__.py +src/pip/_internal/vcs/bazaar.py +src/pip/_internal/vcs/git.py +src/pip/_internal/vcs/mercurial.py +src/pip/_internal/vcs/subversion.py +src/pip/_vendor/README.rst +src/pip/_vendor/__init__.py +src/pip/_vendor/appdirs.py +src/pip/_vendor/distro.py +src/pip/_vendor/ipaddress.py +src/pip/_vendor/pyparsing.py +src/pip/_vendor/retrying.py +src/pip/_vendor/six.py +src/pip/_vendor/vendor.txt +src/pip/_vendor/cachecontrol/__init__.py +src/pip/_vendor/cachecontrol/_cmd.py +src/pip/_vendor/cachecontrol/adapter.py +src/pip/_vendor/cachecontrol/cache.py +src/pip/_vendor/cachecontrol/compat.py +src/pip/_vendor/cachecontrol/controller.py +src/pip/_vendor/cachecontrol/filewrapper.py +src/pip/_vendor/cachecontrol/heuristics.py +src/pip/_vendor/cachecontrol/serialize.py +src/pip/_vendor/cachecontrol/wrapper.py +src/pip/_vendor/cachecontrol/caches/__init__.py +src/pip/_vendor/cachecontrol/caches/file_cache.py +src/pip/_vendor/cachecontrol/caches/redis_cache.py +src/pip/_vendor/certifi/__init__.py +src/pip/_vendor/certifi/__main__.py +src/pip/_vendor/certifi/cacert.pem +src/pip/_vendor/certifi/core.py +src/pip/_vendor/chardet/__init__.py +src/pip/_vendor/chardet/big5freq.py +src/pip/_vendor/chardet/big5prober.py +src/pip/_vendor/chardet/chardistribution.py +src/pip/_vendor/chardet/charsetgroupprober.py +src/pip/_vendor/chardet/charsetprober.py +src/pip/_vendor/chardet/codingstatemachine.py +src/pip/_vendor/chardet/compat.py +src/pip/_vendor/chardet/cp949prober.py +src/pip/_vendor/chardet/enums.py +src/pip/_vendor/chardet/escprober.py +src/pip/_vendor/chardet/escsm.py +src/pip/_vendor/chardet/eucjpprober.py +src/pip/_vendor/chardet/euckrfreq.py +src/pip/_vendor/chardet/euckrprober.py +src/pip/_vendor/chardet/euctwfreq.py +src/pip/_vendor/chardet/euctwprober.py +src/pip/_vendor/chardet/gb2312freq.py +src/pip/_vendor/chardet/gb2312prober.py +src/pip/_vendor/chardet/hebrewprober.py +src/pip/_vendor/chardet/jisfreq.py +src/pip/_vendor/chardet/jpcntx.py +src/pip/_vendor/chardet/langbulgarianmodel.py +src/pip/_vendor/chardet/langcyrillicmodel.py +src/pip/_vendor/chardet/langgreekmodel.py +src/pip/_vendor/chardet/langhebrewmodel.py +src/pip/_vendor/chardet/langhungarianmodel.py +src/pip/_vendor/chardet/langthaimodel.py +src/pip/_vendor/chardet/langturkishmodel.py +src/pip/_vendor/chardet/latin1prober.py +src/pip/_vendor/chardet/mbcharsetprober.py +src/pip/_vendor/chardet/mbcsgroupprober.py +src/pip/_vendor/chardet/mbcssm.py +src/pip/_vendor/chardet/sbcharsetprober.py +src/pip/_vendor/chardet/sbcsgroupprober.py +src/pip/_vendor/chardet/sjisprober.py +src/pip/_vendor/chardet/universaldetector.py +src/pip/_vendor/chardet/utf8prober.py +src/pip/_vendor/chardet/version.py +src/pip/_vendor/chardet/cli/__init__.py +src/pip/_vendor/chardet/cli/chardetect.py +src/pip/_vendor/colorama/__init__.py +src/pip/_vendor/colorama/ansi.py +src/pip/_vendor/colorama/ansitowin32.py +src/pip/_vendor/colorama/initialise.py +src/pip/_vendor/colorama/win32.py +src/pip/_vendor/colorama/winterm.py +src/pip/_vendor/distlib/__init__.py +src/pip/_vendor/distlib/compat.py +src/pip/_vendor/distlib/database.py +src/pip/_vendor/distlib/index.py +src/pip/_vendor/distlib/locators.py +src/pip/_vendor/distlib/manifest.py +src/pip/_vendor/distlib/markers.py +src/pip/_vendor/distlib/metadata.py +src/pip/_vendor/distlib/resources.py +src/pip/_vendor/distlib/scripts.py +src/pip/_vendor/distlib/t32.exe +src/pip/_vendor/distlib/t64.exe +src/pip/_vendor/distlib/util.py +src/pip/_vendor/distlib/version.py +src/pip/_vendor/distlib/w32.exe +src/pip/_vendor/distlib/w64.exe +src/pip/_vendor/distlib/wheel.py +src/pip/_vendor/distlib/_backport/__init__.py +src/pip/_vendor/distlib/_backport/misc.py +src/pip/_vendor/distlib/_backport/shutil.py +src/pip/_vendor/distlib/_backport/sysconfig.cfg +src/pip/_vendor/distlib/_backport/sysconfig.py +src/pip/_vendor/distlib/_backport/tarfile.py +src/pip/_vendor/html5lib/__init__.py +src/pip/_vendor/html5lib/_ihatexml.py +src/pip/_vendor/html5lib/_inputstream.py +src/pip/_vendor/html5lib/_tokenizer.py +src/pip/_vendor/html5lib/_utils.py +src/pip/_vendor/html5lib/constants.py +src/pip/_vendor/html5lib/html5parser.py +src/pip/_vendor/html5lib/serializer.py +src/pip/_vendor/html5lib/_trie/__init__.py +src/pip/_vendor/html5lib/_trie/_base.py +src/pip/_vendor/html5lib/_trie/datrie.py +src/pip/_vendor/html5lib/_trie/py.py +src/pip/_vendor/html5lib/filters/__init__.py +src/pip/_vendor/html5lib/filters/alphabeticalattributes.py +src/pip/_vendor/html5lib/filters/base.py +src/pip/_vendor/html5lib/filters/inject_meta_charset.py +src/pip/_vendor/html5lib/filters/lint.py +src/pip/_vendor/html5lib/filters/optionaltags.py +src/pip/_vendor/html5lib/filters/sanitizer.py +src/pip/_vendor/html5lib/filters/whitespace.py +src/pip/_vendor/html5lib/treeadapters/__init__.py +src/pip/_vendor/html5lib/treeadapters/genshi.py +src/pip/_vendor/html5lib/treeadapters/sax.py +src/pip/_vendor/html5lib/treebuilders/__init__.py +src/pip/_vendor/html5lib/treebuilders/base.py +src/pip/_vendor/html5lib/treebuilders/dom.py +src/pip/_vendor/html5lib/treebuilders/etree.py +src/pip/_vendor/html5lib/treebuilders/etree_lxml.py +src/pip/_vendor/html5lib/treewalkers/__init__.py +src/pip/_vendor/html5lib/treewalkers/base.py +src/pip/_vendor/html5lib/treewalkers/dom.py +src/pip/_vendor/html5lib/treewalkers/etree.py +src/pip/_vendor/html5lib/treewalkers/etree_lxml.py +src/pip/_vendor/html5lib/treewalkers/genshi.py +src/pip/_vendor/idna/__init__.py +src/pip/_vendor/idna/codec.py +src/pip/_vendor/idna/compat.py +src/pip/_vendor/idna/core.py +src/pip/_vendor/idna/idnadata.py +src/pip/_vendor/idna/intranges.py +src/pip/_vendor/idna/package_data.py +src/pip/_vendor/idna/uts46data.py +src/pip/_vendor/lockfile/__init__.py +src/pip/_vendor/lockfile/linklockfile.py +src/pip/_vendor/lockfile/mkdirlockfile.py +src/pip/_vendor/lockfile/pidlockfile.py +src/pip/_vendor/lockfile/sqlitelockfile.py +src/pip/_vendor/lockfile/symlinklockfile.py +src/pip/_vendor/msgpack/__init__.py +src/pip/_vendor/msgpack/_version.py +src/pip/_vendor/msgpack/exceptions.py +src/pip/_vendor/msgpack/fallback.py +src/pip/_vendor/packaging/__about__.py +src/pip/_vendor/packaging/__init__.py +src/pip/_vendor/packaging/_compat.py +src/pip/_vendor/packaging/_structures.py +src/pip/_vendor/packaging/markers.py +src/pip/_vendor/packaging/requirements.py +src/pip/_vendor/packaging/specifiers.py +src/pip/_vendor/packaging/utils.py +src/pip/_vendor/packaging/version.py +src/pip/_vendor/pkg_resources/__init__.py +src/pip/_vendor/pkg_resources/py31compat.py +src/pip/_vendor/progress/__init__.py +src/pip/_vendor/progress/bar.py +src/pip/_vendor/progress/counter.py +src/pip/_vendor/progress/helpers.py +src/pip/_vendor/progress/spinner.py +src/pip/_vendor/pytoml/__init__.py +src/pip/_vendor/pytoml/core.py +src/pip/_vendor/pytoml/parser.py +src/pip/_vendor/pytoml/writer.py +src/pip/_vendor/requests/__init__.py +src/pip/_vendor/requests/__version__.py +src/pip/_vendor/requests/_internal_utils.py +src/pip/_vendor/requests/adapters.py +src/pip/_vendor/requests/api.py +src/pip/_vendor/requests/auth.py +src/pip/_vendor/requests/certs.py +src/pip/_vendor/requests/compat.py +src/pip/_vendor/requests/cookies.py +src/pip/_vendor/requests/exceptions.py +src/pip/_vendor/requests/help.py +src/pip/_vendor/requests/hooks.py +src/pip/_vendor/requests/models.py +src/pip/_vendor/requests/packages.py +src/pip/_vendor/requests/sessions.py +src/pip/_vendor/requests/status_codes.py +src/pip/_vendor/requests/structures.py +src/pip/_vendor/requests/utils.py +src/pip/_vendor/urllib3/__init__.py +src/pip/_vendor/urllib3/_collections.py +src/pip/_vendor/urllib3/connection.py +src/pip/_vendor/urllib3/connectionpool.py +src/pip/_vendor/urllib3/exceptions.py +src/pip/_vendor/urllib3/fields.py +src/pip/_vendor/urllib3/filepost.py +src/pip/_vendor/urllib3/poolmanager.py +src/pip/_vendor/urllib3/request.py +src/pip/_vendor/urllib3/response.py +src/pip/_vendor/urllib3/contrib/__init__.py +src/pip/_vendor/urllib3/contrib/appengine.py +src/pip/_vendor/urllib3/contrib/ntlmpool.py +src/pip/_vendor/urllib3/contrib/pyopenssl.py +src/pip/_vendor/urllib3/contrib/securetransport.py +src/pip/_vendor/urllib3/contrib/socks.py +src/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +src/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +src/pip/_vendor/urllib3/packages/__init__.py +src/pip/_vendor/urllib3/packages/ordered_dict.py +src/pip/_vendor/urllib3/packages/six.py +src/pip/_vendor/urllib3/packages/backports/__init__.py +src/pip/_vendor/urllib3/packages/backports/makefile.py +src/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py +src/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py +src/pip/_vendor/urllib3/util/__init__.py +src/pip/_vendor/urllib3/util/connection.py +src/pip/_vendor/urllib3/util/request.py +src/pip/_vendor/urllib3/util/response.py +src/pip/_vendor/urllib3/util/retry.py +src/pip/_vendor/urllib3/util/selectors.py +src/pip/_vendor/urllib3/util/ssl_.py +src/pip/_vendor/urllib3/util/timeout.py +src/pip/_vendor/urllib3/util/url.py +src/pip/_vendor/urllib3/util/wait.py +src/pip/_vendor/webencodings/__init__.py +src/pip/_vendor/webencodings/labels.py +src/pip/_vendor/webencodings/mklabels.py +src/pip/_vendor/webencodings/tests.py +src/pip/_vendor/webencodings/x_user_defined.py \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/dependency_links.txt b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/entry_points.txt b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/entry_points.txt new file mode 100644 index 0000000..f5809cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip._internal:main +pip3 = pip._internal:main +pip3.7 = pip._internal:main + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/not-zip-safe b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/not-zip-safe @@ -0,0 +1 @@ + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/requires.txt b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/requires.txt new file mode 100644 index 0000000..fdea1b5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/requires.txt @@ -0,0 +1,8 @@ + +[testing] +pytest +mock +pretend +scripttest>=1.3 +virtualenv>=1.10 +freezegun diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/top_level.txt b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/top_level.txt new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/EGG-INFO/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__init__.py new file mode 100644 index 0000000..ab64964 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__init__.py @@ -0,0 +1 @@ +__version__ = "10.0.1" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__main__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__main__.py new file mode 100644 index 0000000..4609582 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__main__.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import + +import os +import sys + +# If we are running from a wheel, add the wheel to sys.path +# This allows the usage python pip-*.whl/pip install pip-*.whl +if __package__ == '': + # __file__ is pip-*.whl/pip/__main__.py + # first dirname call strips of '/__main__.py', second strips off '/pip' + # Resulting path is the name of the wheel itself + # Add that to sys.path so we can import pip + path = os.path.dirname(os.path.dirname(__file__)) + sys.path.insert(0, path) + +from pip._internal import main as _main # noqa + +if __name__ == '__main__': + sys.exit(_main()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..6c2a41e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__pycache__/__main__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000..84a714a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/__pycache__/__main__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__init__.py new file mode 100644 index 0000000..865d9ec --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__init__.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python +from __future__ import absolute_import + +import locale +import logging +import os +import optparse +import warnings + +import sys + +# 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, +# but if invoked (i.e. imported), it will issue a warning to stderr if socks +# isn't available. requests unconditionally imports urllib3's socks contrib +# module, triggering this warning. The warning breaks DEP-8 tests (because of +# the stderr output) and is just plain annoying in normal usage. I don't want +# to add socks as yet another dependency for pip, nor do I want to allow-stder +# in the DEP-8 tests, so just suppress the warning. pdb tells me this has to +# be done before the import of pip.vcs. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.filterwarnings("ignore", category=DependencyWarning) # noqa + +# We want to inject the use of SecureTransport as early as possible so that any +# references or sessions or what have you are ensured to have it, however we +# only want to do this in the case that we're running on macOS and the linked +# OpenSSL is too old to handle TLSv1.2 +try: + import ssl +except ImportError: + pass +else: + # Checks for OpenSSL 1.0.1 on MacOS + if sys.platform == "darwin" and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f: + try: + from pip._vendor.urllib3.contrib import securetransport + except (ImportError, OSError): + pass + else: + securetransport.inject_into_urllib3() + +from pip import __version__ +from pip._internal import cmdoptions +from pip._internal.exceptions import CommandError, PipError +from pip._internal.utils.misc import get_installed_distributions, get_prog +from pip._internal.utils import deprecation +from pip._internal.vcs import git, mercurial, subversion, bazaar # noqa +from pip._internal.baseparser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.commands import get_summaries, get_similar_commands +from pip._internal.commands import commands_dict +from pip._vendor.urllib3.exceptions import InsecureRequestWarning + +logger = logging.getLogger(__name__) + +# Hide the InsecureRequestWarning from urllib3 +warnings.filterwarnings("ignore", category=InsecureRequestWarning) + + +def autocomplete(): + """Command and option completion for the main option parser (and options) + and its subcommands (and options). + + Enable by sourcing one of the completion shell scripts (bash, zsh or fish). + """ + # Don't complete if user hasn't sourced bash_completion file. + if 'PIP_AUTO_COMPLETE' not in os.environ: + return + cwords = os.environ['COMP_WORDS'].split()[1:] + cword = int(os.environ['COMP_CWORD']) + try: + current = cwords[cword - 1] + except IndexError: + current = '' + + subcommands = [cmd for cmd, summary in get_summaries()] + options = [] + # subcommand + try: + subcommand_name = [w for w in cwords if w in subcommands][0] + except IndexError: + subcommand_name = None + + parser = create_main_parser() + # subcommand options + if subcommand_name: + # special case: 'help' subcommand has no options + if subcommand_name == 'help': + sys.exit(1) + # special case: list locally installed dists for show and uninstall + should_list_installed = ( + subcommand_name in ['show', 'uninstall'] and + not current.startswith('-') + ) + if should_list_installed: + installed = [] + lc = current.lower() + for dist in get_installed_distributions(local_only=True): + if dist.key.startswith(lc) and dist.key not in cwords[1:]: + installed.append(dist.key) + # if there are no dists installed, fall back to option completion + if installed: + for dist in installed: + print(dist) + sys.exit(1) + + subcommand = commands_dict[subcommand_name]() + + for opt in subcommand.parser.option_list_all: + if opt.help != optparse.SUPPRESS_HELP: + for opt_str in opt._long_opts + opt._short_opts: + options.append((opt_str, opt.nargs)) + + # filter out previously specified options from available options + prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] + options = [(x, v) for (x, v) in options if x not in prev_opts] + # filter options by current input + options = [(k, v) for k, v in options if k.startswith(current)] + for option in options: + opt_label = option[0] + # append '=' to options which require args + if option[1] and option[0][:2] == "--": + opt_label += '=' + print(opt_label) + else: + # show main parser options only when necessary + if current.startswith('-') or current.startswith('--'): + opts = [i.option_list for i in parser.option_groups] + opts.append(parser.option_list) + opts = (o for it in opts for o in it) + + for opt in opts: + if opt.help != optparse.SUPPRESS_HELP: + subcommands += opt._long_opts + opt._short_opts + + print(' '.join([x for x in subcommands if x.startswith(current)])) + sys.exit(1) + + +def create_main_parser(): + parser_kw = { + 'usage': '\n%prog [options]', + 'add_help_option': False, + 'formatter': UpdatingDefaultsHelpFormatter(), + 'name': 'global', + 'prog': get_prog(), + } + + parser = ConfigOptionParser(**parser_kw) + parser.disable_interspersed_args() + + pip_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + parser.version = 'pip %s from %s (python %s)' % ( + __version__, pip_pkg_dir, sys.version[:3], + ) + + # add the general options + gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) + parser.add_option_group(gen_opts) + + parser.main = True # so the help formatter knows + + # create command listing for description + command_summaries = get_summaries() + description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] + parser.description = '\n'.join(description) + + return parser + + +def parseopts(args): + parser = create_main_parser() + + # Note: parser calls disable_interspersed_args(), so the result of this + # call is to split the initial args into the general options before the + # subcommand and everything else. + # For example: + # args: ['--timeout=5', 'install', '--user', 'INITools'] + # general_options: ['--timeout==5'] + # args_else: ['install', '--user', 'INITools'] + general_options, args_else = parser.parse_args(args) + + # --version + if general_options.version: + sys.stdout.write(parser.version) + sys.stdout.write(os.linesep) + sys.exit() + + # pip || pip help -> print_help() + if not args_else or (args_else[0] == 'help' and len(args_else) == 1): + parser.print_help() + sys.exit() + + # the subcommand name + cmd_name = args_else[0] + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + # all the args without the subcommand + cmd_args = args[:] + cmd_args.remove(cmd_name) + + return cmd_name, cmd_args + + +def check_isolated(args): + isolated = False + + if "--isolated" in args: + isolated = True + + return isolated + + +def main(args=None): + if args is None: + args = sys.argv[1:] + + # Configure our deprecation warnings to be sent through loggers + deprecation.install_warning_logger() + + autocomplete() + + try: + cmd_name, cmd_args = parseopts(args) + except PipError as exc: + sys.stderr.write("ERROR: %s" % exc) + sys.stderr.write(os.linesep) + sys.exit(1) + + # Needed for locale.getpreferredencoding(False) to work + # in pip._internal.utils.encoding.auto_decode + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error as e: + # setlocale can apparently crash if locale are uninitialized + logger.debug("Ignoring error %s when setting locale", e) + command = commands_dict[cmd_name](isolated=check_isolated(cmd_args)) + return command.main(cmd_args) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..e07730c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/basecommand.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/basecommand.cpython-37.pyc new file mode 100644 index 0000000..3a09ec7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/basecommand.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/baseparser.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/baseparser.cpython-37.pyc new file mode 100644 index 0000000..d2937f2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/baseparser.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/build_env.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/build_env.cpython-37.pyc new file mode 100644 index 0000000..ae6dc19 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/build_env.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/cache.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/cache.cpython-37.pyc new file mode 100644 index 0000000..a14a4e3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/cache.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/cmdoptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/cmdoptions.cpython-37.pyc new file mode 100644 index 0000000..98b5e34 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/cmdoptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000..6aca1ae Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/configuration.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/configuration.cpython-37.pyc new file mode 100644 index 0000000..f47b7fa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/configuration.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/download.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/download.cpython-37.pyc new file mode 100644 index 0000000..53dad70 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/download.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000..658d0ed Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/index.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/index.cpython-37.pyc new file mode 100644 index 0000000..a13386b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/index.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/locations.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/locations.cpython-37.pyc new file mode 100644 index 0000000..bb8019b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/locations.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/pep425tags.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/pep425tags.cpython-37.pyc new file mode 100644 index 0000000..0789e61 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/pep425tags.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/resolve.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/resolve.cpython-37.pyc new file mode 100644 index 0000000..244b577 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/resolve.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/status_codes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/status_codes.cpython-37.pyc new file mode 100644 index 0000000..ace373b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/status_codes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/wheel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/wheel.cpython-37.pyc new file mode 100644 index 0000000..008d317 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/__pycache__/wheel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/basecommand.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/basecommand.py new file mode 100644 index 0000000..2503f36 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/basecommand.py @@ -0,0 +1,373 @@ +"""Base Command class, and related routines""" +from __future__ import absolute_import + +import logging +import logging.config +import optparse +import os +import sys +import warnings + +from pip._internal import cmdoptions +from pip._internal.baseparser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.compat import WINDOWS +from pip._internal.download import PipSession +from pip._internal.exceptions import ( + BadCommand, CommandError, InstallationError, PreviousBuildDirError, + UninstallationError, +) +from pip._internal.index import PackageFinder +from pip._internal.locations import running_under_virtualenv +from pip._internal.req.req_file import parse_requirements +from pip._internal.req.req_install import InstallRequirement +from pip._internal.status_codes import ( + ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, + VIRTUALENV_NOT_FOUND, +) +from pip._internal.utils import deprecation +from pip._internal.utils.logging import IndentingFormatter +from pip._internal.utils.misc import get_prog, normalize_path +from pip._internal.utils.outdated import pip_version_check +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + +__all__ = ['Command'] + +logger = logging.getLogger(__name__) + + +class Command(object): + name = None # type: Optional[str] + usage = None # type: Optional[str] + hidden = False # type: bool + ignore_require_venv = False # type: bool + log_streams = ("ext://sys.stdout", "ext://sys.stderr") + + def __init__(self, isolated=False): + parser_kw = { + 'usage': self.usage, + 'prog': '%s %s' % (get_prog(), self.name), + 'formatter': UpdatingDefaultsHelpFormatter(), + 'add_help_option': False, + 'name': self.name, + 'description': self.__doc__, + 'isolated': isolated, + } + + self.parser = ConfigOptionParser(**parser_kw) + + # Commands should add options to this option group + optgroup_name = '%s Options' % self.name.capitalize() + self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) + + # Add the general options + gen_opts = cmdoptions.make_option_group( + cmdoptions.general_group, + self.parser, + ) + self.parser.add_option_group(gen_opts) + + def _build_session(self, options, retries=None, timeout=None): + session = PipSession( + cache=( + normalize_path(os.path.join(options.cache_dir, "http")) + if options.cache_dir else None + ), + retries=retries if retries is not None else options.retries, + insecure_hosts=options.trusted_hosts, + ) + + # Handle custom ca-bundles from the user + if options.cert: + session.verify = options.cert + + # Handle SSL client certificate + if options.client_cert: + session.cert = options.client_cert + + # Handle timeouts + if options.timeout or timeout: + session.timeout = ( + timeout if timeout is not None else options.timeout + ) + + # Handle configured proxies + if options.proxy: + session.proxies = { + "http": options.proxy, + "https": options.proxy, + } + + # Determine if we can prompt the user for authentication or not + session.auth.prompting = not options.no_input + + return session + + def parse_args(self, args): + # factored out for testability + return self.parser.parse_args(args) + + def main(self, args): + options, args = self.parse_args(args) + + # Set verbosity so that it can be used elsewhere. + self.verbosity = options.verbose - options.quiet + + if self.verbosity >= 1: + level = "DEBUG" + elif self.verbosity == -1: + level = "WARNING" + elif self.verbosity == -2: + level = "ERROR" + elif self.verbosity <= -3: + level = "CRITICAL" + else: + level = "INFO" + + # The root logger should match the "console" level *unless* we + # specified "--log" to send debug logs to a file. + root_level = level + if options.log: + root_level = "DEBUG" + + logger_class = "pip._internal.utils.logging.ColorizedStreamHandler" + handler_class = "pip._internal.utils.logging.BetterRotatingFileHandler" + + logging.config.dictConfig({ + "version": 1, + "disable_existing_loggers": False, + "filters": { + "exclude_warnings": { + "()": "pip._internal.utils.logging.MaxLevelFilter", + "level": logging.WARNING, + }, + }, + "formatters": { + "indent": { + "()": IndentingFormatter, + "format": "%(message)s", + }, + }, + "handlers": { + "console": { + "level": level, + "class": logger_class, + "no_color": options.no_color, + "stream": self.log_streams[0], + "filters": ["exclude_warnings"], + "formatter": "indent", + }, + "console_errors": { + "level": "WARNING", + "class": logger_class, + "no_color": options.no_color, + "stream": self.log_streams[1], + "formatter": "indent", + }, + "user_log": { + "level": "DEBUG", + "class": handler_class, + "filename": options.log or "/dev/null", + "delay": True, + "formatter": "indent", + }, + }, + "root": { + "level": root_level, + "handlers": list(filter(None, [ + "console", + "console_errors", + "user_log" if options.log else None, + ])), + }, + # Disable any logging besides WARNING unless we have DEBUG level + # logging enabled. These use both pip._vendor and the bare names + # for the case where someone unbundles our libraries. + "loggers": { + name: { + "level": ( + "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" + ) + } for name in [ + "pip._vendor", "distlib", "requests", "urllib3" + ] + }, + }) + + if sys.version_info[:2] == (3, 3): + warnings.warn( + "Python 3.3 supported has been deprecated and support for it " + "will be dropped in the future. Please upgrade your Python.", + deprecation.RemovedInPip11Warning, + ) + + # TODO: try to get these passing down from the command? + # without resorting to os.environ to hold these. + + if options.no_input: + os.environ['PIP_NO_INPUT'] = '1' + + if options.exists_action: + os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) + + if options.require_venv and not self.ignore_require_venv: + # If a venv is required check if it can really be found + if not running_under_virtualenv(): + logger.critical( + 'Could not find an activated virtualenv (required).' + ) + sys.exit(VIRTUALENV_NOT_FOUND) + + original_root_handlers = set(logging.root.handlers) + + try: + status = self.run(options, args) + # FIXME: all commands should return an exit status + # and when it is done, isinstance is not needed anymore + if isinstance(status, int): + return status + except PreviousBuildDirError as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return PREVIOUS_BUILD_DIR_ERROR + except (InstallationError, UninstallationError, BadCommand) as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except CommandError as exc: + logger.critical('ERROR: %s', exc) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except KeyboardInterrupt: + logger.critical('Operation cancelled by user') + logger.debug('Exception information:', exc_info=True) + + return ERROR + except: + logger.critical('Exception:', exc_info=True) + + return UNKNOWN_ERROR + finally: + # Check if we're using the latest version of pip available + if (not options.disable_pip_version_check and not + getattr(options, "no_index", False)): + with self._build_session( + options, + retries=0, + timeout=min(5, options.timeout)) as session: + pip_version_check(session, options) + # Avoid leaking loggers + for handler in set(logging.root.handlers) - original_root_handlers: + # this method benefit from the Logger class internal lock + logging.root.removeHandler(handler) + + return SUCCESS + + +class RequirementCommand(Command): + + @staticmethod + def populate_requirement_set(requirement_set, args, options, finder, + session, name, wheel_cache): + """ + Marshal cmd line args into a requirement set. + """ + # NOTE: As a side-effect, options.require_hashes and + # requirement_set.require_hashes may be updated + + for filename in options.constraints: + for req_to_add in parse_requirements( + filename, + constraint=True, finder=finder, options=options, + session=session, wheel_cache=wheel_cache): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in args: + req_to_add = InstallRequirement.from_line( + req, None, isolated=options.isolated_mode, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in options.editables: + req_to_add = InstallRequirement.from_editable( + req, + isolated=options.isolated_mode, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for filename in options.requirements: + for req_to_add in parse_requirements( + filename, + finder=finder, options=options, session=session, + wheel_cache=wheel_cache): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + # If --require-hashes was a line in a requirements file, tell + # RequirementSet about it: + requirement_set.require_hashes = options.require_hashes + + if not (args or options.editables or options.requirements): + opts = {'name': name} + if options.find_links: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(maybe you meant "pip %(name)s %(links)s"?)' % + dict(opts, links=' '.join(options.find_links))) + else: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(see "pip help %(name)s")' % opts) + + # On Windows, any operation modifying pip should be run as: + # python -m pip ... + # See https://github.com/pypa/pip/issues/1299 for more discussion + should_show_use_python_msg = ( + WINDOWS and + requirement_set.has_requirement("pip") and + os.path.basename(sys.argv[0]).startswith("pip") + ) + if should_show_use_python_msg: + new_command = [ + sys.executable, "-m", "pip" + ] + sys.argv[1:] + raise CommandError( + 'To modify pip, please run the following command:\n{}' + .format(" ".join(new_command)) + ) + + def _build_package_finder(self, options, session, + platform=None, python_versions=None, + abi=None, implementation=None): + """ + Create a package finder appropriate to this requirement command. + """ + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + return PackageFinder( + find_links=options.find_links, + format_control=options.format_control, + index_urls=index_urls, + trusted_hosts=options.trusted_hosts, + allow_all_prereleases=options.pre, + process_dependency_links=options.process_dependency_links, + session=session, + platform=platform, + versions=python_versions, + abi=abi, + implementation=implementation, + ) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/baseparser.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/baseparser.py new file mode 100644 index 0000000..9a8d129 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/baseparser.py @@ -0,0 +1,240 @@ +"""Base option parser setup""" +from __future__ import absolute_import + +import logging +import optparse +import sys +import textwrap +from distutils.util import strtobool + +from pip._vendor.six import string_types + +from pip._internal.compat import get_terminal_size +from pip._internal.configuration import Configuration, ConfigurationError + +logger = logging.getLogger(__name__) + + +class PrettyHelpFormatter(optparse.IndentedHelpFormatter): + """A prettier/less verbose help formatter for optparse.""" + + def __init__(self, *args, **kwargs): + # help position must be aligned with __init__.parseopts.description + kwargs['max_help_position'] = 30 + kwargs['indent_increment'] = 1 + kwargs['width'] = get_terminal_size()[0] - 2 + optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) + + def format_option_strings(self, option): + return self._format_option_strings(option, ' <%s>', ', ') + + def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '): + """ + Return a comma-separated list of option strings and metavars. + + :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') + :param mvarfmt: metavar format string - evaluated as mvarfmt % metavar + :param optsep: separator + """ + opts = [] + + if option._short_opts: + opts.append(option._short_opts[0]) + if option._long_opts: + opts.append(option._long_opts[0]) + if len(opts) > 1: + opts.insert(1, optsep) + + if option.takes_value(): + metavar = option.metavar or option.dest.lower() + opts.append(mvarfmt % metavar.lower()) + + return ''.join(opts) + + def format_heading(self, heading): + if heading == 'Options': + return '' + return heading + ':\n' + + def format_usage(self, usage): + """ + Ensure there is only one newline between usage and the first heading + if there is no description. + """ + msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ") + return msg + + def format_description(self, description): + # leave full control over description to us + if description: + if hasattr(self.parser, 'main'): + label = 'Commands' + else: + label = 'Description' + # some doc strings have initial newlines, some don't + description = description.lstrip('\n') + # some doc strings have final newlines and spaces, some don't + description = description.rstrip() + # dedent, then reindent + description = self.indent_lines(textwrap.dedent(description), " ") + description = '%s:\n%s\n' % (label, description) + return description + else: + return '' + + def format_epilog(self, epilog): + # leave full control over epilog to us + if epilog: + return epilog + else: + return '' + + def indent_lines(self, text, indent): + new_lines = [indent + line for line in text.split('\n')] + return "\n".join(new_lines) + + +class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): + """Custom help formatter for use in ConfigOptionParser. + + This is updates the defaults before expanding them, allowing + them to show up correctly in the help listing. + """ + + def expand_default(self, option): + if self.parser is not None: + self.parser._update_defaults(self.parser.defaults) + return optparse.IndentedHelpFormatter.expand_default(self, option) + + +class CustomOptionParser(optparse.OptionParser): + + def insert_option_group(self, idx, *args, **kwargs): + """Insert an OptionGroup at a given position.""" + group = self.add_option_group(*args, **kwargs) + + self.option_groups.pop() + self.option_groups.insert(idx, group) + + return group + + @property + def option_list_all(self): + """Get a list of all options, including those in option groups.""" + res = self.option_list[:] + for i in self.option_groups: + res.extend(i.option_list) + + return res + + +class ConfigOptionParser(CustomOptionParser): + """Custom option parser which updates its defaults by checking the + configuration files and environmental variables""" + + def __init__(self, *args, **kwargs): + self.name = kwargs.pop('name') + + isolated = kwargs.pop("isolated", False) + self.config = Configuration(isolated) + + assert self.name + optparse.OptionParser.__init__(self, *args, **kwargs) + + def check_default(self, option, key, val): + try: + return option.check_value(key, val) + except optparse.OptionValueError as exc: + print("An error occurred during configuration: %s" % exc) + sys.exit(3) + + def _get_ordered_configuration_items(self): + # Configuration gives keys in an unordered manner. Order them. + override_order = ["global", self.name, ":env:"] + + # Pool the options into different groups + section_items = {name: [] for name in override_order} + for section_key, val in self.config.items(): + # ignore empty values + if not val: + logger.debug( + "Ignoring configuration key '%s' as it's value is empty.", + section_key + ) + continue + + section, key = section_key.split(".", 1) + if section in override_order: + section_items[section].append((key, val)) + + # Yield each group in their override order + for section in override_order: + for key, val in section_items[section]: + yield key, val + + def _update_defaults(self, defaults): + """Updates the given defaults with values from the config files and + the environ. Does a little special handling for certain types of + options (lists).""" + + # Accumulate complex default state. + self.values = optparse.Values(self.defaults) + late_eval = set() + # Then set the options with those values + for key, val in self._get_ordered_configuration_items(): + # '--' because configuration supports only long names + option = self.get_option('--' + key) + + # Ignore options not present in this parser. E.g. non-globals put + # in [global] by users that want them to apply to all applicable + # commands. + if option is None: + continue + + if option.action in ('store_true', 'store_false', 'count'): + val = strtobool(val) + elif option.action == 'append': + val = val.split() + val = [self.check_default(option, key, v) for v in val] + elif option.action == 'callback': + late_eval.add(option.dest) + opt_str = option.get_opt_string() + val = option.convert_value(opt_str, val) + # From take_action + args = option.callback_args or () + kwargs = option.callback_kwargs or {} + option.callback(option, opt_str, val, self, *args, **kwargs) + else: + val = self.check_default(option, key, val) + + defaults[option.dest] = val + + for key in late_eval: + defaults[key] = getattr(self.values, key) + self.values = None + return defaults + + def get_default_values(self): + """Overriding to make updating the defaults after instantiation of + the option parser possible, _update_defaults() does the dirty work.""" + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return optparse.Values(self.defaults) + + # Load the configuration, or error out in case of an error + try: + self.config.load() + except ConfigurationError as err: + self.exit(2, err.args[0]) + + defaults = self._update_defaults(self.defaults.copy()) # ours + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, string_types): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + return optparse.Values(defaults) + + def error(self, msg): + self.print_usage(sys.stderr) + self.exit(2, "%s\n" % msg) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/build_env.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/build_env.py new file mode 100644 index 0000000..791d734 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/build_env.py @@ -0,0 +1,92 @@ +"""Build Environment used for isolation during sdist building +""" + +import os +from distutils.sysconfig import get_python_lib +from sysconfig import get_paths + +from pip._internal.utils.temp_dir import TempDirectory + + +class BuildEnvironment(object): + """Creates and manages an isolated environment to install build deps + """ + + def __init__(self, no_clean): + self._temp_dir = TempDirectory(kind="build-env") + self._no_clean = no_clean + + @property + def path(self): + return self._temp_dir.path + + def __enter__(self): + self._temp_dir.create() + + self.save_path = os.environ.get('PATH', None) + self.save_pythonpath = os.environ.get('PYTHONPATH', None) + self.save_nousersite = os.environ.get('PYTHONNOUSERSITE', None) + + install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' + install_dirs = get_paths(install_scheme, vars={ + 'base': self.path, + 'platbase': self.path, + }) + + scripts = install_dirs['scripts'] + if self.save_path: + os.environ['PATH'] = scripts + os.pathsep + self.save_path + else: + os.environ['PATH'] = scripts + os.pathsep + os.defpath + + # Note: prefer distutils' sysconfig to get the + # library paths so PyPy is correctly supported. + purelib = get_python_lib(plat_specific=0, prefix=self.path) + platlib = get_python_lib(plat_specific=1, prefix=self.path) + if purelib == platlib: + lib_dirs = purelib + else: + lib_dirs = purelib + os.pathsep + platlib + if self.save_pythonpath: + os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ + self.save_pythonpath + else: + os.environ['PYTHONPATH'] = lib_dirs + + os.environ['PYTHONNOUSERSITE'] = '1' + + return self.path + + def __exit__(self, exc_type, exc_val, exc_tb): + if not self._no_clean: + self._temp_dir.cleanup() + + def restore_var(varname, old_value): + if old_value is None: + os.environ.pop(varname, None) + else: + os.environ[varname] = old_value + + restore_var('PATH', self.save_path) + restore_var('PYTHONPATH', self.save_pythonpath) + restore_var('PYTHONNOUSERSITE', self.save_nousersite) + + def cleanup(self): + self._temp_dir.cleanup() + + +class NoOpBuildEnvironment(BuildEnvironment): + """A no-op drop-in replacement for BuildEnvironment + """ + + def __init__(self, no_clean): + pass + + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + def cleanup(self): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cache.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cache.py new file mode 100644 index 0000000..1aa17aa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cache.py @@ -0,0 +1,202 @@ +"""Cache Management +""" + +import errno +import hashlib +import logging +import os + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal import index +from pip._internal.compat import expanduser +from pip._internal.download import path_to_url +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import InvalidWheelFilename, Wheel + +logger = logging.getLogger(__name__) + + +class Cache(object): + """An abstract class - provides cache directories for data from links + + + :param cache_dir: The root of the cache. + :param format_control: A pip.index.FormatControl object to limit + binaries being read from the cache. + :param allowed_formats: which formats of files the cache should store. + ('binary' and 'source' are the only allowed values) + """ + + def __init__(self, cache_dir, format_control, allowed_formats): + super(Cache, self).__init__() + self.cache_dir = expanduser(cache_dir) if cache_dir else None + self.format_control = format_control + self.allowed_formats = allowed_formats + + _valid_formats = {"source", "binary"} + assert self.allowed_formats.union(_valid_formats) == _valid_formats + + def _get_cache_path_parts(self, link): + """Get parts of part that must be os.path.joined with cache_dir + """ + + # We want to generate an url to use as our cache key, we don't want to + # just re-use the URL because it might have other items in the fragment + # and we don't care about those. + key_parts = [link.url_without_fragment] + if link.hash_name is not None and link.hash is not None: + key_parts.append("=".join([link.hash_name, link.hash])) + key_url = "#".join(key_parts) + + # Encode our key url with sha224, we'll use this because it has similar + # security properties to sha256, but with a shorter total output (and + # thus less secure). However the differences don't make a lot of + # difference for our use case here. + hashed = hashlib.sha224(key_url.encode()).hexdigest() + + # We want to nest the directories some to prevent having a ton of top + # level directories where we might run out of sub directories on some + # FS. + parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] + + return parts + + def _get_candidates(self, link, package_name): + can_not_cache = ( + not self.cache_dir or + not package_name or + not link + ) + if can_not_cache: + return [] + + canonical_name = canonicalize_name(package_name) + formats = index.fmt_ctl_formats( + self.format_control, canonical_name + ) + if not self.allowed_formats.intersection(formats): + return [] + + root = self.get_path_for_link(link) + try: + return os.listdir(root) + except OSError as err: + if err.errno in {errno.ENOENT, errno.ENOTDIR}: + return [] + raise + + def get_path_for_link(self, link): + """Return a directory to store cached items in for link. + """ + raise NotImplementedError() + + def get(self, link, package_name): + """Returns a link to a cached item if it exists, otherwise returns the + passed link. + """ + raise NotImplementedError() + + def _link_for_candidate(self, link, candidate): + root = self.get_path_for_link(link) + path = os.path.join(root, candidate) + + return index.Link(path_to_url(path)) + + def cleanup(self): + pass + + +class SimpleWheelCache(Cache): + """A cache of wheels for future installs. + """ + + def __init__(self, cache_dir, format_control): + super(SimpleWheelCache, self).__init__( + cache_dir, format_control, {"binary"} + ) + + def get_path_for_link(self, link): + """Return a directory to store cached wheels for link + + Because there are M wheels for any one sdist, we provide a directory + to cache them in, and then consult that directory when looking up + cache hits. + + We only insert things into the cache if they have plausible version + numbers, so that we don't contaminate the cache with things that were + not unique. E.g. ./package might have dozens of installs done for it + and build a version of 0.0...and if we built and cached a wheel, we'd + end up using the same wheel even if the source has been edited. + + :param link: The link of the sdist for which this will cache wheels. + """ + parts = self._get_cache_path_parts(link) + + # Store wheels within the root cache_dir + return os.path.join(self.cache_dir, "wheels", *parts) + + def get(self, link, package_name): + candidates = [] + + for wheel_name in self._get_candidates(link, package_name): + try: + wheel = Wheel(wheel_name) + except InvalidWheelFilename: + continue + if not wheel.supported(): + # Built for a different python/arch/etc + continue + candidates.append((wheel.support_index_min(), wheel_name)) + + if not candidates: + return link + + return self._link_for_candidate(link, min(candidates)[1]) + + +class EphemWheelCache(SimpleWheelCache): + """A SimpleWheelCache that creates it's own temporary cache directory + """ + + def __init__(self, format_control): + self._temp_dir = TempDirectory(kind="ephem-wheel-cache") + self._temp_dir.create() + + super(EphemWheelCache, self).__init__( + self._temp_dir.path, format_control + ) + + def cleanup(self): + self._temp_dir.cleanup() + + +class WheelCache(Cache): + """Wraps EphemWheelCache and SimpleWheelCache into a single Cache + + This Cache allows for gracefully degradation, using the ephem wheel cache + when a certain link is not found in the simple wheel cache first. + """ + + def __init__(self, cache_dir, format_control): + super(WheelCache, self).__init__( + cache_dir, format_control, {'binary'} + ) + self._wheel_cache = SimpleWheelCache(cache_dir, format_control) + self._ephem_cache = EphemWheelCache(format_control) + + def get_path_for_link(self, link): + return self._wheel_cache.get_path_for_link(link) + + def get_ephem_path_for_link(self, link): + return self._ephem_cache.get_path_for_link(link) + + def get(self, link, package_name): + retval = self._wheel_cache.get(link, package_name) + if retval is link: + retval = self._ephem_cache.get(link, package_name) + return retval + + def cleanup(self): + self._wheel_cache.cleanup() + self._ephem_cache.cleanup() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cmdoptions.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cmdoptions.py new file mode 100644 index 0000000..6319995 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/cmdoptions.py @@ -0,0 +1,609 @@ +""" +shared options and groups + +The principle here is to define options once, but *not* instantiate them +globally. One reason being that options with action='append' can carry state +between parses. pip parses general options twice internally, and shouldn't +pass on state. To be consistent, all options will follow this design. + +""" +from __future__ import absolute_import + +import warnings +from functools import partial +from optparse import SUPPRESS_HELP, Option, OptionGroup + +from pip._internal.index import ( + FormatControl, fmt_ctl_handle_mutual_exclude, fmt_ctl_no_binary, +) +from pip._internal.locations import USER_CACHE_DIR, src_prefix +from pip._internal.models import PyPI +from pip._internal.utils.hashes import STRONG_HASHES +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import BAR_TYPES + +if MYPY_CHECK_RUNNING: + from typing import Any + + +def make_option_group(group, parser): + """ + Return an OptionGroup object + group -- assumed to be dict with 'name' and 'options' keys + parser -- an optparse Parser + """ + option_group = OptionGroup(parser, group['name']) + for option in group['options']: + option_group.add_option(option()) + return option_group + + +def check_install_build_global(options, check_options=None): + """Disable wheels if per-setup.py call options are set. + + :param options: The OptionParser options to update. + :param check_options: The options to check, if not supplied defaults to + options. + """ + if check_options is None: + check_options = options + + def getname(n): + return getattr(check_options, n, None) + names = ["build_options", "global_options", "install_options"] + if any(map(getname, names)): + control = options.format_control + fmt_ctl_no_binary(control) + warnings.warn( + 'Disabling all use of wheels due to the use of --build-options ' + '/ --global-options / --install-options.', stacklevel=2, + ) + + +########### +# options # +########### + +help_ = partial( + Option, + '-h', '--help', + dest='help', + action='help', + help='Show help.', +) # type: Any + +isolated_mode = partial( + Option, + "--isolated", + dest="isolated_mode", + action="store_true", + default=False, + help=( + "Run pip in an isolated mode, ignoring environment variables and user " + "configuration." + ), +) + +require_virtualenv = partial( + Option, + # Run only if inside a virtualenv, bail if not. + '--require-virtualenv', '--require-venv', + dest='require_venv', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +verbose = partial( + Option, + '-v', '--verbose', + dest='verbose', + action='count', + default=0, + help='Give more output. Option is additive, and can be used up to 3 times.' +) + +no_color = partial( + Option, + '--no-color', + dest='no_color', + action='store_true', + default=False, + help="Suppress colored output", +) + +version = partial( + Option, + '-V', '--version', + dest='version', + action='store_true', + help='Show version and exit.', +) # type: Any + +quiet = partial( + Option, + '-q', '--quiet', + dest='quiet', + action='count', + default=0, + help=( + 'Give less output. Option is additive, and can be used up to 3' + ' times (corresponding to WARNING, ERROR, and CRITICAL logging' + ' levels).' + ), +) # type: Any + +progress_bar = partial( + Option, + '--progress-bar', + dest='progress_bar', + type='choice', + choices=list(BAR_TYPES.keys()), + default='on', + help=( + 'Specify type of progress to be displayed [' + + '|'.join(BAR_TYPES.keys()) + '] (default: %default)' + ), +) # type: Any + +log = partial( + Option, + "--log", "--log-file", "--local-log", + dest="log", + metavar="path", + help="Path to a verbose appending log." +) # type: Any + +no_input = partial( + Option, + # Don't ask for input + '--no-input', + dest='no_input', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +proxy = partial( + Option, + '--proxy', + dest='proxy', + type='str', + default='', + help="Specify a proxy in the form [user:passwd@]proxy.server:port." +) # type: Any + +retries = partial( + Option, + '--retries', + dest='retries', + type='int', + default=5, + help="Maximum number of retries each connection should attempt " + "(default %default times).", +) # type: Any + +timeout = partial( + Option, + '--timeout', '--default-timeout', + metavar='sec', + dest='timeout', + type='float', + default=15, + help='Set the socket timeout (default %default seconds).', +) # type: Any + +skip_requirements_regex = partial( + Option, + # A regex to be used to skip requirements + '--skip-requirements-regex', + dest='skip_requirements_regex', + type='str', + default='', + help=SUPPRESS_HELP, +) # type: Any + + +def exists_action(): + return Option( + # Option when path already exist + '--exists-action', + dest='exists_action', + type='choice', + choices=['s', 'i', 'w', 'b', 'a'], + default=[], + action='append', + metavar='action', + help="Default action when a path already exists: " + "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", + ) + + +cert = partial( + Option, + '--cert', + dest='cert', + type='str', + metavar='path', + help="Path to alternate CA bundle.", +) # type: Any + +client_cert = partial( + Option, + '--client-cert', + dest='client_cert', + type='str', + default=None, + metavar='path', + help="Path to SSL client certificate, a single file containing the " + "private key and the certificate in PEM format.", +) # type: Any + +index_url = partial( + Option, + '-i', '--index-url', '--pypi-url', + dest='index_url', + metavar='URL', + default=PyPI.simple_url, + help="Base URL of Python Package Index (default %default). " + "This should point to a repository compliant with PEP 503 " + "(the simple repository API) or a local directory laid out " + "in the same format.", +) # type: Any + + +def extra_index_url(): + return Option( + '--extra-index-url', + dest='extra_index_urls', + metavar='URL', + action='append', + default=[], + help="Extra URLs of package indexes to use in addition to " + "--index-url. Should follow the same rules as " + "--index-url.", + ) + + +no_index = partial( + Option, + '--no-index', + dest='no_index', + action='store_true', + default=False, + help='Ignore package index (only looking at --find-links URLs instead).', +) # type: Any + + +def find_links(): + return Option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='url', + help="If a url or path to an html file, then parse for links to " + "archives. If a local path or file:// url that's a directory, " + "then look for archives in the directory listing.", + ) + + +def trusted_host(): + return Option( + "--trusted-host", + dest="trusted_hosts", + action="append", + metavar="HOSTNAME", + default=[], + help="Mark this host as trusted, even though it does not have valid " + "or any HTTPS.", + ) + + +# Remove after 1.5 +process_dependency_links = partial( + Option, + "--process-dependency-links", + dest="process_dependency_links", + action="store_true", + default=False, + help="Enable the processing of dependency links.", +) # type: Any + + +def constraints(): + return Option( + '-c', '--constraint', + dest='constraints', + action='append', + default=[], + metavar='file', + help='Constrain versions using the given constraints file. ' + 'This option can be used multiple times.' + ) + + +def requirements(): + return Option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Install from the given requirements file. ' + 'This option can be used multiple times.' + ) + + +def editable(): + return Option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='path/url', + help=('Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.'), + ) + + +src = partial( + Option, + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + metavar='dir', + default=src_prefix, + help='Directory to check out editable projects into. ' + 'The default in a virtualenv is "/src". ' + 'The default for global installs is "/src".' +) # type: Any + + +def _get_format_control(values, option): + """Get a format_control object.""" + return getattr(values, option.dest) + + +def _handle_no_binary(option, opt_str, value, parser): + existing = getattr(parser.values, option.dest) + fmt_ctl_handle_mutual_exclude( + value, existing.no_binary, existing.only_binary, + ) + + +def _handle_only_binary(option, opt_str, value, parser): + existing = getattr(parser.values, option.dest) + fmt_ctl_handle_mutual_exclude( + value, existing.only_binary, existing.no_binary, + ) + + +def no_binary(): + return Option( + "--no-binary", dest="format_control", action="callback", + callback=_handle_no_binary, type="str", + default=FormatControl(set(), set()), + help="Do not use binary packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all binary packages, :none: to empty the set, or one or " + "more package names with commas between them. Note that some " + "packages are tricky to compile and may fail to install when " + "this option is used on them.", + ) + + +def only_binary(): + return Option( + "--only-binary", dest="format_control", action="callback", + callback=_handle_only_binary, type="str", + default=FormatControl(set(), set()), + help="Do not use source packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all source packages, :none: to empty the set, or one or " + "more package names with commas between them. Packages without " + "binary distributions will fail to install when this option is " + "used on them.", + ) + + +cache_dir = partial( + Option, + "--cache-dir", + dest="cache_dir", + default=USER_CACHE_DIR, + metavar="dir", + help="Store the cache data in ." +) + +no_cache = partial( + Option, + "--no-cache-dir", + dest="cache_dir", + action="store_false", + help="Disable the cache.", +) + +no_deps = partial( + Option, + '--no-deps', '--no-dependencies', + dest='ignore_dependencies', + action='store_true', + default=False, + help="Don't install package dependencies.", +) # type: Any + +build_dir = partial( + Option, + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + metavar='dir', + help='Directory to unpack packages into and build in. Note that ' + 'an initial build still takes place in a temporary directory. ' + 'The location of temporary directories can be controlled by setting ' + 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' + 'When passed, build directories are not cleaned in case of failures.' +) # type: Any + +ignore_requires_python = partial( + Option, + '--ignore-requires-python', + dest='ignore_requires_python', + action='store_true', + help='Ignore the Requires-Python information.' +) # type: Any + +no_build_isolation = partial( + Option, + '--no-build-isolation', + dest='build_isolation', + action='store_false', + default=True, + help='Disable isolation when building a modern source distribution. ' + 'Build dependencies specified by PEP 518 must be already installed ' + 'if this option is used.' +) # type: Any + +install_options = partial( + Option, + '--install-option', + dest='install_options', + action='append', + metavar='options', + help="Extra arguments to be supplied to the setup.py install " + "command (use like --install-option=\"--install-scripts=/usr/local/" + "bin\"). Use multiple --install-option options to pass multiple " + "options to setup.py install. If you are using an option with a " + "directory path, be sure to use absolute path.", +) # type: Any + +global_options = partial( + Option, + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the install command.", +) # type: Any + +no_clean = partial( + Option, + '--no-clean', + action='store_true', + default=False, + help="Don't clean up build directories)." +) # type: Any + +pre = partial( + Option, + '--pre', + action='store_true', + default=False, + help="Include pre-release and development versions. By default, " + "pip only finds stable versions.", +) # type: Any + +disable_pip_version_check = partial( + Option, + "--disable-pip-version-check", + dest="disable_pip_version_check", + action="store_true", + default=False, + help="Don't periodically check PyPI to determine whether a new version " + "of pip is available for download. Implied with --no-index.", +) # type: Any + + +# Deprecated, Remove later +always_unzip = partial( + Option, + '-Z', '--always-unzip', + dest='always_unzip', + action='store_true', + help=SUPPRESS_HELP, +) # type: Any + + +def _merge_hash(option, opt_str, value, parser): + """Given a value spelled "algo:digest", append the digest to a list + pointed to in a dict by the algo name.""" + if not parser.values.hashes: + parser.values.hashes = {} + try: + algo, digest = value.split(':', 1) + except ValueError: + parser.error('Arguments to %s must be a hash name ' + 'followed by a value, like --hash=sha256:abcde...' % + opt_str) + if algo not in STRONG_HASHES: + parser.error('Allowed hash algorithms for %s are %s.' % + (opt_str, ', '.join(STRONG_HASHES))) + parser.values.hashes.setdefault(algo, []).append(digest) + + +hash = partial( + Option, + '--hash', + # Hash values eventually end up in InstallRequirement.hashes due to + # __dict__ copying in process_line(). + dest='hashes', + action='callback', + callback=_merge_hash, + type='string', + help="Verify that the package's archive matches this " + 'hash before installing. Example: --hash=sha256:abcdef...', +) # type: Any + + +require_hashes = partial( + Option, + '--require-hashes', + dest='require_hashes', + action='store_true', + default=False, + help='Require a hash to check each requirement against, for ' + 'repeatable installs. This option is implied when any package in a ' + 'requirements file has a --hash option.', +) # type: Any + + +########## +# groups # +########## + +general_group = { + 'name': 'General Options', + 'options': [ + help_, + isolated_mode, + require_virtualenv, + verbose, + version, + quiet, + log, + no_input, + proxy, + retries, + timeout, + skip_requirements_regex, + exists_action, + trusted_host, + cert, + client_cert, + cache_dir, + no_cache, + disable_pip_version_check, + no_color, + ] +} + +index_group = { + 'name': 'Package Index Options', + 'options': [ + index_url, + extra_index_url, + no_index, + find_links, + process_dependency_links, + ] +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__init__.py new file mode 100644 index 0000000..d79c48e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__init__.py @@ -0,0 +1,79 @@ +""" +Package containing all pip commands +""" +from __future__ import absolute_import + +from pip._internal.commands.completion import CompletionCommand +from pip._internal.commands.configuration import ConfigurationCommand +from pip._internal.commands.download import DownloadCommand +from pip._internal.commands.freeze import FreezeCommand +from pip._internal.commands.hash import HashCommand +from pip._internal.commands.help import HelpCommand +from pip._internal.commands.list import ListCommand +from pip._internal.commands.check import CheckCommand +from pip._internal.commands.search import SearchCommand +from pip._internal.commands.show import ShowCommand +from pip._internal.commands.install import InstallCommand +from pip._internal.commands.uninstall import UninstallCommand +from pip._internal.commands.wheel import WheelCommand + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Type + from pip._internal.basecommand import Command + +commands_order = [ + InstallCommand, + DownloadCommand, + UninstallCommand, + FreezeCommand, + ListCommand, + ShowCommand, + CheckCommand, + ConfigurationCommand, + SearchCommand, + WheelCommand, + HashCommand, + CompletionCommand, + HelpCommand, +] # type: List[Type[Command]] + +commands_dict = {c.name: c for c in commands_order} + + +def get_summaries(ordered=True): + """Yields sorted (command name, command summary) tuples.""" + + if ordered: + cmditems = _sort_commands(commands_dict, commands_order) + else: + cmditems = commands_dict.items() + + for name, command_class in cmditems: + yield (name, command_class.summary) + + +def get_similar_commands(name): + """Command name auto-correct.""" + from difflib import get_close_matches + + name = name.lower() + + close_commands = get_close_matches(name, commands_dict.keys()) + + if close_commands: + return close_commands[0] + else: + return False + + +def _sort_commands(cmddict, order): + def keyfn(key): + try: + return order.index(key[1]) + except ValueError: + # unordered items should come last + return 0xff + + return sorted(cmddict.items(), key=keyfn) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..cf997d0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/check.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/check.cpython-37.pyc new file mode 100644 index 0000000..97a3896 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/check.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/completion.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/completion.cpython-37.pyc new file mode 100644 index 0000000..b7bd4c0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/completion.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc new file mode 100644 index 0000000..9b2e189 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/download.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/download.cpython-37.pyc new file mode 100644 index 0000000..9f34fe7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/download.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc new file mode 100644 index 0000000..94b2ffa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/hash.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/hash.cpython-37.pyc new file mode 100644 index 0000000..df5fad8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/hash.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/help.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/help.cpython-37.pyc new file mode 100644 index 0000000..3d68a1b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/help.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/install.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/install.cpython-37.pyc new file mode 100644 index 0000000..c161952 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/install.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/list.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/list.cpython-37.pyc new file mode 100644 index 0000000..7f7c948 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/list.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/search.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/search.cpython-37.pyc new file mode 100644 index 0000000..9e3689e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/search.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/show.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/show.cpython-37.pyc new file mode 100644 index 0000000..b09499a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/show.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc new file mode 100644 index 0000000..56a7810 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc new file mode 100644 index 0000000..5a776a5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/check.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/check.py new file mode 100644 index 0000000..88db510 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/check.py @@ -0,0 +1,42 @@ +import logging + +from pip._internal.basecommand import Command +from pip._internal.operations.check import ( + check_package_set, create_package_set_from_installed, +) +from pip._internal.utils.misc import get_installed_distributions + +logger = logging.getLogger(__name__) + + +class CheckCommand(Command): + """Verify installed packages have compatible dependencies.""" + name = 'check' + usage = """ + %prog [options]""" + summary = 'Verify installed packages have compatible dependencies.' + + def run(self, options, args): + package_set = create_package_set_from_installed() + missing, conflicting = check_package_set(package_set) + + for project_name in missing: + version = package_set[project_name].version + for dependency in missing[project_name]: + logger.info( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[0], + ) + + for project_name in conflicting: + version = package_set[project_name].version + for dep_name, dep_version, req in conflicting[project_name]: + logger.info( + "%s %s has requirement %s, but you have %s %s.", + project_name, version, req, dep_name, dep_version, + ) + + if missing or conflicting: + return 1 + else: + logger.info("No broken requirements found.") diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/completion.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/completion.py new file mode 100644 index 0000000..c4b3873 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/completion.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import + +import sys +import textwrap + +from pip._internal.basecommand import Command +from pip._internal.utils.misc import get_prog + +BASE_COMPLETION = """ +# pip %(shell)s completion start%(script)s# pip %(shell)s completion end +""" + +COMPLETION_SCRIPTS = { + 'bash': """ + _pip_completion() + { + COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ + COMP_CWORD=$COMP_CWORD \\ + PIP_AUTO_COMPLETE=1 $1 ) ) + } + complete -o default -F _pip_completion %(prog)s + """, + 'zsh': """ + function _pip_completion { + local words cword + read -Ac words + read -cn cword + reply=( $( COMP_WORDS="$words[*]" \\ + COMP_CWORD=$(( cword-1 )) \\ + PIP_AUTO_COMPLETE=1 $words[1] ) ) + } + compctl -K _pip_completion %(prog)s + """, + 'fish': """ + function __fish_complete_pip + set -lx COMP_WORDS (commandline -o) "" + set -lx COMP_CWORD ( \\ + math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\ + ) + set -lx PIP_AUTO_COMPLETE 1 + string split \\ -- (eval $COMP_WORDS[1]) + end + complete -fa "(__fish_complete_pip)" -c %(prog)s + """, +} + + +class CompletionCommand(Command): + """A helper command to be used for command completion.""" + name = 'completion' + summary = 'A helper command used for command completion.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(CompletionCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '--bash', '-b', + action='store_const', + const='bash', + dest='shell', + help='Emit completion code for bash') + cmd_opts.add_option( + '--zsh', '-z', + action='store_const', + const='zsh', + dest='shell', + help='Emit completion code for zsh') + cmd_opts.add_option( + '--fish', '-f', + action='store_const', + const='fish', + dest='shell', + help='Emit completion code for fish') + + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + """Prints the completion code of the given shell""" + shells = COMPLETION_SCRIPTS.keys() + shell_options = ['--' + shell for shell in sorted(shells)] + if options.shell in shells: + script = textwrap.dedent( + COMPLETION_SCRIPTS.get(options.shell, '') % { + 'prog': get_prog(), + } + ) + print(BASE_COMPLETION % {'script': script, 'shell': options.shell}) + else: + sys.stderr.write( + 'ERROR: You must pass %s\n' % ' or '.join(shell_options) + ) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/configuration.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/configuration.py new file mode 100644 index 0000000..57448cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/configuration.py @@ -0,0 +1,227 @@ +import logging +import os +import subprocess + +from pip._internal.basecommand import Command +from pip._internal.configuration import Configuration, kinds +from pip._internal.exceptions import PipError +from pip._internal.locations import venv_config_file +from pip._internal.status_codes import ERROR, SUCCESS +from pip._internal.utils.misc import get_prog + +logger = logging.getLogger(__name__) + + +class ConfigurationCommand(Command): + """Manage local and global configuration. + + Subcommands: + + list: List the active configuration (or from the file specified) + edit: Edit the configuration file in an editor + get: Get the value associated with name + set: Set the name=value + unset: Unset the value associated with name + + If none of --user, --global and --venv are passed, a virtual + environment configuration file is used if one is active and the file + exists. Otherwise, all modifications happen on the to the user file by + default. + """ + + name = 'config' + usage = """ + %prog [] list + %prog [] [--editor ] edit + + %prog [] get name + %prog [] set name value + %prog [] unset name + """ + + summary = "Manage local and global configuration." + + def __init__(self, *args, **kwargs): + super(ConfigurationCommand, self).__init__(*args, **kwargs) + + self.configuration = None + + self.cmd_opts.add_option( + '--editor', + dest='editor', + action='store', + default=None, + help=( + 'Editor to use to edit the file. Uses VISUAL or EDITOR ' + 'environment variables if not provided.' + ) + ) + + self.cmd_opts.add_option( + '--global', + dest='global_file', + action='store_true', + default=False, + help='Use the system-wide configuration file only' + ) + + self.cmd_opts.add_option( + '--user', + dest='user_file', + action='store_true', + default=False, + help='Use the user configuration file only' + ) + + self.cmd_opts.add_option( + '--venv', + dest='venv_file', + action='store_true', + default=False, + help='Use the virtualenv configuration file only' + ) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + handlers = { + "list": self.list_values, + "edit": self.open_in_editor, + "get": self.get_name, + "set": self.set_name_value, + "unset": self.unset_name + } + + # Determine action + if not args or args[0] not in handlers: + logger.error("Need an action ({}) to perform.".format( + ", ".join(sorted(handlers))) + ) + return ERROR + + action = args[0] + + # Determine which configuration files are to be loaded + # Depends on whether the command is modifying. + try: + load_only = self._determine_file( + options, need_value=(action in ["get", "set", "unset", "edit"]) + ) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + # Load a new configuration + self.configuration = Configuration( + isolated=options.isolated_mode, load_only=load_only + ) + self.configuration.load() + + # Error handling happens here, not in the action-handlers. + try: + handlers[action](options, args[1:]) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + return SUCCESS + + def _determine_file(self, options, need_value): + file_options = { + kinds.USER: options.user_file, + kinds.GLOBAL: options.global_file, + kinds.VENV: options.venv_file + } + + if sum(file_options.values()) == 0: + if not need_value: + return None + # Default to user, unless there's a virtualenv file. + elif os.path.exists(venv_config_file): + return kinds.VENV + else: + return kinds.USER + elif sum(file_options.values()) == 1: + # There's probably a better expression for this. + return [key for key in file_options if file_options[key]][0] + + raise PipError( + "Need exactly one file to operate upon " + "(--user, --venv, --global) to perform." + ) + + def list_values(self, options, args): + self._get_n_args(args, "list", n=0) + + for key, value in sorted(self.configuration.items()): + logger.info("%s=%r", key, value) + + def get_name(self, options, args): + key = self._get_n_args(args, "get [name]", n=1) + value = self.configuration.get_value(key) + + logger.info("%s", value) + + def set_name_value(self, options, args): + key, value = self._get_n_args(args, "set [name] [value]", n=2) + self.configuration.set_value(key, value) + + self._save_configuration() + + def unset_name(self, options, args): + key = self._get_n_args(args, "unset [name]", n=1) + self.configuration.unset_value(key) + + self._save_configuration() + + def open_in_editor(self, options, args): + editor = self._determine_editor(options) + + fname = self.configuration.get_file_to_edit() + if fname is None: + raise PipError("Could not determine appropriate file.") + + try: + subprocess.check_call([editor, fname]) + except subprocess.CalledProcessError as e: + raise PipError( + "Editor Subprocess exited with exit code {}" + .format(e.returncode) + ) + + def _get_n_args(self, args, example, n): + """Helper to make sure the command got the right number of arguments + """ + if len(args) != n: + msg = ( + 'Got unexpected number of arguments, expected {}. ' + '(example: "{} config {}")' + ).format(n, get_prog(), example) + raise PipError(msg) + + if n == 1: + return args[0] + else: + return args + + def _save_configuration(self): + # We successfully ran a modifying command. Need to save the + # configuration. + try: + self.configuration.save() + except Exception: + logger.error( + "Unable to save configuration. Please report this as a bug.", + exc_info=1 + ) + raise PipError("Internal Error.") + + def _determine_editor(self, options): + if options.editor is not None: + return options.editor + elif "VISUAL" in os.environ: + return os.environ["VISUAL"] + elif "EDITOR" in os.environ: + return os.environ["EDITOR"] + else: + raise PipError("Could not determine editor to use.") diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/download.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/download.py new file mode 100644 index 0000000..5713d07 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/download.py @@ -0,0 +1,233 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._internal import cmdoptions +from pip._internal.basecommand import RequirementCommand +from pip._internal.exceptions import CommandError +from pip._internal.index import FormatControl +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, normalize_path +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +class DownloadCommand(RequirementCommand): + """ + Download packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports downloading from "requirements files", which provide + an easy way to specify a whole environment to be downloaded. + """ + name = 'download' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] ... + %prog [options] ... + %prog [options] ...""" + + summary = 'Download packages.' + + def __init__(self, *args, **kw): + super(DownloadCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.global_options()) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.pre()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + + cmd_opts.add_option( + '-d', '--dest', '--destination-dir', '--destination-directory', + dest='download_dir', + metavar='dir', + default=os.curdir, + help=("Download packages into ."), + ) + + cmd_opts.add_option( + '--platform', + dest='platform', + metavar='platform', + default=None, + help=("Only download wheels compatible with . " + "Defaults to the platform of the running system."), + ) + + cmd_opts.add_option( + '--python-version', + dest='python_version', + metavar='python_version', + default=None, + help=("Only download wheels compatible with Python " + "interpreter version . If not specified, then the " + "current system interpreter minor version is used. A major " + "version (e.g. '2') can be specified to match all " + "minor revs of that major version. A minor version " + "(e.g. '34') can also be specified."), + ) + + cmd_opts.add_option( + '--implementation', + dest='implementation', + metavar='implementation', + default=None, + help=("Only download wheels compatible with Python " + "implementation , e.g. 'pp', 'jy', 'cp', " + " or 'ip'. If not specified, then the current " + "interpreter implementation is used. Use 'py' to force " + "implementation-agnostic wheels."), + ) + + cmd_opts.add_option( + '--abi', + dest='abi', + metavar='abi', + default=None, + help=("Only download wheels compatible with Python " + "abi , e.g. 'pypy_41'. If not specified, then the " + "current interpreter abi tag is used. Generally " + "you will need to specify --implementation, " + "--platform, and --python-version when using " + "this option."), + ) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + options.ignore_installed = True + # editable doesn't really make sense for `pip download`, but the bowels + # of the RequirementSet code require that property. + options.editables = [] + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + dist_restriction_set = any([ + options.python_version, + options.platform, + options.abi, + options.implementation, + ]) + binary_only = FormatControl(set(), {':all:'}) + no_sdist_dependencies = ( + options.format_control != binary_only and + not options.ignore_dependencies + ) + if dist_restriction_set and no_sdist_dependencies: + raise CommandError( + "When restricting platform and interpreter constraints using " + "--python-version, --platform, --abi, or --implementation, " + "either --no-deps must be set, or --only-binary=:all: must be " + "set and --no-binary must not be set (or must be set to " + ":none:)." + ) + + options.src_dir = os.path.abspath(options.src_dir) + options.download_dir = normalize_path(options.download_dir) + + ensure_dir(options.download_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + build_delete = (not (options.no_clean or options.build_dir)) + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with TempDirectory( + options.build_dir, delete=build_delete, kind="download" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + self.populate_requirement_set( + requirement_set, + args, + options, + finder, + session, + self.name, + None + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=options.download_dir, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=None, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=False, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + downloaded = ' '.join([ + req.name for req in requirement_set.successfully_downloaded + ]) + if downloaded: + logger.info('Successfully downloaded %s', downloaded) + + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + + return requirement_set diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/freeze.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/freeze.py new file mode 100644 index 0000000..0d3d4ae --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/freeze.py @@ -0,0 +1,96 @@ +from __future__ import absolute_import + +import sys + +from pip._internal import index +from pip._internal.basecommand import Command +from pip._internal.cache import WheelCache +from pip._internal.compat import stdlib_pkgs +from pip._internal.operations.freeze import freeze + +DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} + + +class FreezeCommand(Command): + """ + Output installed packages in requirements format. + + packages are listed in a case-insensitive sorted order. + """ + name = 'freeze' + usage = """ + %prog [options]""" + summary = 'Output installed packages in requirements format.' + log_streams = ("ext://sys.stderr", "ext://sys.stderr") + + def __init__(self, *args, **kw): + super(FreezeCommand, self).__init__(*args, **kw) + + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help="Use the order in the given requirements file and its " + "comments when generating output. This option can be " + "used multiple times.") + self.cmd_opts.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the ' + 'output.') + self.cmd_opts.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv that has global access, do not output ' + 'globally-installed packages.') + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + self.cmd_opts.add_option( + '--all', + dest='freeze_all', + action='store_true', + help='Do not skip these packages in the output:' + ' %s' % ', '.join(DEV_PKGS)) + self.cmd_opts.add_option( + '--exclude-editable', + dest='exclude_editable', + action='store_true', + help='Exclude editable package from output.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + format_control = index.FormatControl(set(), set()) + wheel_cache = WheelCache(options.cache_dir, format_control) + skip = set(stdlib_pkgs) + if not options.freeze_all: + skip.update(DEV_PKGS) + + freeze_kwargs = dict( + requirement=options.requirements, + find_links=options.find_links, + local_only=options.local, + user_only=options.user, + skip_regex=options.skip_requirements_regex, + isolated=options.isolated_mode, + wheel_cache=wheel_cache, + skip=skip, + exclude_editable=options.exclude_editable, + ) + + try: + for line in freeze(**freeze_kwargs): + sys.stdout.write(line + '\n') + finally: + wheel_cache.cleanup() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/hash.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/hash.py new file mode 100644 index 0000000..95353b0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/hash.py @@ -0,0 +1,57 @@ +from __future__ import absolute_import + +import hashlib +import logging +import sys + +from pip._internal.basecommand import Command +from pip._internal.status_codes import ERROR +from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES +from pip._internal.utils.misc import read_chunks + +logger = logging.getLogger(__name__) + + +class HashCommand(Command): + """ + Compute a hash of a local package archive. + + These can be used with --hash in a requirements file to do repeatable + installs. + + """ + name = 'hash' + usage = '%prog [options] ...' + summary = 'Compute hashes of package archives.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(HashCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-a', '--algorithm', + dest='algorithm', + choices=STRONG_HASHES, + action='store', + default=FAVORITE_HASH, + help='The hash algorithm to use: one of %s' % + ', '.join(STRONG_HASHES)) + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + self.parser.print_usage(sys.stderr) + return ERROR + + algorithm = options.algorithm + for path in args: + logger.info('%s:\n--hash=%s:%s', + path, algorithm, _hash_of_file(path, algorithm)) + + +def _hash_of_file(path, algorithm): + """Return the hash digest of a file.""" + with open(path, 'rb') as archive: + hash = hashlib.new(algorithm) + for chunk in read_chunks(archive): + hash.update(chunk) + return hash.hexdigest() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/help.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/help.py new file mode 100644 index 0000000..06ca2c1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/help.py @@ -0,0 +1,36 @@ +from __future__ import absolute_import + +from pip._internal.basecommand import SUCCESS, Command +from pip._internal.exceptions import CommandError + + +class HelpCommand(Command): + """Show help for commands""" + name = 'help' + usage = """ + %prog """ + summary = 'Show help for commands.' + ignore_require_venv = True + + def run(self, options, args): + from pip._internal.commands import commands_dict, get_similar_commands + + try: + # 'pip help' with no args is handled by pip.__init__.parseopt() + cmd_name = args[0] # the command we need help for + except IndexError: + return SUCCESS + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + command = commands_dict[cmd_name]() + command.parser.print_help() + + return SUCCESS diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/install.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/install.py new file mode 100644 index 0000000..9138683 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/install.py @@ -0,0 +1,502 @@ +from __future__ import absolute_import + +import errno +import logging +import operator +import os +import shutil +from optparse import SUPPRESS_HELP + +from pip._internal import cmdoptions +from pip._internal.basecommand import RequirementCommand +from pip._internal.cache import WheelCache +from pip._internal.exceptions import ( + CommandError, InstallationError, PreviousBuildDirError, +) +from pip._internal.locations import distutils_scheme, virtualenv_no_global +from pip._internal.operations.check import check_install_conflicts +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet, install_given_reqs +from pip._internal.resolve import Resolver +from pip._internal.status_codes import ERROR +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, get_installed_version +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +try: + import wheel +except ImportError: + wheel = None + + +logger = logging.getLogger(__name__) + + +class InstallCommand(RequirementCommand): + """ + Install packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports installing from "requirements files", which provide + an easy way to specify a whole environment to be installed. + """ + name = 'install' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Install packages.' + + def __init__(self, *args, **kw): + super(InstallCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.pre()) + + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option( + '-t', '--target', + dest='target_dir', + metavar='dir', + default=None, + help='Install packages into . ' + 'By default this will not replace existing files/folders in ' + '. Use --upgrade to replace existing packages in ' + 'with new versions.' + ) + cmd_opts.add_option( + '--user', + dest='use_user_site', + action='store_true', + help="Install to the Python user install directory for your " + "platform. Typically ~/.local/, or %APPDATA%\\Python on " + "Windows. (See the Python documentation for site.USER_BASE " + "for full details.)") + cmd_opts.add_option( + '--no-user', + dest='use_user_site', + action='store_false', + help=SUPPRESS_HELP) + cmd_opts.add_option( + '--root', + dest='root_path', + metavar='dir', + default=None, + help="Install everything relative to this alternate root " + "directory.") + cmd_opts.add_option( + '--prefix', + dest='prefix_path', + metavar='dir', + default=None, + help="Installation prefix where lib, bin and other top-level " + "folders are placed") + + cmd_opts.add_option(cmdoptions.build_dir()) + + cmd_opts.add_option(cmdoptions.src()) + + cmd_opts.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all specified packages to the newest available ' + 'version. The handling of dependencies depends on the ' + 'upgrade-strategy used.' + ) + + cmd_opts.add_option( + '--upgrade-strategy', + dest='upgrade_strategy', + default='only-if-needed', + choices=['only-if-needed', 'eager'], + help='Determines how dependency upgrading should be handled ' + '[default: %default]. ' + '"eager" - dependencies are upgraded regardless of ' + 'whether the currently installed version satisfies the ' + 'requirements of the upgraded package(s). ' + '"only-if-needed" - are upgraded only when they do not ' + 'satisfy the requirements of the upgraded package(s).' + ) + + cmd_opts.add_option( + '--force-reinstall', + dest='force_reinstall', + action='store_true', + help='Reinstall all packages even if they are already ' + 'up-to-date.') + + cmd_opts.add_option( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages (reinstalling instead).') + + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + + cmd_opts.add_option(cmdoptions.install_options()) + cmd_opts.add_option(cmdoptions.global_options()) + + cmd_opts.add_option( + "--compile", + action="store_true", + dest="compile", + default=True, + help="Compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-compile", + action="store_false", + dest="compile", + help="Do not compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-warn-script-location", + action="store_false", + dest="warn_script_location", + default=True, + help="Do not warn when installing scripts outside PATH", + ) + cmd_opts.add_option( + "--no-warn-conflicts", + action="store_false", + dest="warn_about_conflicts", + default=True, + help="Do not warn about broken dependencies", + ) + + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + + upgrade_strategy = "to-satisfy-only" + if options.upgrade: + upgrade_strategy = options.upgrade_strategy + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + options.src_dir = os.path.abspath(options.src_dir) + install_options = options.install_options or [] + if options.use_user_site: + if options.prefix_path: + raise CommandError( + "Can not combine '--user' and '--prefix' as they imply " + "different installation locations" + ) + if virtualenv_no_global(): + raise InstallationError( + "Can not perform a '--user' install. User site-packages " + "are not visible in this virtualenv." + ) + install_options.append('--user') + install_options.append('--prefix=') + + target_temp_dir = TempDirectory(kind="target") + if options.target_dir: + options.ignore_installed = True + options.target_dir = os.path.abspath(options.target_dir) + if (os.path.exists(options.target_dir) and not + os.path.isdir(options.target_dir)): + raise CommandError( + "Target path exists but is not a directory, will not " + "continue." + ) + + # Create a target directory for using with the target option + target_temp_dir.create() + install_options.append('--home=' + target_temp_dir.path) + + global_options = options.global_options or [] + + with self._build_session(options) as session: + finder = self._build_package_finder(options, session) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with TempDirectory( + options.build_dir, delete=build_delete, kind="install" + ) as directory: + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=options.use_user_site, + upgrade_strategy=upgrade_strategy, + force_reinstall=options.force_reinstall, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=options.ignore_installed, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + # If caching is disabled or wheel is not installed don't + # try to build wheels. + if wheel and options.cache_dir: + # build wheels before install. + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=[], global_options=[], + ) + # Ignore the result: a failed wheel will be + # installed from the sdist/vcs whatever. + wb.build( + requirement_set.requirements.values(), + session=session, autobuilding=True + ) + + to_install = resolver.get_installation_order( + requirement_set + ) + + # Consistency Checking of the package set we're installing. + should_warn_about_conflicts = ( + not options.ignore_dependencies and + options.warn_about_conflicts + ) + if should_warn_about_conflicts: + self._warn_about_conflicts(to_install) + + # Don't warn about script install locations if + # --target has been specified + warn_script_location = options.warn_script_location + if options.target_dir: + warn_script_location = False + + installed = install_given_reqs( + to_install, + install_options, + global_options, + root=options.root_path, + home=target_temp_dir.path, + prefix=options.prefix_path, + pycompile=options.compile, + warn_script_location=warn_script_location, + use_user_site=options.use_user_site, + ) + + possible_lib_locations = get_lib_location_guesses( + user=options.use_user_site, + home=target_temp_dir.path, + root=options.root_path, + prefix=options.prefix_path, + isolated=options.isolated_mode, + ) + reqs = sorted(installed, key=operator.attrgetter('name')) + items = [] + for req in reqs: + item = req.name + try: + installed_version = get_installed_version( + req.name, possible_lib_locations + ) + if installed_version: + item += '-' + installed_version + except Exception: + pass + items.append(item) + installed = ' '.join(items) + if installed: + logger.info('Successfully installed %s', installed) + except EnvironmentError as error: + show_traceback = (self.verbosity >= 1) + + message = create_env_error_message( + error, show_traceback, options.use_user_site, + ) + logger.error(message, exc_info=show_traceback) + + return ERROR + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() + + if options.target_dir: + self._handle_target_dir( + options.target_dir, target_temp_dir, options.upgrade + ) + return requirement_set + + def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): + ensure_dir(target_dir) + + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + lib_dir_list = [] + + with target_temp_dir: + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + scheme = distutils_scheme('', home=target_temp_dir.path) + purelib_dir = scheme['purelib'] + platlib_dir = scheme['platlib'] + data_dir = scheme['data'] + + if os.path.exists(purelib_dir): + lib_dir_list.append(purelib_dir) + if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: + lib_dir_list.append(platlib_dir) + if os.path.exists(data_dir): + lib_dir_list.append(data_dir) + + for lib_dir in lib_dir_list: + for item in os.listdir(lib_dir): + if lib_dir == data_dir: + ddir = os.path.join(data_dir, item) + if any(s.startswith(ddir) for s in lib_dir_list[:-1]): + continue + target_item_dir = os.path.join(target_dir, item) + if os.path.exists(target_item_dir): + if not upgrade: + logger.warning( + 'Target directory %s already exists. Specify ' + '--upgrade to force replacement.', + target_item_dir + ) + continue + if os.path.islink(target_item_dir): + logger.warning( + 'Target directory %s already exists and is ' + 'a link. Pip will not automatically replace ' + 'links, please remove if replacement is ' + 'desired.', + target_item_dir + ) + continue + if os.path.isdir(target_item_dir): + shutil.rmtree(target_item_dir) + else: + os.remove(target_item_dir) + + shutil.move( + os.path.join(lib_dir, item), + target_item_dir + ) + + def _warn_about_conflicts(self, to_install): + package_set, _dep_info = check_install_conflicts(to_install) + missing, conflicting = _dep_info + + # NOTE: There is some duplication here from pip check + for project_name in missing: + version = package_set[project_name][0] + for dependency in missing[project_name]: + logger.critical( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[1], + ) + + for project_name in conflicting: + version = package_set[project_name][0] + for dep_name, dep_version, req in conflicting[project_name]: + logger.critical( + "%s %s has requirement %s, but you'll have %s %s which is " + "incompatible.", + project_name, version, req, dep_name, dep_version, + ) + + +def get_lib_location_guesses(*args, **kwargs): + scheme = distutils_scheme('', *args, **kwargs) + return [scheme['purelib'], scheme['platlib']] + + +def create_env_error_message(error, show_traceback, using_user_site): + """Format an error message for an EnvironmentError + + It may occur anytime during the execution of the install command. + """ + parts = [] + + # Mention the error if we are not going to show a traceback + parts.append("Could not install packages due to an EnvironmentError") + if not show_traceback: + parts.append(": ") + parts.append(str(error)) + else: + parts.append(".") + + # Spilt the error indication from a helper message (if any) + parts[-1] += "\n" + + # Suggest useful actions to the user: + # (1) using user site-packages or (2) verifying the permissions + if error.errno == errno.EACCES: + user_option_part = "Consider using the `--user` option" + permissions_part = "Check the permissions" + + if not using_user_site: + parts.extend([ + user_option_part, " or ", + permissions_part.lower(), + ]) + else: + parts.append(permissions_part) + parts.append(".\n") + + return "".join(parts).strip() + "\n" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/list.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/list.py new file mode 100644 index 0000000..09f633f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/list.py @@ -0,0 +1,343 @@ +from __future__ import absolute_import + +import json +import logging +import warnings + +from pip._vendor import six +from pip._vendor.six.moves import zip_longest + +from pip._internal.basecommand import Command +from pip._internal.cmdoptions import index_group, make_option_group +from pip._internal.exceptions import CommandError +from pip._internal.index import PackageFinder +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) +from pip._internal.utils.packaging import get_installer + +logger = logging.getLogger(__name__) + + +class ListCommand(Command): + """ + List installed packages, including editables. + + Packages are listed in a case-insensitive sorted order. + """ + name = 'list' + usage = """ + %prog [options]""" + summary = 'List installed packages.' + + def __init__(self, *args, **kw): + super(ListCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-o', '--outdated', + action='store_true', + default=False, + help='List outdated packages') + cmd_opts.add_option( + '-u', '--uptodate', + action='store_true', + default=False, + help='List uptodate packages') + cmd_opts.add_option( + '-e', '--editable', + action='store_true', + default=False, + help='List editable projects.') + cmd_opts.add_option( + '-l', '--local', + action='store_true', + default=False, + help=('If in a virtualenv that has global access, do not list ' + 'globally-installed packages.'), + ) + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option( + '--format', + action='store', + dest='list_format', + default="columns", + choices=('legacy', 'columns', 'freeze', 'json'), + help="Select the output format among: columns (default), freeze, " + "json, or legacy.", + ) + + cmd_opts.add_option( + '--not-required', + action='store_true', + dest='not_required', + help="List packages that are not dependencies of " + "installed packages.", + ) + + cmd_opts.add_option( + '--exclude-editable', + action='store_false', + dest='include_editable', + help='Exclude editable package from output.', + ) + cmd_opts.add_option( + '--include-editable', + action='store_true', + dest='include_editable', + help='Include editable package from output.', + default=True, + ) + index_opts = make_option_group(index_group, self.parser) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def _build_package_finder(self, options, index_urls, session): + """ + Create a package finder appropriate to this list command. + """ + return PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + allow_all_prereleases=options.pre, + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + + def run(self, options, args): + if options.list_format == "legacy": + warnings.warn( + "The legacy format has been deprecated and will be removed " + "in the future.", + RemovedInPip11Warning, + ) + + if options.outdated and options.uptodate: + raise CommandError( + "Options --outdated and --uptodate cannot be combined.") + + packages = get_installed_distributions( + local_only=options.local, + user_only=options.user, + editables_only=options.editable, + include_editables=options.include_editable, + ) + + if options.outdated: + packages = self.get_outdated(packages, options) + elif options.uptodate: + packages = self.get_uptodate(packages, options) + + if options.not_required: + packages = self.get_not_required(packages, options) + + self.output_package_listing(packages, options) + + def get_outdated(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version > dist.parsed_version + ] + + def get_uptodate(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version == dist.parsed_version + ] + + def get_not_required(self, packages, options): + dep_keys = set() + for dist in packages: + dep_keys.update(requirement.key for requirement in dist.requires()) + return {pkg for pkg in packages if pkg.key not in dep_keys} + + def iter_packages_latest_infos(self, packages, options): + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + dependency_links = [] + for dist in packages: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt'), + ) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, index_urls, session) + finder.add_dependency_links(dependency_links) + + for dist in packages: + typ = 'unknown' + all_candidates = finder.find_all_candidates(dist.key) + if not options.pre: + # Remove prereleases + all_candidates = [candidate for candidate in all_candidates + if not candidate.version.is_prerelease] + + if not all_candidates: + continue + best_candidate = max(all_candidates, + key=finder._candidate_sort_key) + remote_version = best_candidate.version + if best_candidate.location.is_wheel: + typ = 'wheel' + else: + typ = 'sdist' + # This is dirty but makes the rest of the code much cleaner + dist.latest_version = remote_version + dist.latest_filetype = typ + yield dist + + def output_legacy(self, dist, options): + if options.verbose >= 1: + return '%s (%s, %s, %s)' % ( + dist.project_name, + dist.version, + dist.location, + get_installer(dist), + ) + elif dist_is_editable(dist): + return '%s (%s, %s)' % ( + dist.project_name, + dist.version, + dist.location, + ) + else: + return '%s (%s)' % (dist.project_name, dist.version) + + def output_legacy_latest(self, dist, options): + return '%s - Latest: %s [%s]' % ( + self.output_legacy(dist, options), + dist.latest_version, + dist.latest_filetype, + ) + + def output_package_listing(self, packages, options): + packages = sorted( + packages, + key=lambda dist: dist.project_name.lower(), + ) + if options.list_format == 'columns' and packages: + data, header = format_for_columns(packages, options) + self.output_package_listing_columns(data, header) + elif options.list_format == 'freeze': + for dist in packages: + if options.verbose >= 1: + logger.info("%s==%s (%s)", dist.project_name, + dist.version, dist.location) + else: + logger.info("%s==%s", dist.project_name, dist.version) + elif options.list_format == 'json': + logger.info(format_for_json(packages, options)) + elif options.list_format == "legacy": + for dist in packages: + if options.outdated: + logger.info(self.output_legacy_latest(dist, options)) + else: + logger.info(self.output_legacy(dist, options)) + + def output_package_listing_columns(self, data, header): + # insert the header first: we need to know the size of column names + if len(data) > 0: + data.insert(0, header) + + pkg_strings, sizes = tabulate(data) + + # Create and add a separator. + if len(data) > 0: + pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) + + for val in pkg_strings: + logger.info(val) + + +def tabulate(vals): + # From pfmoore on GitHub: + # https://github.com/pypa/pip/issues/3651#issuecomment-216932564 + assert len(vals) > 0 + + sizes = [0] * max(len(x) for x in vals) + for row in vals: + sizes = [max(s, len(str(c))) for s, c in zip_longest(sizes, row)] + + result = [] + for row in vals: + display = " ".join([str(c).ljust(s) if c is not None else '' + for s, c in zip_longest(sizes, row)]) + result.append(display) + + return result, sizes + + +def format_for_columns(pkgs, options): + """ + Convert the package data into something usable + by output_package_listing_columns. + """ + running_outdated = options.outdated + # Adjust the header for the `pip list --outdated` case. + if running_outdated: + header = ["Package", "Version", "Latest", "Type"] + else: + header = ["Package", "Version"] + + data = [] + if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): + header.append("Location") + if options.verbose >= 1: + header.append("Installer") + + for proj in pkgs: + # if we're working on the 'outdated' list, separate out the + # latest_version and type + row = [proj.project_name, proj.version] + + if running_outdated: + row.append(proj.latest_version) + row.append(proj.latest_filetype) + + if options.verbose >= 1 or dist_is_editable(proj): + row.append(proj.location) + if options.verbose >= 1: + row.append(get_installer(proj)) + + data.append(row) + + return data, header + + +def format_for_json(packages, options): + data = [] + for dist in packages: + info = { + 'name': dist.project_name, + 'version': six.text_type(dist.version), + } + if options.verbose >= 1: + info['location'] = dist.location + info['installer'] = get_installer(dist) + if options.outdated: + info['latest_version'] = six.text_type(dist.latest_version) + info['latest_filetype'] = dist.latest_filetype + data.append(info) + return json.dumps(data) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/search.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/search.py new file mode 100644 index 0000000..3abdf59 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/search.py @@ -0,0 +1,135 @@ +from __future__ import absolute_import + +import logging +import sys +import textwrap +from collections import OrderedDict + +from pip._vendor import pkg_resources +from pip._vendor.packaging.version import parse as parse_version +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore + +from pip._internal.basecommand import SUCCESS, Command +from pip._internal.compat import get_terminal_size +from pip._internal.download import PipXmlrpcTransport +from pip._internal.exceptions import CommandError +from pip._internal.models import PyPI +from pip._internal.status_codes import NO_MATCHES_FOUND +from pip._internal.utils.logging import indent_log + +logger = logging.getLogger(__name__) + + +class SearchCommand(Command): + """Search for PyPI packages whose name or summary contains .""" + name = 'search' + usage = """ + %prog [options] """ + summary = 'Search PyPI for packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(SearchCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-i', '--index', + dest='index', + metavar='URL', + default=PyPI.pypi_url, + help='Base URL of Python Package Index (default %default)') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + raise CommandError('Missing required argument (search query).') + query = args + pypi_hits = self.search(query, options) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + if pypi_hits: + return SUCCESS + return NO_MATCHES_FOUND + + def search(self, query, options): + index_url = options.index + with self._build_session(options) as session: + transport = PipXmlrpcTransport(index_url, session) + pypi = xmlrpc_client.ServerProxy(index_url, transport) + hits = pypi.search({'name': query, 'summary': query}, 'or') + return hits + + +def transform_hits(hits): + """ + The list from pypi is really a list of versions. We want a list of + packages with the list of versions stored inline. This converts the + list from pypi into one we can use. + """ + packages = OrderedDict() + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + + if name not in packages.keys(): + packages[name] = { + 'name': name, + 'summary': summary, + 'versions': [version], + } + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + + return list(packages.values()) + + +def print_results(hits, name_column_width=None, terminal_width=None): + if not hits: + return + if name_column_width is None: + name_column_width = max([ + len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) + for hit in hits + ]) + 4 + + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + latest = highest_version(hit.get('versions', ['-'])) + if terminal_width is not None: + target_width = terminal_width - name_column_width - 5 + if target_width > 10: + # wrap and indent summary to fit terminal + summary = textwrap.wrap(summary, target_width) + summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) + + line = '%-*s - %s' % (name_column_width, + '%s (%s)' % (name, latest), summary) + try: + logger.info(line) + if name in installed_packages: + dist = pkg_resources.get_distribution(name) + with indent_log(): + if dist.version == latest: + logger.info('INSTALLED: %s (latest)', dist.version) + else: + logger.info('INSTALLED: %s', dist.version) + logger.info('LATEST: %s', latest) + except UnicodeEncodeError: + pass + + +def highest_version(versions): + return max(versions, key=parse_version) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/show.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/show.py new file mode 100644 index 0000000..1a8d968 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/show.py @@ -0,0 +1,164 @@ +from __future__ import absolute_import + +import logging +import os +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.basecommand import Command +from pip._internal.status_codes import ERROR, SUCCESS + +logger = logging.getLogger(__name__) + + +class ShowCommand(Command): + """Show information about one or more installed packages.""" + name = 'show' + usage = """ + %prog [options] ...""" + summary = 'Show information about installed packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(ShowCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-f', '--files', + dest='files', + action='store_true', + default=False, + help='Show the full list of installed files for each package.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + logger.warning('ERROR: Please provide a package name or names.') + return ERROR + query = args + + results = search_packages_info(query) + if not print_results( + results, list_files=options.files, verbose=options.verbose): + return ERROR + return SUCCESS + + +def search_packages_info(query): + """ + Gather details from installed distributions. Print distribution name, + version, location, and installed files. Installed files requires a + pip generated 'installed-files.txt' in the distributions '.egg-info' + directory. + """ + installed = {} + for p in pkg_resources.working_set: + installed[canonicalize_name(p.project_name)] = p + + query_names = [canonicalize_name(name) for name in query] + + for dist in [installed[pkg] for pkg in query_names if pkg in installed]: + package = { + 'name': dist.project_name, + 'version': dist.version, + 'location': dist.location, + 'requires': [dep.project_name for dep in dist.requires()], + } + file_list = None + metadata = None + if isinstance(dist, pkg_resources.DistInfoDistribution): + # RECORDs should be part of .dist-info metadatas + if dist.has_metadata('RECORD'): + lines = dist.get_metadata_lines('RECORD') + paths = [l.split(',')[0] for l in lines] + paths = [os.path.join(dist.location, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('METADATA'): + metadata = dist.get_metadata('METADATA') + else: + # Otherwise use pip's log for .egg-info's + if dist.has_metadata('installed-files.txt'): + paths = dist.get_metadata_lines('installed-files.txt') + paths = [os.path.join(dist.egg_info, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + + if dist.has_metadata('entry_points.txt'): + entry_points = dist.get_metadata_lines('entry_points.txt') + package['entry_points'] = entry_points + + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + package['installer'] = line.strip() + break + + # @todo: Should pkg_resources.Distribution have a + # `get_pkg_info` method? + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + for key in ('metadata-version', 'summary', + 'home-page', 'author', 'author-email', 'license'): + package[key] = pkg_info_dict.get(key) + + # It looks like FeedParser cannot deal with repeated headers + classifiers = [] + for line in metadata.splitlines(): + if line.startswith('Classifier: '): + classifiers.append(line[len('Classifier: '):]) + package['classifiers'] = classifiers + + if file_list: + package['files'] = sorted(file_list) + yield package + + +def print_results(distributions, list_files=False, verbose=False): + """ + Print the informations from installed distributions found. + """ + results_printed = False + for i, dist in enumerate(distributions): + results_printed = True + if i > 0: + logger.info("---") + + name = dist.get('name', '') + required_by = [ + pkg.project_name for pkg in pkg_resources.working_set + if name in [required.name for required in pkg.requires()] + ] + + logger.info("Name: %s", name) + logger.info("Version: %s", dist.get('version', '')) + logger.info("Summary: %s", dist.get('summary', '')) + logger.info("Home-page: %s", dist.get('home-page', '')) + logger.info("Author: %s", dist.get('author', '')) + logger.info("Author-email: %s", dist.get('author-email', '')) + logger.info("License: %s", dist.get('license', '')) + logger.info("Location: %s", dist.get('location', '')) + logger.info("Requires: %s", ', '.join(dist.get('requires', []))) + logger.info("Required-by: %s", ', '.join(required_by)) + + if verbose: + logger.info("Metadata-Version: %s", + dist.get('metadata-version', '')) + logger.info("Installer: %s", dist.get('installer', '')) + logger.info("Classifiers:") + for classifier in dist.get('classifiers', []): + logger.info(" %s", classifier) + logger.info("Entry-points:") + for entry in dist.get('entry_points', []): + logger.info(" %s", entry.strip()) + if list_files: + logger.info("Files:") + for line in dist.get('files', []): + logger.info(" %s", line.strip()) + if "files" not in dist: + logger.info("Cannot locate installed-files.txt") + return results_printed diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/uninstall.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/uninstall.py new file mode 100644 index 0000000..7476fa6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/uninstall.py @@ -0,0 +1,71 @@ +from __future__ import absolute_import + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.basecommand import Command +from pip._internal.exceptions import InstallationError +from pip._internal.req import InstallRequirement, parse_requirements + + +class UninstallCommand(Command): + """ + Uninstall packages. + + pip is able to uninstall most installed packages. Known exceptions are: + + - Pure distutils packages installed with ``python setup.py install``, which + leave behind no metadata to determine what files were installed. + - Script wrappers installed by ``python setup.py develop``. + """ + name = 'uninstall' + usage = """ + %prog [options] ... + %prog [options] -r ...""" + summary = 'Uninstall packages.' + + def __init__(self, *args, **kw): + super(UninstallCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Uninstall all the packages listed in the given requirements ' + 'file. This option can be used multiple times.', + ) + self.cmd_opts.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + with self._build_session(options) as session: + reqs_to_uninstall = {} + for name in args: + req = InstallRequirement.from_line( + name, isolated=options.isolated_mode, + ) + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + for filename in options.requirements: + for req in parse_requirements( + filename, + options=options, + session=session): + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + if not reqs_to_uninstall: + raise InstallationError( + 'You must give at least one requirement to %(name)s (see ' + '"pip help %(name)s")' % dict(name=self.name) + ) + for req in reqs_to_uninstall.values(): + uninstall_pathset = req.uninstall( + auto_confirm=options.yes, verbose=self.verbosity > 0, + ) + if uninstall_pathset: + uninstall_pathset.commit() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/wheel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/wheel.py new file mode 100644 index 0000000..ac55f91 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/commands/wheel.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import logging +import os + +from pip._internal import cmdoptions +from pip._internal.basecommand import RequirementCommand +from pip._internal.cache import WheelCache +from pip._internal.exceptions import CommandError, PreviousBuildDirError +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.resolve import Resolver +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +logger = logging.getLogger(__name__) + + +class WheelCommand(RequirementCommand): + """ + Build Wheel archives for your requirements and dependencies. + + Wheel is a built-package format, and offers the advantage of not + recompiling your software during every install. For more details, see the + wheel docs: https://wheel.readthedocs.io/en/latest/ + + Requirements: setuptools>=0.8, and wheel. + + 'pip wheel' uses the bdist_wheel setuptools extension from the wheel + package to build individual wheels. + + """ + + name = 'wheel' + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Build wheels from your requirements.' + + def __init__(self, *args, **kw): + super(WheelCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-w', '--wheel-dir', + dest='wheel_dir', + metavar='dir', + default=os.curdir, + help=("Build wheels into , where the default is the " + "current working directory."), + ) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option( + '--build-option', + dest='build_options', + metavar='options', + action='append', + help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", + ) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + cmd_opts.add_option( + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the 'bdist_wheel' command.") + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + options.src_dir = os.path.abspath(options.src_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, session) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + with TempDirectory( + options.build_dir, delete=build_delete, kind="wheel" + ) as directory: + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=options.wheel_dir, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + # build wheels + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=options.build_options or [], + global_options=options.global_options or [], + no_clean=options.no_clean, + ) + wheels_built_successfully = wb.build( + requirement_set.requirements.values(), session=session, + ) + if not wheels_built_successfully: + raise CommandError( + "Failed to build one or more wheels" + ) + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/compat.py new file mode 100644 index 0000000..4aefd58 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/compat.py @@ -0,0 +1,235 @@ +"""Stuff that differs in different Python versions and platform +distributions.""" +from __future__ import absolute_import, division + +import codecs +import locale +import logging +import os +import shutil +import sys + +from pip._vendor.six import text_type + +try: + import ipaddress +except ImportError: + try: + from pip._vendor import ipaddress # type: ignore + except ImportError: + import ipaddr as ipaddress # type: ignore + ipaddress.ip_address = ipaddress.IPAddress + ipaddress.ip_network = ipaddress.IPNetwork + + +__all__ = [ + "ipaddress", "uses_pycache", "console_to_str", "native_str", + "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", +] + + +logger = logging.getLogger(__name__) + +if sys.version_info >= (3, 4): + uses_pycache = True + from importlib.util import cache_from_source +else: + import imp + + try: + cache_from_source = imp.cache_from_source # type: ignore + except AttributeError: + # does not use __pycache__ + cache_from_source = None + + uses_pycache = cache_from_source is not None + + +if sys.version_info >= (3, 5): + backslashreplace_decode = "backslashreplace" +else: + # In version 3.4 and older, backslashreplace exists + # but does not support use for decoding. + # We implement our own replace handler for this + # situation, so that we can consistently use + # backslash replacement for all versions. + def backslashreplace_decode_fn(err): + raw_bytes = (err.object[i] for i in range(err.start, err.end)) + if sys.version_info[0] == 2: + # Python 2 gave us characters - convert to numeric bytes + raw_bytes = (ord(b) for b in raw_bytes) + return u"".join(u"\\x%x" % c for c in raw_bytes), err.end + codecs.register_error( + "backslashreplace_decode", + backslashreplace_decode_fn, + ) + backslashreplace_decode = "backslashreplace_decode" + + +def console_to_str(data): + """Return a string, safe for output, of subprocess output. + + We assume the data is in the locale preferred encoding. + If it won't decode properly, we warn the user but decode as + best we can. + + We also ensure that the output can be safely written to + standard output without encoding errors. + """ + + # First, get the encoding we assume. This is the preferred + # encoding for the locale, unless that is not found, or + # it is ASCII, in which case assume UTF-8 + encoding = locale.getpreferredencoding() + if (not encoding) or codecs.lookup(encoding).name == "ascii": + encoding = "utf-8" + + # Now try to decode the data - if we fail, warn the user and + # decode with replacement. + try: + s = data.decode(encoding) + except UnicodeDecodeError: + logger.warning( + "Subprocess output does not appear to be encoded as %s", + encoding, + ) + s = data.decode(encoding, errors=backslashreplace_decode) + + # Make sure we can print the output, by encoding it to the output + # encoding with replacement of unencodable characters, and then + # decoding again. + # We use stderr's encoding because it's less likely to be + # redirected and if we don't find an encoding we skip this + # step (on the assumption that output is wrapped by something + # that won't fail). + # The double getattr is to deal with the possibility that we're + # being called in a situation where sys.__stderr__ doesn't exist, + # or doesn't have an encoding attribute. Neither of these cases + # should occur in normal pip use, but there's no harm in checking + # in case people use pip in (unsupported) unusual situations. + output_encoding = getattr(getattr(sys, "__stderr__", None), + "encoding", None) + + if output_encoding: + s = s.encode(output_encoding, errors="backslashreplace") + s = s.decode(output_encoding) + + return s + + +if sys.version_info >= (3,): + def native_str(s, replace=False): + if isinstance(s, bytes): + return s.decode('utf-8', 'replace' if replace else 'strict') + return s + +else: + def native_str(s, replace=False): + # Replace is ignored -- unicode to UTF-8 can't fail + if isinstance(s, text_type): + return s.encode('utf-8') + return s + + +def get_path_uid(path): + """ + Return path's uid. + + Does not follow symlinks: + https://github.com/pypa/pip/pull/935#discussion_r5307003 + + Placed this function in compat due to differences on AIX and + Jython, that should eventually go away. + + :raises OSError: When path is a symlink or can't be read. + """ + if hasattr(os, 'O_NOFOLLOW'): + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + file_uid = os.fstat(fd).st_uid + os.close(fd) + else: # AIX and Jython + # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW + if not os.path.islink(path): + # older versions of Jython don't have `os.fstat` + file_uid = os.stat(path).st_uid + else: + # raise OSError for parity with os.O_NOFOLLOW above + raise OSError( + "%s is a symlink; Will not return uid for symlinks" % path + ) + return file_uid + + +def expanduser(path): + """ + Expand ~ and ~user constructions. + + Includes a workaround for http://bugs.python.org/issue14768 + """ + expanded = os.path.expanduser(path) + if path.startswith('~/') and expanded.startswith('//'): + expanded = expanded[1:] + return expanded + + +# packages in the stdlib that may have installation metadata, but should not be +# considered 'installed'. this theoretically could be determined based on +# dist.location (py27:`sysconfig.get_paths()['stdlib']`, +# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may +# make this ineffective, so hard-coding +stdlib_pkgs = {"python", "wsgiref", "argparse"} + + +# windows detection, covers cpython and ironpython +WINDOWS = (sys.platform.startswith("win") or + (sys.platform == 'cli' and os.name == 'nt')) + + +def samefile(file1, file2): + """Provide an alternative for os.path.samefile on Windows/Python2""" + if hasattr(os.path, 'samefile'): + return os.path.samefile(file1, file2) + else: + path1 = os.path.normcase(os.path.abspath(file1)) + path2 = os.path.normcase(os.path.abspath(file2)) + return path1 == path2 + + +if hasattr(shutil, 'get_terminal_size'): + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + return tuple(shutil.get_terminal_size()) +else: + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + import struct + cr = struct.unpack_from( + 'hh', + fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') + ) + except: + return None + if cr == (0, 0): + return None + return cr + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: + cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) + return int(cr[1]), int(cr[0]) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/configuration.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/configuration.py new file mode 100644 index 0000000..b15e3d5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/configuration.py @@ -0,0 +1,378 @@ +"""Configuration management setup + +Some terminology: +- name + As written in config files. +- value + Value associated with a name +- key + Name combined with it's section (section.name) +- variant + A single word describing where the configuration key-value pair came from +""" + +import locale +import logging +import os + +from pip._vendor import six +from pip._vendor.six.moves import configparser + +from pip._internal.exceptions import ConfigurationError +from pip._internal.locations import ( + legacy_config_file, new_config_file, running_under_virtualenv, + site_config_files, venv_config_file, +) +from pip._internal.utils.misc import ensure_dir, enum +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterable, List, NewType, Optional, Tuple + + RawConfigParser = configparser.RawConfigParser # Shorthand + Kind = NewType("Kind", str) + +logger = logging.getLogger(__name__) + + +# NOTE: Maybe use the optionx attribute to normalize keynames. +def _normalize_name(name): + # type: (str) -> str + """Make a name consistent regardless of source (environment or file) + """ + name = name.lower().replace('_', '-') + if name.startswith('--'): + name = name[2:] # only prefer long opts + return name + + +def _disassemble_key(name): + # type: (str) -> List[str] + return name.split(".", 1) + + +# The kinds of configurations there are. +kinds = enum( + USER="user", # User Specific + GLOBAL="global", # System Wide + VENV="venv", # Virtual Environment Specific + ENV="env", # from PIP_CONFIG_FILE + ENV_VAR="env-var", # from Environment Variables +) + + +class Configuration(object): + """Handles management of configuration. + + Provides an interface to accessing and managing configuration files. + + This class converts provides an API that takes "section.key-name" style + keys and stores the value associated with it as "key-name" under the + section "section". + + This allows for a clean interface wherein the both the section and the + key-name are preserved in an easy to manage form in the configuration files + and the data stored is also nice. + """ + + def __init__(self, isolated, load_only=None): + # type: (bool, Kind) -> None + super(Configuration, self).__init__() + + _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.VENV, None] + if load_only not in _valid_load_only: + raise ConfigurationError( + "Got invalid value for load_only - should be one of {}".format( + ", ".join(map(repr, _valid_load_only[:-1])) + ) + ) + self.isolated = isolated # type: bool + self.load_only = load_only # type: Optional[Kind] + + # The order here determines the override order. + self._override_order = [ + kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR + ] + + self._ignore_env_names = ["version", "help"] + + # Because we keep track of where we got the data from + self._parsers = { + variant: [] for variant in self._override_order + } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] + self._config = { + variant: {} for variant in self._override_order + } # type: Dict[Kind, Dict[str, Any]] + self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] + + def load(self): + # type: () -> None + """Loads configuration from configuration files and environment + """ + self._load_config_files() + if not self.isolated: + self._load_environment_vars() + + def get_file_to_edit(self): + # type: () -> Optional[str] + """Returns the file with highest priority in configuration + """ + assert self.load_only is not None, \ + "Need to be specified a file to be editing" + + try: + return self._get_parser_to_modify()[0] + except IndexError: + return None + + def items(self): + # type: () -> Iterable[Tuple[str, Any]] + """Returns key-value pairs like dict.items() representing the loaded + configuration + """ + return self._dictionary.items() + + def get_value(self, key): + # type: (str) -> Any + """Get a value from the configuration. + """ + try: + return self._dictionary[key] + except KeyError: + raise ConfigurationError("No such key - {}".format(key)) + + def set_value(self, key, value): + # type: (str, Any) -> None + """Modify a value in the configuration. + """ + self._ensure_have_load_only() + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Modify the parser and the configuration + if not parser.has_section(section): + parser.add_section(section) + parser.set(section, name, value) + + self._config[self.load_only][key] = value + self._mark_as_modified(fname, parser) + + def unset_value(self, key): + # type: (str) -> None + """Unset a value in the configuration. + """ + self._ensure_have_load_only() + + if key not in self._config[self.load_only]: + raise ConfigurationError("No such key - {}".format(key)) + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Remove the key in the parser + modified_something = False + if parser.has_section(section): + # Returns whether the option was removed or not + modified_something = parser.remove_option(section, name) + + if modified_something: + # name removed from parser, section may now be empty + section_iter = iter(parser.items(section)) + try: + val = six.next(section_iter) + except StopIteration: + val = None + + if val is None: + parser.remove_section(section) + + self._mark_as_modified(fname, parser) + else: + raise ConfigurationError( + "Fatal Internal error [id=1]. Please report as a bug." + ) + + del self._config[self.load_only][key] + + def save(self): + # type: () -> None + """Save the currentin-memory state. + """ + self._ensure_have_load_only() + + for fname, parser in self._modified_parsers: + logger.info("Writing to %s", fname) + + # Ensure directory exists. + ensure_dir(os.path.dirname(fname)) + + with open(fname, "w") as f: + parser.write(f) # type: ignore + + # + # Private routines + # + + def _ensure_have_load_only(self): + # type: () -> None + if self.load_only is None: + raise ConfigurationError("Needed a specific file to be modifying.") + logger.debug("Will be working with %s variant only", self.load_only) + + @property + def _dictionary(self): + # type: () -> Dict[str, Any] + """A dictionary representing the loaded configuration. + """ + # NOTE: Dictionaries are not populated if not loaded. So, conditionals + # are not needed here. + retval = {} + + for variant in self._override_order: + retval.update(self._config[variant]) + + return retval + + def _load_config_files(self): + # type: () -> None + """Loads configuration from configuration files + """ + config_files = dict(self._iter_config_files()) + if config_files[kinds.ENV][0:1] == [os.devnull]: + logger.debug( + "Skipping loading configuration files due to " + "environment's PIP_CONFIG_FILE being os.devnull" + ) + return + + for variant, files in config_files.items(): + for fname in files: + # If there's specific variant set in `load_only`, load only + # that variant, not the others. + if self.load_only is not None and variant != self.load_only: + logger.debug( + "Skipping file '%s' (variant: %s)", fname, variant + ) + continue + + parser = self._load_file(variant, fname) + + # Keeping track of the parsers used + self._parsers[variant].append((fname, parser)) + + def _load_file(self, variant, fname): + # type: (Kind, str) -> RawConfigParser + logger.debug("For variant '%s', will try loading '%s'", variant, fname) + parser = self._construct_parser(fname) + + for section in parser.sections(): + items = parser.items(section) + self._config[variant].update(self._normalized_keys(section, items)) + + return parser + + def _construct_parser(self, fname): + # type: (str) -> RawConfigParser + parser = configparser.RawConfigParser() + # If there is no such file, don't bother reading it but create the + # parser anyway, to hold the data. + # Doing this is useful when modifying and saving files, where we don't + # need to construct a parser. + if os.path.exists(fname): + try: + parser.read(fname) + except UnicodeDecodeError: + raise ConfigurationError(( + "ERROR: " + "Configuration file contains invalid %s characters.\n" + "Please fix your configuration, located at %s\n" + ) % (locale.getpreferredencoding(False), fname)) + return parser + + def _load_environment_vars(self): + # type: () -> None + """Loads configuration from environment variables + """ + self._config[kinds.ENV_VAR].update( + self._normalized_keys(":env:", self._get_environ_vars()) + ) + + def _normalized_keys(self, section, items): + # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] + """Normalizes items to construct a dictionary with normalized keys. + + This routine is where the names become keys and are made the same + regardless of source - configuration files or environment. + """ + normalized = {} + for name, val in items: + key = section + "." + _normalize_name(name) + normalized[key] = val + return normalized + + def _get_environ_vars(self): + # type: () -> Iterable[Tuple[str, str]] + """Returns a generator with all environmental vars with prefix PIP_""" + for key, val in os.environ.items(): + should_be_yielded = ( + key.startswith("PIP_") and + key[4:].lower() not in self._ignore_env_names + ) + if should_be_yielded: + yield key[4:].lower(), val + + # XXX: This is patched in the tests. + def _iter_config_files(self): + # type: () -> Iterable[Tuple[Kind, List[str]]] + """Yields variant and configuration files associated with it. + + This should be treated like items of a dictionary. + """ + # SMELL: Move the conditions out of this function + + # environment variables have the lowest priority + config_file = os.environ.get('PIP_CONFIG_FILE', None) + if config_file is not None: + yield kinds.ENV, [config_file] + else: + yield kinds.ENV, [] + + # at the base we have any global configuration + yield kinds.GLOBAL, list(site_config_files) + + # per-user configuration next + should_load_user_config = not self.isolated and not ( + config_file and os.path.exists(config_file) + ) + if should_load_user_config: + # The legacy config file is overridden by the new config file + yield kinds.USER, [legacy_config_file, new_config_file] + + # finally virtualenv configuration first trumping others + if running_under_virtualenv(): + yield kinds.VENV, [venv_config_file] + + def _get_parser_to_modify(self): + # type: () -> Tuple[str, RawConfigParser] + # Determine which parser to modify + parsers = self._parsers[self.load_only] + if not parsers: + # This should not happen if everything works correctly. + raise ConfigurationError( + "Fatal Internal error [id=2]. Please report as a bug." + ) + + # Use the highest priority parser. + return parsers[-1] + + # XXX: This is patched in the tests. + def _mark_as_modified(self, fname, parser): + # type: (str, RawConfigParser) -> None + file_parser_tuple = (fname, parser) + if file_parser_tuple not in self._modified_parsers: + self._modified_parsers.append(file_parser_tuple) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/download.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/download.py new file mode 100644 index 0000000..06d7201 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/download.py @@ -0,0 +1,922 @@ +from __future__ import absolute_import + +import cgi +import email.utils +import getpass +import json +import logging +import mimetypes +import os +import platform +import re +import shutil +import sys + +from pip._vendor import requests, six, urllib3 +from pip._vendor.cachecontrol import CacheControlAdapter +from pip._vendor.cachecontrol.caches import FileCache +from pip._vendor.lockfile import LockError +from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter +from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response +from pip._vendor.requests.structures import CaseInsensitiveDict +from pip._vendor.requests.utils import get_netrc_auth +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request +from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote +from pip._vendor.urllib3.util import IS_PYOPENSSL + +import pip +from pip._internal.compat import WINDOWS +from pip._internal.exceptions import HashMismatch, InstallationError +from pip._internal.locations import write_delete_marker_file +from pip._internal.models import PyPI +from pip._internal.utils.encoding import auto_decode +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.glibc import libc_ver +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume, + display_path, format_size, get_installed_version, rmtree, splitext, + unpack_file, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import DownloadProgressProvider +from pip._internal.vcs import vcs + +try: + import ssl # noqa +except ImportError: + ssl = None + +HAS_TLS = (ssl is not None) or IS_PYOPENSSL + +__all__ = ['get_file_content', + 'is_url', 'url_to_path', 'path_to_url', + 'is_archive_file', 'unpack_vcs_link', + 'unpack_file_url', 'is_vcs_url', 'is_file_url', + 'unpack_http_url', 'unpack_url'] + + +logger = logging.getLogger(__name__) + + +def user_agent(): + """ + Return a string representing the user agent. + """ + data = { + "installer": {"name": "pip", "version": pip.__version__}, + "python": platform.python_version(), + "implementation": { + "name": platform.python_implementation(), + }, + } + + if data["implementation"]["name"] == 'CPython': + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'PyPy': + if sys.pypy_version_info.releaselevel == 'final': + pypy_version_info = sys.pypy_version_info[:3] + else: + pypy_version_info = sys.pypy_version_info + data["implementation"]["version"] = ".".join( + [str(x) for x in pypy_version_info] + ) + elif data["implementation"]["name"] == 'Jython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'IronPython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + + if sys.platform.startswith("linux"): + from pip._vendor import distro + distro_infos = dict(filter( + lambda x: x[1], + zip(["name", "version", "id"], distro.linux_distribution()), + )) + libc = dict(filter( + lambda x: x[1], + zip(["lib", "version"], libc_ver()), + )) + if libc: + distro_infos["libc"] = libc + if distro_infos: + data["distro"] = distro_infos + + if sys.platform.startswith("darwin") and platform.mac_ver()[0]: + data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} + + if platform.system(): + data.setdefault("system", {})["name"] = platform.system() + + if platform.release(): + data.setdefault("system", {})["release"] = platform.release() + + if platform.machine(): + data["cpu"] = platform.machine() + + if HAS_TLS: + data["openssl_version"] = ssl.OPENSSL_VERSION + + setuptools_version = get_installed_version("setuptools") + if setuptools_version is not None: + data["setuptools_version"] = setuptools_version + + return "{data[installer][name]}/{data[installer][version]} {json}".format( + data=data, + json=json.dumps(data, separators=(",", ":"), sort_keys=True), + ) + + +class MultiDomainBasicAuth(AuthBase): + + def __init__(self, prompting=True): + self.prompting = prompting + self.passwords = {} + + def __call__(self, req): + parsed = urllib_parse.urlparse(req.url) + + # Get the netloc without any embedded credentials + netloc = parsed.netloc.rsplit("@", 1)[-1] + + # Set the url of the request to the url without any credentials + req.url = urllib_parse.urlunparse(parsed[:1] + (netloc,) + parsed[2:]) + + # Use any stored credentials that we have for this netloc + username, password = self.passwords.get(netloc, (None, None)) + + # Extract credentials embedded in the url if we have none stored + if username is None: + username, password = self.parse_credentials(parsed.netloc) + + # Get creds from netrc if we still don't have them + if username is None and password is None: + netrc_auth = get_netrc_auth(req.url) + username, password = netrc_auth if netrc_auth else (None, None) + + if username or password: + # Store the username and password + self.passwords[netloc] = (username, password) + + # Send the basic auth with this request + req = HTTPBasicAuth(username or "", password or "")(req) + + # Attach a hook to handle 401 responses + req.register_hook("response", self.handle_401) + + return req + + def handle_401(self, resp, **kwargs): + # We only care about 401 responses, anything else we want to just + # pass through the actual response + if resp.status_code != 401: + return resp + + # We are not able to prompt the user so simply return the response + if not self.prompting: + return resp + + parsed = urllib_parse.urlparse(resp.url) + + # Prompt the user for a new username and password + username = six.moves.input("User for %s: " % parsed.netloc) + password = getpass.getpass("Password: ") + + # Store the new username and password to use for future requests + if username or password: + self.passwords[parsed.netloc] = (username, password) + + # Consume content and release the original connection to allow our new + # request to reuse the same one. + resp.content + resp.raw.release_conn() + + # Add our new username and password to the request + req = HTTPBasicAuth(username or "", password or "")(resp.request) + + # Send our new request + new_resp = resp.connection.send(req, **kwargs) + new_resp.history.append(resp) + + return new_resp + + def parse_credentials(self, netloc): + if "@" in netloc: + userinfo = netloc.rsplit("@", 1)[0] + if ":" in userinfo: + user, pwd = userinfo.split(":", 1) + return (urllib_unquote(user), urllib_unquote(pwd)) + return urllib_unquote(userinfo), None + return None, None + + +class LocalFSAdapter(BaseAdapter): + + def send(self, request, stream=None, timeout=None, verify=None, cert=None, + proxies=None): + pathname = url_to_path(request.url) + + resp = Response() + resp.status_code = 200 + resp.url = request.url + + try: + stats = os.stat(pathname) + except OSError as exc: + resp.status_code = 404 + resp.raw = exc + else: + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) + content_type = mimetypes.guess_type(pathname)[0] or "text/plain" + resp.headers = CaseInsensitiveDict({ + "Content-Type": content_type, + "Content-Length": stats.st_size, + "Last-Modified": modified, + }) + + resp.raw = open(pathname, "rb") + resp.close = resp.raw.close + + return resp + + def close(self): + pass + + +class SafeFileCache(FileCache): + """ + A file based cache which is safe to use even when the target directory may + not be accessible or writable. + """ + + def __init__(self, *args, **kwargs): + super(SafeFileCache, self).__init__(*args, **kwargs) + + # Check to ensure that the directory containing our cache directory + # is owned by the user current executing pip. If it does not exist + # we will check the parent directory until we find one that does exist. + # If it is not owned by the user executing pip then we will disable + # the cache and log a warning. + if not check_path_owner(self.directory): + logger.warning( + "The directory '%s' or its parent directory is not owned by " + "the current user and the cache has been disabled. Please " + "check the permissions and owner of that directory. If " + "executing pip with sudo, you may want sudo's -H flag.", + self.directory, + ) + + # Set our directory to None to disable the Cache + self.directory = None + + def get(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).get(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def set(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).set(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def delete(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).delete(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + +class InsecureHTTPAdapter(HTTPAdapter): + + def cert_verify(self, conn, url, verify, cert): + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + + +class PipSession(requests.Session): + + timeout = None + + def __init__(self, *args, **kwargs): + retries = kwargs.pop("retries", 0) + cache = kwargs.pop("cache", None) + insecure_hosts = kwargs.pop("insecure_hosts", []) + + super(PipSession, self).__init__(*args, **kwargs) + + # Attach our User Agent to the request + self.headers["User-Agent"] = user_agent() + + # Attach our Authentication handler to the session + self.auth = MultiDomainBasicAuth() + + # Create our urllib3.Retry instance which will allow us to customize + # how we handle retries. + retries = urllib3.Retry( + # Set the total number of retries that a particular request can + # have. + total=retries, + + # A 503 error from PyPI typically means that the Fastly -> Origin + # connection got interrupted in some way. A 503 error in general + # is typically considered a transient error so we'll go ahead and + # retry it. + # A 500 may indicate transient error in Amazon S3 + # A 520 or 527 - may indicate transient error in CloudFlare + status_forcelist=[500, 503, 520, 527], + + # Add a small amount of back off between failed requests in + # order to prevent hammering the service. + backoff_factor=0.25, + ) + + # We want to _only_ cache responses on securely fetched origins. We do + # this because we can't validate the response of an insecurely fetched + # origin, and we don't want someone to be able to poison the cache and + # require manual eviction from the cache to fix it. + if cache: + secure_adapter = CacheControlAdapter( + cache=SafeFileCache(cache, use_dir_lock=True), + max_retries=retries, + ) + else: + secure_adapter = HTTPAdapter(max_retries=retries) + + # Our Insecure HTTPAdapter disables HTTPS validation. It does not + # support caching (see above) so we'll use it for all http:// URLs as + # well as any https:// host that we've marked as ignoring TLS errors + # for. + insecure_adapter = InsecureHTTPAdapter(max_retries=retries) + + self.mount("https://", secure_adapter) + self.mount("http://", insecure_adapter) + + # Enable file:// urls + self.mount("file://", LocalFSAdapter()) + + # We want to use a non-validating adapter for any requests which are + # deemed insecure. + for host in insecure_hosts: + self.mount("https://{}/".format(host), insecure_adapter) + + def request(self, method, url, *args, **kwargs): + # Allow setting a default timeout on a session + kwargs.setdefault("timeout", self.timeout) + + # Dispatch the actual request + return super(PipSession, self).request(method, url, *args, **kwargs) + + +def get_file_content(url, comes_from=None, session=None): + """Gets the content of a file; it may be a filename, file: URL, or + http: URL. Returns (location, content). Content is unicode. + + :param url: File path or url. + :param comes_from: Origin description of requirements. + :param session: Instance of pip.download.PipSession. + """ + if session is None: + raise TypeError( + "get_file_content() missing 1 required keyword argument: 'session'" + ) + + match = _scheme_re.search(url) + if match: + scheme = match.group(1).lower() + if (scheme == 'file' and comes_from and + comes_from.startswith('http')): + raise InstallationError( + 'Requirements file %s references URL %s, which is local' + % (comes_from, url)) + if scheme == 'file': + path = url.split(':', 1)[1] + path = path.replace('\\', '/') + match = _url_slash_drive_re.match(path) + if match: + path = match.group(1) + ':' + path.split('|', 1)[1] + path = urllib_parse.unquote(path) + if path.startswith('/'): + path = '/' + path.lstrip('/') + url = path + else: + # FIXME: catch some errors + resp = session.get(url) + resp.raise_for_status() + return resp.url, resp.text + try: + with open(url, 'rb') as f: + content = auto_decode(f.read()) + except IOError as exc: + raise InstallationError( + 'Could not open requirements file: %s' % str(exc) + ) + return url, content + + +_scheme_re = re.compile(r'^(http|https|file):', re.I) +_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) + + +def is_url(name): + """Returns true if the name looks like a URL""" + if ':' not in name: + return False + scheme = name.split(':', 1)[0].lower() + return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes + + +def url_to_path(url): + """ + Convert a file: URL to a path. + """ + assert url.startswith('file:'), ( + "You can only turn file: urls into filenames (not %r)" % url) + + _, netloc, path, _, _ = urllib_parse.urlsplit(url) + + # if we have a UNC path, prepend UNC share notation + if netloc: + netloc = '\\\\' + netloc + + path = urllib_request.url2pathname(netloc + path) + return path + + +def path_to_url(path): + """ + Convert a path to a file: URL. The path will be made absolute and have + quoted path parts. + """ + path = os.path.normpath(os.path.abspath(path)) + url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) + return url + + +def is_archive_file(name): + """Return True if `name` is a considered as an archive file.""" + ext = splitext(name)[1].lower() + if ext in ARCHIVE_EXTENSIONS: + return True + return False + + +def unpack_vcs_link(link, location): + vcs_backend = _get_used_vcs_backend(link) + vcs_backend.unpack(location) + + +def _get_used_vcs_backend(link): + for backend in vcs.backends: + if link.scheme in backend.schemes: + vcs_backend = backend(link.url) + return vcs_backend + + +def is_vcs_url(link): + return bool(_get_used_vcs_backend(link)) + + +def is_file_url(link): + return link.url.lower().startswith('file:') + + +def is_dir_url(link): + """Return whether a file:// Link points to a directory. + + ``link`` must not have any other scheme but file://. Call is_file_url() + first. + + """ + link_path = url_to_path(link.url_without_fragment) + return os.path.isdir(link_path) + + +def _progress_indicator(iterable, *args, **kwargs): + return iterable + + +def _download_url(resp, link, content_file, hashes, progress_bar): + try: + total_length = int(resp.headers['content-length']) + except (ValueError, KeyError, TypeError): + total_length = 0 + + cached_resp = getattr(resp, "from_cache", False) + if logger.getEffectiveLevel() > logging.INFO: + show_progress = False + elif cached_resp: + show_progress = False + elif total_length > (40 * 1000): + show_progress = True + elif not total_length: + show_progress = True + else: + show_progress = False + + show_url = link.show_url + + def resp_read(chunk_size): + try: + # Special case for urllib3. + for chunk in resp.raw.stream( + chunk_size, + # We use decode_content=False here because we don't + # want urllib3 to mess with the raw bytes we get + # from the server. If we decompress inside of + # urllib3 then we cannot verify the checksum + # because the checksum will be of the compressed + # file. This breakage will only occur if the + # server adds a Content-Encoding header, which + # depends on how the server was configured: + # - Some servers will notice that the file isn't a + # compressible file and will leave the file alone + # and with an empty Content-Encoding + # - Some servers will notice that the file is + # already compressed and will leave the file + # alone and will add a Content-Encoding: gzip + # header + # - Some servers won't notice anything at all and + # will take a file that's already been compressed + # and compress it again and set the + # Content-Encoding: gzip header + # + # By setting this not to decode automatically we + # hope to eliminate problems with the second case. + decode_content=False): + yield chunk + except AttributeError: + # Standard file-like object. + while True: + chunk = resp.raw.read(chunk_size) + if not chunk: + break + yield chunk + + def written_chunks(chunks): + for chunk in chunks: + content_file.write(chunk) + yield chunk + + progress_indicator = _progress_indicator + + if link.netloc == PyPI.netloc: + url = show_url + else: + url = link.url_without_fragment + + if show_progress: # We don't show progress on cached responses + progress_indicator = DownloadProgressProvider(progress_bar, + max=total_length) + if total_length: + logger.info("Downloading %s (%s)", url, format_size(total_length)) + else: + logger.info("Downloading %s", url) + elif cached_resp: + logger.info("Using cached %s", url) + else: + logger.info("Downloading %s", url) + + logger.debug('Downloading from URL %s', link) + + downloaded_chunks = written_chunks( + progress_indicator( + resp_read(CONTENT_CHUNK_SIZE), + CONTENT_CHUNK_SIZE + ) + ) + if hashes: + hashes.check_against_chunks(downloaded_chunks) + else: + consume(downloaded_chunks) + + +def _copy_file(filename, location, link): + copy = True + download_location = os.path.join(location, link.filename) + if os.path.exists(download_location): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' % + display_path(download_location), ('i', 'w', 'b', 'a')) + if response == 'i': + copy = False + elif response == 'w': + logger.warning('Deleting %s', display_path(download_location)) + os.remove(download_location) + elif response == 'b': + dest_file = backup_dir(download_location) + logger.warning( + 'Backing up %s to %s', + display_path(download_location), + display_path(dest_file), + ) + shutil.move(download_location, dest_file) + elif response == 'a': + sys.exit(-1) + if copy: + shutil.copy(filename, download_location) + logger.info('Saved %s', display_path(download_location)) + + +def unpack_http_url(link, location, download_dir=None, + session=None, hashes=None, progress_bar="on"): + if session is None: + raise TypeError( + "unpack_http_url() missing 1 required keyword argument: 'session'" + ) + + with TempDirectory(kind="unpack") as temp_dir: + # If a download dir is specified, is the file already downloaded there? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + content_type = mimetypes.guess_type(from_path)[0] + else: + # let's download to a tmp dir + from_path, content_type = _download_http_url(link, + session, + temp_dir.path, + hashes, + progress_bar) + + # unpack the archive to the build dir location. even when only + # downloading archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified; let's copy the archive there + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + if not already_downloaded_path: + os.unlink(from_path) + + +def unpack_file_url(link, location, download_dir=None, hashes=None): + """Unpack link into location. + + If download_dir is provided and link points to a file, make a copy + of the link file inside download_dir. + """ + link_path = url_to_path(link.url_without_fragment) + + # If it's a url to a local directory + if is_dir_url(link): + if os.path.isdir(location): + rmtree(location) + shutil.copytree(link_path, location, symlinks=True) + if download_dir: + logger.info('Link is a directory, ignoring download_dir') + return + + # If --require-hashes is off, `hashes` is either empty, the + # link's embedded hash, or MissingHashes; it is required to + # match. If --require-hashes is on, we are satisfied by any + # hash in `hashes` matching: a URL-based or an option-based + # one; no internet-sourced hash will be in `hashes`. + if hashes: + hashes.check_against_path(link_path) + + # If a download dir is specified, is the file already there and valid? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + else: + from_path = link_path + + content_type = mimetypes.guess_type(from_path)[0] + + # unpack the archive to the build dir location. even when only downloading + # archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified and not already downloaded + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + +def _copy_dist_from_dir(link_path, location): + """Copy distribution files in `link_path` to `location`. + + Invoked when user requests to install a local directory. E.g.: + + pip install . + pip install ~/dev/git-repos/python-prompt-toolkit + + """ + + # Note: This is currently VERY SLOW if you have a lot of data in the + # directory, because it copies everything with `shutil.copytree`. + # What it should really do is build an sdist and install that. + # See https://github.com/pypa/pip/issues/2195 + + if os.path.isdir(location): + rmtree(location) + + # build an sdist + setup_py = 'setup.py' + sdist_args = [sys.executable] + sdist_args.append('-c') + sdist_args.append(SETUPTOOLS_SHIM % setup_py) + sdist_args.append('sdist') + sdist_args += ['--dist-dir', location] + logger.info('Running setup.py sdist for %s', link_path) + + with indent_log(): + call_subprocess(sdist_args, cwd=link_path, show_stdout=False) + + # unpack sdist into `location` + sdist = os.path.join(location, os.listdir(location)[0]) + logger.info('Unpacking sdist %s into %s', sdist, location) + unpack_file(sdist, location, content_type=None, link=None) + + +class PipXmlrpcTransport(xmlrpc_client.Transport): + """Provide a `xmlrpclib.Transport` implementation via a `PipSession` + object. + """ + + def __init__(self, index_url, session, use_datetime=False): + xmlrpc_client.Transport.__init__(self, use_datetime) + index_parts = urllib_parse.urlparse(index_url) + self._scheme = index_parts.scheme + self._session = session + + def request(self, host, handler, request_body, verbose=False): + parts = (self._scheme, host, handler, None, None, None) + url = urllib_parse.urlunparse(parts) + try: + headers = {'Content-Type': 'text/xml'} + response = self._session.post(url, data=request_body, + headers=headers, stream=True) + response.raise_for_status() + self.verbose = verbose + return self.parse_response(response.raw) + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", + exc.response.status_code, url, + ) + raise + + +def unpack_url(link, location, download_dir=None, + only_download=False, session=None, hashes=None, + progress_bar="on"): + """Unpack link. + If link is a VCS link: + if only_download, export into download_dir and ignore location + else unpack into location + for other types of link: + - unpack into location + - if download_dir, copy the file into download_dir + - if only_download, mark location for deletion + + :param hashes: A Hashes object, one of whose embedded hashes must match, + or HashMismatch will be raised. If the Hashes is empty, no matches are + required, and unhashable types of requirements (like VCS ones, which + would ordinarily raise HashUnsupported) are allowed. + """ + # non-editable vcs urls + if is_vcs_url(link): + unpack_vcs_link(link, location) + + # file urls + elif is_file_url(link): + unpack_file_url(link, location, download_dir, hashes=hashes) + + # http urls + else: + if session is None: + session = PipSession() + + unpack_http_url( + link, + location, + download_dir, + session, + hashes=hashes, + progress_bar=progress_bar + ) + if only_download: + write_delete_marker_file(location) + + +def _download_http_url(link, session, temp_dir, hashes, progress_bar): + """Download link url into temp_dir using provided session""" + target_url = link.url.split('#', 1)[0] + try: + resp = session.get( + target_url, + # We use Accept-Encoding: identity here because requests + # defaults to accepting compressed responses. This breaks in + # a variety of ways depending on how the server is configured. + # - Some servers will notice that the file isn't a compressible + # file and will leave the file alone and with an empty + # Content-Encoding + # - Some servers will notice that the file is already + # compressed and will leave the file alone and will add a + # Content-Encoding: gzip header + # - Some servers won't notice anything at all and will take + # a file that's already been compressed and compress it again + # and set the Content-Encoding: gzip header + # By setting this to request only the identity encoding We're + # hoping to eliminate the third case. Hopefully there does not + # exist a server which when given a file will notice it is + # already compressed and that you're not asking for a + # compressed file and will then decompress it before sending + # because if that's the case I don't think it'll ever be + # possible to make this work. + headers={"Accept-Encoding": "identity"}, + stream=True, + ) + resp.raise_for_status() + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", exc.response.status_code, link, + ) + raise + + content_type = resp.headers.get('content-type', '') + filename = link.filename # fallback + # Have a look at the Content-Disposition header for a better guess + content_disposition = resp.headers.get('content-disposition') + if content_disposition: + type, params = cgi.parse_header(content_disposition) + # We use ``or`` here because we don't want to use an "empty" value + # from the filename param. + filename = params.get('filename') or filename + ext = splitext(filename)[1] + if not ext: + ext = mimetypes.guess_extension(content_type) + if ext: + filename += ext + if not ext and link.url != resp.url: + ext = os.path.splitext(resp.url)[1] + if ext: + filename += ext + file_path = os.path.join(temp_dir, filename) + with open(file_path, 'wb') as content_file: + _download_url(resp, link, content_file, hashes, progress_bar) + return file_path, content_type + + +def _check_download_dir(link, download_dir, hashes): + """ Check download_dir for previously downloaded file with correct hash + If a correct file is found return its path else None + """ + download_path = os.path.join(download_dir, link.filename) + if os.path.exists(download_path): + # If already downloaded, does its hash match? + logger.info('File was already downloaded %s', download_path) + if hashes: + try: + hashes.check_against_path(download_path) + except HashMismatch: + logger.warning( + 'Previously-downloaded file %s has bad hash. ' + 'Re-downloading.', + download_path + ) + os.unlink(download_path) + return None + return download_path + return None diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/exceptions.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/exceptions.py new file mode 100644 index 0000000..ad6f412 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/exceptions.py @@ -0,0 +1,249 @@ +"""Exceptions used throughout package""" +from __future__ import absolute_import + +from itertools import chain, groupby, repeat + +from pip._vendor.six import iteritems + + +class PipError(Exception): + """Base pip exception""" + + +class ConfigurationError(PipError): + """General exception in configuration""" + + +class InstallationError(PipError): + """General exception during installation""" + + +class UninstallationError(PipError): + """General exception during uninstallation""" + + +class DistributionNotFound(InstallationError): + """Raised when a distribution cannot be found to satisfy a requirement""" + + +class RequirementsFileParseError(InstallationError): + """Raised when a general error occurs parsing a requirements file line.""" + + +class BestVersionAlreadyInstalled(PipError): + """Raised when the most up-to-date version of a package is already + installed.""" + + +class BadCommand(PipError): + """Raised when virtualenv or a command is not found""" + + +class CommandError(PipError): + """Raised when there is an error in command-line arguments""" + + +class PreviousBuildDirError(PipError): + """Raised when there's a previous conflicting build directory""" + + +class InvalidWheelFilename(InstallationError): + """Invalid wheel filename.""" + + +class UnsupportedWheel(InstallationError): + """Unsupported wheel.""" + + +class HashErrors(InstallationError): + """Multiple HashError instances rolled into one for reporting""" + + def __init__(self): + self.errors = [] + + def append(self, error): + self.errors.append(error) + + def __str__(self): + lines = [] + self.errors.sort(key=lambda e: e.order) + for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): + lines.append(cls.head) + lines.extend(e.body() for e in errors_of_cls) + if lines: + return '\n'.join(lines) + + def __nonzero__(self): + return bool(self.errors) + + def __bool__(self): + return self.__nonzero__() + + +class HashError(InstallationError): + """ + A failure to verify a package against known-good hashes + + :cvar order: An int sorting hash exception classes by difficulty of + recovery (lower being harder), so the user doesn't bother fretting + about unpinned packages when he has deeper issues, like VCS + dependencies, to deal with. Also keeps error reports in a + deterministic order. + :cvar head: A section heading for display above potentially many + exceptions of this kind + :ivar req: The InstallRequirement that triggered this error. This is + pasted on after the exception is instantiated, because it's not + typically available earlier. + + """ + req = None + head = '' + + def body(self): + """Return a summary of me for display under the heading. + + This default implementation simply prints a description of the + triggering requirement. + + :param req: The InstallRequirement that provoked this error, with + populate_link() having already been called + + """ + return ' %s' % self._requirement_name() + + def __str__(self): + return '%s\n%s' % (self.head, self.body()) + + def _requirement_name(self): + """Return a description of the requirement that triggered me. + + This default implementation returns long description of the req, with + line numbers + + """ + return str(self.req) if self.req else 'unknown package' + + +class VcsHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 0 + head = ("Can't verify hashes for these requirements because we don't " + "have a way to hash version control repositories:") + + +class DirectoryUrlHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 1 + head = ("Can't verify hashes for these file:// requirements because they " + "point to directories:") + + +class HashMissing(HashError): + """A hash was needed for a requirement but is absent.""" + + order = 2 + head = ('Hashes are required in --require-hashes mode, but they are ' + 'missing from some requirements. Here is a list of those ' + 'requirements along with the hashes their downloaded archives ' + 'actually had. Add lines like these to your requirements files to ' + 'prevent tampering. (If you did not enable --require-hashes ' + 'manually, note that it turns on automatically when any package ' + 'has a hash.)') + + def __init__(self, gotten_hash): + """ + :param gotten_hash: The hash of the (possibly malicious) archive we + just downloaded + """ + self.gotten_hash = gotten_hash + + def body(self): + # Dodge circular import. + from pip._internal.utils.hashes import FAVORITE_HASH + + package = None + if self.req: + # In the case of URL-based requirements, display the original URL + # seen in the requirements file rather than the package name, + # so the output can be directly copied into the requirements file. + package = (self.req.original_link if self.req.original_link + # In case someone feeds something downright stupid + # to InstallRequirement's constructor. + else getattr(self.req, 'req', None)) + return ' %s --hash=%s:%s' % (package or 'unknown package', + FAVORITE_HASH, + self.gotten_hash) + + +class HashUnpinned(HashError): + """A requirement had a hash specified but was not pinned to a specific + version.""" + + order = 3 + head = ('In --require-hashes mode, all requirements must have their ' + 'versions pinned with ==. These do not:') + + +class HashMismatch(HashError): + """ + Distribution file hash values don't match. + + :ivar package_name: The name of the package that triggered the hash + mismatch. Feel free to write to this after the exception is raise to + improve its error message. + + """ + order = 4 + head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' + 'FILE. If you have updated the package versions, please update ' + 'the hashes. Otherwise, examine the package contents carefully; ' + 'someone may have tampered with them.') + + def __init__(self, allowed, gots): + """ + :param allowed: A dict of algorithm names pointing to lists of allowed + hex digests + :param gots: A dict of algorithm names pointing to hashes we + actually got from the files under suspicion + """ + self.allowed = allowed + self.gots = gots + + def body(self): + return ' %s:\n%s' % (self._requirement_name(), + self._hash_comparison()) + + def _hash_comparison(self): + """ + Return a comparison of actual and expected hash values. + + Example:: + + Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde + or 123451234512345123451234512345123451234512345 + Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef + + """ + def hash_then_or(hash_name): + # For now, all the decent hashes have 6-char names, so we can get + # away with hard-coding space literals. + return chain([hash_name], repeat(' or')) + + lines = [] + for hash_name, expecteds in iteritems(self.allowed): + prefix = hash_then_or(hash_name) + lines.extend((' Expected %s %s' % (next(prefix), e)) + for e in expecteds) + lines.append(' Got %s\n' % + self.gots[hash_name].hexdigest()) + prefix = ' or' + return '\n'.join(lines) + + +class UnsupportedPythonVersion(InstallationError): + """Unsupported python version according to Requires-Python package + metadata.""" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/index.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/index.py new file mode 100644 index 0000000..3c3a92b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/index.py @@ -0,0 +1,1117 @@ +"""Routines related to PyPI, indexes""" +from __future__ import absolute_import + +import cgi +import itertools +import logging +import mimetypes +import os +import posixpath +import re +import sys +import warnings +from collections import namedtuple + +from pip._vendor import html5lib, requests, six +from pip._vendor.distlib.compat import unescape +from pip._vendor.packaging import specifiers +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.requests.exceptions import SSLError +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.compat import ipaddress +from pip._internal.download import HAS_TLS, is_url, path_to_url, url_to_path +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, + UnsupportedWheel, +) +from pip._internal.models import PyPI +from pip._internal.pep425tags import get_supported +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, cached_property, normalize_path, + splitext, +) +from pip._internal.utils.packaging import check_requires_python +from pip._internal.wheel import Wheel, wheel_ext + +__all__ = ['FormatControl', 'fmt_ctl_handle_mutual_exclude', 'PackageFinder'] + + +SECURE_ORIGINS = [ + # protocol, hostname, port + # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) + ("https", "*", "*"), + ("*", "localhost", "*"), + ("*", "127.0.0.0/8", "*"), + ("*", "::1/128", "*"), + ("file", "*", None), + # ssh is always secure. + ("ssh", "*", "*"), +] + + +logger = logging.getLogger(__name__) + + +class InstallationCandidate(object): + + def __init__(self, project, version, location): + self.project = project + self.version = parse_version(version) + self.location = location + self._key = (self.project, self.version, self.location) + + def __repr__(self): + return "".format( + self.project, self.version, self.location, + ) + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, InstallationCandidate): + return NotImplemented + + return method(self._key, other._key) + + +class PackageFinder(object): + """This finds packages. + + This is meant to match easy_install's technique for looking for + packages, by reading pages and looking for appropriate links. + """ + + def __init__(self, find_links, index_urls, allow_all_prereleases=False, + trusted_hosts=None, process_dependency_links=False, + session=None, format_control=None, platform=None, + versions=None, abi=None, implementation=None): + """Create a PackageFinder. + + :param format_control: A FormatControl object or None. Used to control + the selection of source packages / binary packages when consulting + the index and links. + :param platform: A string or None. If None, searches for packages + that are supported by the current system. Otherwise, will find + packages that can be built on the platform passed in. These + packages will only be downloaded for distribution: they will + not be built locally. + :param versions: A list of strings or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param abi: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param implementation: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + """ + if session is None: + raise TypeError( + "PackageFinder() missing 1 required keyword argument: " + "'session'" + ) + + # Build find_links. If an argument starts with ~, it may be + # a local file relative to a home directory. So try normalizing + # it and if it exists, use the normalized version. + # This is deliberately conservative - it might be fine just to + # blindly normalize anything starting with a ~... + self.find_links = [] + for link in find_links: + if link.startswith('~'): + new_link = normalize_path(link) + if os.path.exists(new_link): + link = new_link + self.find_links.append(link) + + self.index_urls = index_urls + self.dependency_links = [] + + # These are boring links that have already been logged somehow: + self.logged_links = set() + + self.format_control = format_control or FormatControl(set(), set()) + + # Domains that we won't emit warnings for when not using HTTPS + self.secure_origins = [ + ("*", host, "*") + for host in (trusted_hosts if trusted_hosts else []) + ] + + # Do we want to allow _all_ pre-releases? + self.allow_all_prereleases = allow_all_prereleases + + # Do we process dependency links? + self.process_dependency_links = process_dependency_links + + # The Session we'll use to make requests + self.session = session + + # The valid tags to check potential found wheel candidates against + self.valid_tags = get_supported( + versions=versions, + platform=platform, + abi=abi, + impl=implementation, + ) + + # If we don't have TLS enabled, then WARN if anyplace we're looking + # relies on TLS. + if not HAS_TLS: + for link in itertools.chain(self.index_urls, self.find_links): + parsed = urllib_parse.urlparse(link) + if parsed.scheme == "https": + logger.warning( + "pip is configured with locations that require " + "TLS/SSL, however the ssl module in Python is not " + "available." + ) + break + + def get_formatted_locations(self): + lines = [] + if self.index_urls and self.index_urls != [PyPI.simple_url]: + lines.append( + "Looking in indexes: {}".format(", ".join(self.index_urls)) + ) + if self.find_links: + lines.append( + "Looking in links: {}".format(", ".join(self.find_links)) + ) + return "\n".join(lines) + + def add_dependency_links(self, links): + # # FIXME: this shouldn't be global list this, it should only + # # apply to requirements of the package that specifies the + # # dependency_links value + # # FIXME: also, we should track comes_from (i.e., use Link) + if self.process_dependency_links: + warnings.warn( + "Dependency Links processing has been deprecated and will be " + "removed in a future release.", + RemovedInPip11Warning, + ) + self.dependency_links.extend(links) + + @staticmethod + def _sort_locations(locations, expand_dir=False): + """ + Sort locations into "files" (archives) and "urls", and return + a pair of lists (files,urls) + """ + files = [] + urls = [] + + # puts the url for the given file path into the appropriate list + def sort_path(path): + url = path_to_url(path) + if mimetypes.guess_type(url, strict=False)[0] == 'text/html': + urls.append(url) + else: + files.append(url) + + for url in locations: + + is_local_path = os.path.exists(url) + is_file_url = url.startswith('file:') + + if is_local_path or is_file_url: + if is_local_path: + path = url + else: + path = url_to_path(url) + if os.path.isdir(path): + if expand_dir: + path = os.path.realpath(path) + for item in os.listdir(path): + sort_path(os.path.join(path, item)) + elif is_file_url: + urls.append(url) + elif os.path.isfile(path): + sort_path(path) + else: + logger.warning( + "Url '%s' is ignored: it is neither a file " + "nor a directory.", url, + ) + elif is_url(url): + # Only add url with clear scheme + urls.append(url) + else: + logger.warning( + "Url '%s' is ignored. It is either a non-existing " + "path or lacks a specific scheme.", url, + ) + + return files, urls + + def _candidate_sort_key(self, candidate): + """ + Function used to generate link sort key for link tuples. + The greater the return value, the more preferred it is. + If not finding wheels, then sorted by version only. + If finding wheels, then the sort order is by version, then: + 1. existing installs + 2. wheels ordered via Wheel.support_index_min(self.valid_tags) + 3. source archives + Note: it was considered to embed this logic into the Link + comparison operators, but then different sdist links + with the same version, would have to be considered equal + """ + support_num = len(self.valid_tags) + build_tag = tuple() + if candidate.location.is_wheel: + # can raise InvalidWheelFilename + wheel = Wheel(candidate.location.filename) + if not wheel.supported(self.valid_tags): + raise UnsupportedWheel( + "%s is not a supported wheel for this platform. It " + "can't be sorted." % wheel.filename + ) + pri = -(wheel.support_index_min(self.valid_tags)) + if wheel.build_tag is not None: + match = re.match(r'^(\d+)(.*)$', wheel.build_tag) + build_tag_groups = match.groups() + build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) + else: # sdist + pri = -(support_num) + return (candidate.version, build_tag, pri) + + def _validate_secure_origin(self, logger, location): + # Determine if this url used a secure transport mechanism + parsed = urllib_parse.urlparse(str(location)) + origin = (parsed.scheme, parsed.hostname, parsed.port) + + # The protocol to use to see if the protocol matches. + # Don't count the repository type as part of the protocol: in + # cases such as "git+ssh", only use "ssh". (I.e., Only verify against + # the last scheme.) + protocol = origin[0].rsplit('+', 1)[-1] + + # Determine if our origin is a secure origin by looking through our + # hardcoded list of secure origins, as well as any additional ones + # configured on this PackageFinder instance. + for secure_origin in (SECURE_ORIGINS + self.secure_origins): + if protocol != secure_origin[0] and secure_origin[0] != "*": + continue + + try: + # We need to do this decode dance to ensure that we have a + # unicode object, even on Python 2.x. + addr = ipaddress.ip_address( + origin[1] + if ( + isinstance(origin[1], six.text_type) or + origin[1] is None + ) + else origin[1].decode("utf8") + ) + network = ipaddress.ip_network( + secure_origin[1] + if isinstance(secure_origin[1], six.text_type) + else secure_origin[1].decode("utf8") + ) + except ValueError: + # We don't have both a valid address or a valid network, so + # we'll check this origin against hostnames. + if (origin[1] and + origin[1].lower() != secure_origin[1].lower() and + secure_origin[1] != "*"): + continue + else: + # We have a valid address and network, so see if the address + # is contained within the network. + if addr not in network: + continue + + # Check to see if the port patches + if (origin[2] != secure_origin[2] and + secure_origin[2] != "*" and + secure_origin[2] is not None): + continue + + # If we've gotten here, then this origin matches the current + # secure origin and we should return True + return True + + # If we've gotten to this point, then the origin isn't secure and we + # will not accept it as a valid location to search. We will however + # log a warning that we are ignoring it. + logger.warning( + "The repository located at %s is not a trusted or secure host and " + "is being ignored. If this repository is available via HTTPS we " + "recommend you use HTTPS instead, otherwise you may silence " + "this warning and allow it anyway with '--trusted-host %s'.", + parsed.hostname, + parsed.hostname, + ) + + return False + + def _get_index_urls_locations(self, project_name): + """Returns the locations found via self.index_urls + + Checks the url_name on the main (first in the list) index and + use this url_name to produce all locations + """ + + def mkurl_pypi_url(url): + loc = posixpath.join( + url, + urllib_parse.quote(canonicalize_name(project_name))) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's + # behavior. + if not loc.endswith('/'): + loc = loc + '/' + return loc + + return [mkurl_pypi_url(url) for url in self.index_urls] + + def find_all_candidates(self, project_name): + """Find all available InstallationCandidate for project_name + + This checks index_urls, find_links and dependency_links. + All versions found are returned as an InstallationCandidate list. + + See _link_package_versions for details on which files are accepted + """ + index_locations = self._get_index_urls_locations(project_name) + index_file_loc, index_url_loc = self._sort_locations(index_locations) + fl_file_loc, fl_url_loc = self._sort_locations( + self.find_links, expand_dir=True, + ) + dep_file_loc, dep_url_loc = self._sort_locations(self.dependency_links) + + file_locations = (Link(url) for url in itertools.chain( + index_file_loc, fl_file_loc, dep_file_loc, + )) + + # We trust every url that the user has given us whether it was given + # via --index-url or --find-links + # We explicitly do not trust links that came from dependency_links + # We want to filter out any thing which does not have a secure origin. + url_locations = [ + link for link in itertools.chain( + (Link(url) for url in index_url_loc), + (Link(url) for url in fl_url_loc), + (Link(url) for url in dep_url_loc), + ) + if self._validate_secure_origin(logger, link) + ] + + logger.debug('%d location(s) to search for versions of %s:', + len(url_locations), project_name) + + for location in url_locations: + logger.debug('* %s', location) + + canonical_name = canonicalize_name(project_name) + formats = fmt_ctl_formats(self.format_control, canonical_name) + search = Search(project_name, canonical_name, formats) + find_links_versions = self._package_versions( + # We trust every directly linked archive in find_links + (Link(url, '-f') for url in self.find_links), + search + ) + + page_versions = [] + for page in self._get_pages(url_locations, project_name): + logger.debug('Analyzing links from page %s', page.url) + with indent_log(): + page_versions.extend( + self._package_versions(page.links, search) + ) + + dependency_versions = self._package_versions( + (Link(url) for url in self.dependency_links), search + ) + if dependency_versions: + logger.debug( + 'dependency_links found: %s', + ', '.join([ + version.location.url for version in dependency_versions + ]) + ) + + file_versions = self._package_versions(file_locations, search) + if file_versions: + file_versions.sort(reverse=True) + logger.debug( + 'Local files found: %s', + ', '.join([ + url_to_path(candidate.location.url) + for candidate in file_versions + ]) + ) + + # This is an intentional priority ordering + return ( + file_versions + find_links_versions + page_versions + + dependency_versions + ) + + def find_requirement(self, req, upgrade): + """Try to find a Link matching req + + Expects req, an InstallRequirement and upgrade, a boolean + Returns a Link if found, + Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise + """ + all_candidates = self.find_all_candidates(req.name) + + # Filter out anything which doesn't match our specifier + compatible_versions = set( + req.specifier.filter( + # We turn the version object into a str here because otherwise + # when we're debundled but setuptools isn't, Python will see + # packaging.version.Version and + # pkg_resources._vendor.packaging.version.Version as different + # types. This way we'll use a str as a common data interchange + # format. If we stop using the pkg_resources provided specifier + # and start using our own, we can drop the cast to str(). + [str(c.version) for c in all_candidates], + prereleases=( + self.allow_all_prereleases + if self.allow_all_prereleases else None + ), + ) + ) + applicable_candidates = [ + # Again, converting to str to deal with debundling. + c for c in all_candidates if str(c.version) in compatible_versions + ] + + if applicable_candidates: + best_candidate = max(applicable_candidates, + key=self._candidate_sort_key) + else: + best_candidate = None + + if req.satisfied_by is not None: + installed_version = parse_version(req.satisfied_by.version) + else: + installed_version = None + + if installed_version is None and best_candidate is None: + logger.critical( + 'Could not find a version that satisfies the requirement %s ' + '(from versions: %s)', + req, + ', '.join( + sorted( + {str(c.version) for c in all_candidates}, + key=parse_version, + ) + ) + ) + + raise DistributionNotFound( + 'No matching distribution found for %s' % req + ) + + best_installed = False + if installed_version and ( + best_candidate is None or + best_candidate.version <= installed_version): + best_installed = True + + if not upgrade and installed_version is not None: + if best_installed: + logger.debug( + 'Existing installed version (%s) is most up-to-date and ' + 'satisfies requirement', + installed_version, + ) + else: + logger.debug( + 'Existing installed version (%s) satisfies requirement ' + '(most up-to-date version is %s)', + installed_version, + best_candidate.version, + ) + return None + + if best_installed: + # We have an existing version, and its the best version + logger.debug( + 'Installed version (%s) is most up-to-date (past versions: ' + '%s)', + installed_version, + ', '.join(sorted(compatible_versions, key=parse_version)) or + "none", + ) + raise BestVersionAlreadyInstalled + + logger.debug( + 'Using version %s (newest of versions: %s)', + best_candidate.version, + ', '.join(sorted(compatible_versions, key=parse_version)) + ) + return best_candidate.location + + def _get_pages(self, locations, project_name): + """ + Yields (page, page_url) from the given locations, skipping + locations that have errors. + """ + seen = set() + for location in locations: + if location in seen: + continue + seen.add(location) + + page = self._get_page(location) + if page is None: + continue + + yield page + + _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') + + def _sort_links(self, links): + """ + Returns elements of links in order, non-egg links first, egg links + second, while eliminating duplicates + """ + eggs, no_eggs = [], [] + seen = set() + for link in links: + if link not in seen: + seen.add(link) + if link.egg_fragment: + eggs.append(link) + else: + no_eggs.append(link) + return no_eggs + eggs + + def _package_versions(self, links, search): + result = [] + for link in self._sort_links(links): + v = self._link_package_versions(link, search) + if v is not None: + result.append(v) + return result + + def _log_skipped_link(self, link, reason): + if link not in self.logged_links: + logger.debug('Skipping link %s; %s', link, reason) + self.logged_links.add(link) + + def _link_package_versions(self, link, search): + """Return an InstallationCandidate or None""" + version = None + if link.egg_fragment: + egg_info = link.egg_fragment + ext = link.ext + else: + egg_info, ext = link.splitext() + if not ext: + self._log_skipped_link(link, 'not a file') + return + if ext not in SUPPORTED_EXTENSIONS: + self._log_skipped_link( + link, 'unsupported archive format: %s' % ext, + ) + return + if "binary" not in search.formats and ext == wheel_ext: + self._log_skipped_link( + link, 'No binaries permitted for %s' % search.supplied, + ) + return + if "macosx10" in link.path and ext == '.zip': + self._log_skipped_link(link, 'macosx10 one') + return + if ext == wheel_ext: + try: + wheel = Wheel(link.filename) + except InvalidWheelFilename: + self._log_skipped_link(link, 'invalid wheel filename') + return + if canonicalize_name(wheel.name) != search.canonical: + self._log_skipped_link( + link, 'wrong project name (not %s)' % search.supplied) + return + + if not wheel.supported(self.valid_tags): + self._log_skipped_link( + link, 'it is not compatible with this Python') + return + + version = wheel.version + + # This should be up by the search.ok_binary check, but see issue 2700. + if "source" not in search.formats and ext != wheel_ext: + self._log_skipped_link( + link, 'No sources permitted for %s' % search.supplied, + ) + return + + if not version: + version = egg_info_matches(egg_info, search.supplied, link) + if version is None: + self._log_skipped_link( + link, 'wrong project name (not %s)' % search.supplied) + return + + match = self._py_version_re.search(version) + if match: + version = version[:match.start()] + py_version = match.group(1) + if py_version != sys.version[:3]: + self._log_skipped_link( + link, 'Python version is incorrect') + return + try: + support_this_python = check_requires_python(link.requires_python) + except specifiers.InvalidSpecifier: + logger.debug("Package %s has an invalid Requires-Python entry: %s", + link.filename, link.requires_python) + support_this_python = True + + if not support_this_python: + logger.debug("The package %s is incompatible with the python" + "version in use. Acceptable python versions are:%s", + link, link.requires_python) + return + logger.debug('Found link %s, version: %s', link, version) + + return InstallationCandidate(search.supplied, version, link) + + def _get_page(self, link): + return HTMLPage.get_page(link, session=self.session) + + +def egg_info_matches( + egg_info, search_name, link, + _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): + """Pull the version part out of a string. + + :param egg_info: The string to parse. E.g. foo-2.1 + :param search_name: The name of the package this belongs to. None to + infer the name. Note that this cannot unambiguously parse strings + like foo-2-2 which might be foo, 2-2 or foo-2, 2. + :param link: The link the string came from, for logging on failure. + """ + match = _egg_info_re.search(egg_info) + if not match: + logger.debug('Could not parse version from link: %s', link) + return None + if search_name is None: + full_match = match.group(0) + return full_match[full_match.index('-'):] + name = match.group(0).lower() + # To match the "safe" name that pkg_resources creates: + name = name.replace('_', '-') + # project name and version must be separated by a dash + look_for = search_name.lower() + "-" + if name.startswith(look_for): + return match.group(0)[len(look_for):] + else: + return None + + +class HTMLPage(object): + """Represents one page, along with its URL""" + + def __init__(self, content, url, headers=None): + # Determine if we have any encoding information in our headers + encoding = None + if headers and "Content-Type" in headers: + content_type, params = cgi.parse_header(headers["Content-Type"]) + + if "charset" in params: + encoding = params['charset'] + + self.content = content + self.parsed = html5lib.parse( + self.content, + transport_encoding=encoding, + namespaceHTMLElements=False, + ) + self.url = url + self.headers = headers + + def __str__(self): + return self.url + + @classmethod + def get_page(cls, link, skip_archives=True, session=None): + if session is None: + raise TypeError( + "get_page() missing 1 required keyword argument: 'session'" + ) + + url = link.url + url = url.split('#', 1)[0] + + # Check for VCS schemes that do not support lookup as web pages. + from pip._internal.vcs import VcsSupport + for scheme in VcsSupport.schemes: + if url.lower().startswith(scheme) and url[len(scheme)] in '+:': + logger.debug('Cannot look at %s URL %s', scheme, link) + return None + + try: + if skip_archives: + filename = link.filename + for bad_ext in ARCHIVE_EXTENSIONS: + if filename.endswith(bad_ext): + content_type = cls._get_content_type( + url, session=session, + ) + if content_type.lower().startswith('text/html'): + break + else: + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + logger.debug('Getting page %s', url) + + # Tack index.html onto file:// URLs that point to directories + (scheme, netloc, path, params, query, fragment) = \ + urllib_parse.urlparse(url) + if (scheme == 'file' and + os.path.isdir(urllib_request.url2pathname(path))): + # add trailing slash if not present so urljoin doesn't trim + # final segment + if not url.endswith('/'): + url += '/' + url = urllib_parse.urljoin(url, 'index.html') + logger.debug(' file: URL is directory, getting %s', url) + + resp = session.get( + url, + headers={ + "Accept": "text/html", + "Cache-Control": "max-age=600", + }, + ) + resp.raise_for_status() + + # The check for archives above only works if the url ends with + # something that looks like an archive. However that is not a + # requirement of an url. Unless we issue a HEAD request on every + # url we cannot know ahead of time for sure if something is HTML + # or not. However we can check after we've downloaded it. + content_type = resp.headers.get('Content-Type', 'unknown') + if not content_type.lower().startswith("text/html"): + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + inst = cls(resp.content, resp.url, resp.headers) + except requests.HTTPError as exc: + cls._handle_fail(link, exc, url) + except SSLError as exc: + reason = "There was a problem confirming the ssl certificate: " + reason += str(exc) + cls._handle_fail(link, reason, url, meth=logger.info) + except requests.ConnectionError as exc: + cls._handle_fail(link, "connection error: %s" % exc, url) + except requests.Timeout: + cls._handle_fail(link, "timed out", url) + else: + return inst + + @staticmethod + def _handle_fail(link, reason, url, meth=None): + if meth is None: + meth = logger.debug + + meth("Could not fetch URL %s: %s - skipping", link, reason) + + @staticmethod + def _get_content_type(url, session): + """Get the Content-Type of the given url, using a HEAD request""" + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) + if scheme not in {'http', 'https'}: + # FIXME: some warning or something? + # assertion error? + return '' + + resp = session.head(url, allow_redirects=True) + resp.raise_for_status() + + return resp.headers.get("Content-Type", "") + + @cached_property + def base_url(self): + bases = [ + x for x in self.parsed.findall(".//base") + if x.get("href") is not None + ] + if bases and bases[0].get("href"): + return bases[0].get("href") + else: + return self.url + + @property + def links(self): + """Yields all links in the page""" + for anchor in self.parsed.findall(".//a"): + if anchor.get("href"): + href = anchor.get("href") + url = self.clean_link( + urllib_parse.urljoin(self.base_url, href) + ) + pyrequire = anchor.get('data-requires-python') + pyrequire = unescape(pyrequire) if pyrequire else None + yield Link(url, self, requires_python=pyrequire) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + def clean_link(self, url): + """Makes sure a link is fully encoded. That is, if a ' ' shows up in + the link, it will be rewritten to %20 (while not over-quoting + % or other characters).""" + return self._clean_re.sub( + lambda match: '%%%2x' % ord(match.group(0)), url) + + +class Link(object): + + def __init__(self, url, comes_from=None, requires_python=None): + """ + Object representing a parsed link from https://pypi.org/simple/* + + url: + url of the resource pointed to (href of the link) + comes_from: + instance of HTMLPage where the link was found, or string. + requires_python: + String containing the `Requires-Python` metadata field, specified + in PEP 345. This may be specified by a data-requires-python + attribute in the HTML link tag, as described in PEP 503. + """ + + # url can be a UNC windows share + if url.startswith('\\\\'): + url = path_to_url(url) + + self.url = url + self.comes_from = comes_from + self.requires_python = requires_python if requires_python else None + + def __str__(self): + if self.requires_python: + rp = ' (requires-python:%s)' % self.requires_python + else: + rp = '' + if self.comes_from: + return '%s (from %s)%s' % (self.url, self.comes_from, rp) + else: + return str(self.url) + + def __repr__(self): + return '' % self + + def __eq__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url == other.url + + def __ne__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url != other.url + + def __lt__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url < other.url + + def __le__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url <= other.url + + def __gt__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url > other.url + + def __ge__(self, other): + if not isinstance(other, Link): + return NotImplemented + return self.url >= other.url + + def __hash__(self): + return hash(self.url) + + @property + def filename(self): + _, netloc, path, _, _ = urllib_parse.urlsplit(self.url) + name = posixpath.basename(path.rstrip('/')) or netloc + name = urllib_parse.unquote(name) + assert name, ('URL %r produced no filename' % self.url) + return name + + @property + def scheme(self): + return urllib_parse.urlsplit(self.url)[0] + + @property + def netloc(self): + return urllib_parse.urlsplit(self.url)[1] + + @property + def path(self): + return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2]) + + def splitext(self): + return splitext(posixpath.basename(self.path.rstrip('/'))) + + @property + def ext(self): + return self.splitext()[1] + + @property + def url_without_fragment(self): + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url) + return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) + + _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') + + @property + def egg_fragment(self): + match = self._egg_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') + + @property + def subdirectory_fragment(self): + match = self._subdirectory_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _hash_re = re.compile( + r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' + ) + + @property + def hash(self): + match = self._hash_re.search(self.url) + if match: + return match.group(2) + return None + + @property + def hash_name(self): + match = self._hash_re.search(self.url) + if match: + return match.group(1) + return None + + @property + def show_url(self): + return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) + + @property + def is_wheel(self): + return self.ext == wheel_ext + + @property + def is_artifact(self): + """ + Determines if this points to an actual artifact (e.g. a tarball) or if + it points to an "abstract" thing like a path or a VCS location. + """ + from pip._internal.vcs import vcs + + if self.scheme in vcs.all_schemes: + return False + + return True + + +FormatControl = namedtuple('FormatControl', 'no_binary only_binary') +"""This object has two fields, no_binary and only_binary. + +If a field is falsy, it isn't set. If it is {':all:'}, it should match all +packages except those listed in the other field. Only one field can be set +to {':all:'} at a time. The rest of the time exact package name matches +are listed, with any given package only showing up in one field at a time. +""" + + +def fmt_ctl_handle_mutual_exclude(value, target, other): + new = value.split(',') + while ':all:' in new: + other.clear() + target.clear() + target.add(':all:') + del new[:new.index(':all:') + 1] + if ':none:' not in new: + # Without a none, we want to discard everything as :all: covers it + return + for name in new: + if name == ':none:': + target.clear() + continue + name = canonicalize_name(name) + other.discard(name) + target.add(name) + + +def fmt_ctl_formats(fmt_ctl, canonical_name): + result = {"binary", "source"} + if canonical_name in fmt_ctl.only_binary: + result.discard('source') + elif canonical_name in fmt_ctl.no_binary: + result.discard('binary') + elif ':all:' in fmt_ctl.only_binary: + result.discard('source') + elif ':all:' in fmt_ctl.no_binary: + result.discard('binary') + return frozenset(result) + + +def fmt_ctl_no_binary(fmt_ctl): + fmt_ctl_handle_mutual_exclude( + ':all:', fmt_ctl.no_binary, fmt_ctl.only_binary, + ) + + +Search = namedtuple('Search', 'supplied canonical formats') +"""Capture key aspects of a search. + +:attribute supplied: The user supplied package. +:attribute canonical: The canonical package name. +:attribute formats: The formats allowed for this package. Should be a set + with 'binary' or 'source' or both in it. +""" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/locations.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/locations.py new file mode 100644 index 0000000..5a20c92 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/locations.py @@ -0,0 +1,194 @@ +"""Locations where we look for configs, install stuff, etc""" +from __future__ import absolute_import + +import os +import os.path +import platform +import site +import sys +import sysconfig +from distutils import sysconfig as distutils_sysconfig +from distutils.command.install import SCHEME_KEYS, install # type: ignore + +from pip._internal.compat import WINDOWS, expanduser +from pip._internal.utils import appdirs + +# Application Directories +USER_CACHE_DIR = appdirs.user_cache_dir("pip") + + +DELETE_MARKER_MESSAGE = '''\ +This file is placed here by pip to indicate the source was put +here by pip. + +Once this package is successfully installed this source code will be +deleted (unless you remove this file). +''' +PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' + + +def write_delete_marker_file(directory): + """ + Write the pip delete marker file into this directory. + """ + filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME) + with open(filepath, 'w') as marker_fp: + marker_fp.write(DELETE_MARKER_MESSAGE) + + +def running_under_virtualenv(): + """ + Return True if we're running inside a virtualenv, False otherwise. + + """ + if hasattr(sys, 'real_prefix'): + return True + elif sys.prefix != getattr(sys, "base_prefix", sys.prefix): + return True + + return False + + +def virtualenv_no_global(): + """ + Return True if in a venv and no system site packages. + """ + # this mirrors the logic in virtualenv.py for locating the + # no-global-site-packages.txt file + site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) + no_global_file = os.path.join(site_mod_dir, 'no-global-site-packages.txt') + if running_under_virtualenv() and os.path.isfile(no_global_file): + return True + + +if running_under_virtualenv(): + src_prefix = os.path.join(sys.prefix, 'src') +else: + # FIXME: keep src in cwd for now (it is not a temporary folder) + try: + src_prefix = os.path.join(os.getcwd(), 'src') + except OSError: + # In case the current working directory has been renamed or deleted + sys.exit( + "The folder you are executing pip from can no longer be found." + ) + +# under macOS + virtualenv sys.prefix is not properly resolved +# it is something like /path/to/python/bin/.. +# Note: using realpath due to tmp dirs on OSX being symlinks +src_prefix = os.path.abspath(src_prefix) + +# FIXME doesn't account for venv linked to global site-packages + +site_packages = sysconfig.get_path("purelib") +# This is because of a bug in PyPy's sysconfig module, see +# https://bitbucket.org/pypy/pypy/issues/2506/sysconfig-returns-incorrect-paths +# for more information. +if platform.python_implementation().lower() == "pypy": + site_packages = distutils_sysconfig.get_python_lib() +try: + # Use getusersitepackages if this is present, as it ensures that the + # value is initialised properly. + user_site = site.getusersitepackages() +except AttributeError: + user_site = site.USER_SITE +user_dir = expanduser('~') +if WINDOWS: + bin_py = os.path.join(sys.prefix, 'Scripts') + bin_user = os.path.join(user_site, 'Scripts') + # buildout uses 'bin' on Windows too? + if not os.path.exists(bin_py): + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.ini' + + legacy_storage_dir = os.path.join(user_dir, 'pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) +else: + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.conf' + + legacy_storage_dir = os.path.join(user_dir, '.pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) + # Forcing to use /usr/local/bin for standard macOS framework installs + # Also log to ~/Library/Logs/ for use with the Console.app log viewer + if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': + bin_py = '/usr/local/bin' + +site_config_files = [ + os.path.join(path, config_basename) + for path in appdirs.site_config_dirs('pip') +] + +venv_config_file = os.path.join(sys.prefix, config_basename) +new_config_file = os.path.join(appdirs.user_config_dir("pip"), config_basename) + + +def distutils_scheme(dist_name, user=False, home=None, root=None, + isolated=False, prefix=None): + """ + Return a distutils install scheme + """ + from distutils.dist import Distribution + + scheme = {} + + if isolated: + extra_dist_args = {"script_args": ["--no-user-cfg"]} + else: + extra_dist_args = {} + dist_args = {'name': dist_name} + dist_args.update(extra_dist_args) + + d = Distribution(dist_args) + d.parse_config_files() + i = d.get_command_obj('install', create=True) + # NOTE: setting user or home has the side-effect of creating the home dir + # or user base for installations during finalize_options() + # ideally, we'd prefer a scheme class that has no side-effects. + assert not (user and prefix), "user={} prefix={}".format(user, prefix) + i.user = user or i.user + if user: + i.prefix = "" + i.prefix = prefix or i.prefix + i.home = home or i.home + i.root = root or i.root + i.finalize_options() + for key in SCHEME_KEYS: + scheme[key] = getattr(i, 'install_' + key) + + # install_lib specified in setup.cfg should install *everything* + # into there (i.e. it takes precedence over both purelib and + # platlib). Note, i.install_lib is *always* set after + # finalize_options(); we only want to override here if the user + # has explicitly requested it hence going back to the config + if 'install_lib' in d.get_option_dict('install'): + scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) + + if running_under_virtualenv(): + scheme['headers'] = os.path.join( + sys.prefix, + 'include', + 'site', + 'python' + sys.version[:3], + dist_name, + ) + + if root is not None: + path_no_drive = os.path.splitdrive( + os.path.abspath(scheme["headers"]))[1] + scheme["headers"] = os.path.join( + root, + path_no_drive[1:], + ) + + return scheme diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__init__.py new file mode 100644 index 0000000..505d92c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__init__.py @@ -0,0 +1,4 @@ +from pip._internal.models.index import Index, PyPI + + +__all__ = ["Index", "PyPI"] diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..3c7512c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__pycache__/index.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__pycache__/index.cpython-37.pyc new file mode 100644 index 0000000..4aacfd4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/__pycache__/index.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/index.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/index.py new file mode 100644 index 0000000..a7f10c8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/models/index.py @@ -0,0 +1,15 @@ +from pip._vendor.six.moves.urllib import parse as urllib_parse + + +class Index(object): + def __init__(self, url): + self.url = url + self.netloc = urllib_parse.urlsplit(url).netloc + self.simple_url = self.url_to_path('simple') + self.pypi_url = self.url_to_path('pypi') + + def url_to_path(self, path): + return urllib_parse.urljoin(self.url, path) + + +PyPI = Index('https://pypi.org/') diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..135a042 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/check.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/check.cpython-37.pyc new file mode 100644 index 0000000..e33dc1e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/check.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc new file mode 100644 index 0000000..056927d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc new file mode 100644 index 0000000..1cd448a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/check.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/check.py new file mode 100644 index 0000000..b1ad5b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/check.py @@ -0,0 +1,106 @@ +"""Validation of dependencies of packages +""" + +from collections import namedtuple + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.operations.prepare import make_abstract_dist + +from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from pip._internal.req.req_install import InstallRequirement + from typing import Any, Dict, Iterator, Set, Tuple, List + + # Shorthands + PackageSet = Dict[str, 'PackageDetails'] + Missing = Tuple[str, Any] + Conflicting = Tuple[str, str, Any] + + MissingDict = Dict[str, List[Missing]] + ConflictingDict = Dict[str, List[Conflicting]] + CheckResult = Tuple[MissingDict, ConflictingDict] + +PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) + + +def create_package_set_from_installed(**kwargs): + # type: (**Any) -> PackageSet + """Converts a list of distributions into a PackageSet. + """ + # Default to using all packages installed on the system + if kwargs == {}: + kwargs = {"local_only": False, "skip": ()} + retval = {} + for dist in get_installed_distributions(**kwargs): + name = canonicalize_name(dist.project_name) + retval[name] = PackageDetails(dist.version, dist.requires()) + return retval + + +def check_package_set(package_set): + # type: (PackageSet) -> CheckResult + """Check if a package set is consistent + """ + missing = dict() + conflicting = dict() + + for package_name in package_set: + # Info about dependencies of package_name + missing_deps = set() # type: Set[Missing] + conflicting_deps = set() # type: Set[Conflicting] + + for req in package_set[package_name].requires: + name = canonicalize_name(req.project_name) # type: str + + # Check if it's missing + if name not in package_set: + missed = True + if req.marker is not None: + missed = req.marker.evaluate() + if missed: + missing_deps.add((name, req)) + continue + + # Check if there's a conflict + version = package_set[name].version # type: str + if not req.specifier.contains(version, prereleases=True): + conflicting_deps.add((name, version, req)) + + def str_key(x): + return str(x) + + if missing_deps: + missing[package_name] = sorted(missing_deps, key=str_key) + if conflicting_deps: + conflicting[package_name] = sorted(conflicting_deps, key=str_key) + + return missing, conflicting + + +def check_install_conflicts(to_install): + # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] + """For checking if the dependency graph would be consistent after \ + installing given requirements + """ + # Start from the current state + state = create_package_set_from_installed() + _simulate_installation_of(to_install, state) + return state, check_package_set(state) + + +# NOTE from @pradyunsg +# This required a minor update in dependency link handling logic over at +# operations.prepare.IsSDist.dist() to get it working +def _simulate_installation_of(to_install, state): + # type: (List[InstallRequirement], PackageSet) -> None + """Computes the version of packages after installing to_install. + """ + + # Modify it as installing requirement_set would (assuming no errors) + for inst_req in to_install: + dist = make_abstract_dist(inst_req).dist(finder=None) + name = canonicalize_name(dist.key) + state[name] = PackageDetails(dist.version, dist.requires()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/freeze.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/freeze.py new file mode 100644 index 0000000..b6821c0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/freeze.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import + +import collections +import logging +import os +import re +import warnings + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.exceptions import InstallationError +from pip._internal.req import InstallRequirement +from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) + +logger = logging.getLogger(__name__) + + +def freeze( + requirement=None, + find_links=None, local_only=None, user_only=None, skip_regex=None, + isolated=False, + wheel_cache=None, + exclude_editable=False, + skip=()): + find_links = find_links or [] + skip_match = None + + if skip_regex: + skip_match = re.compile(skip_regex).search + + dependency_links = [] + + for dist in pkg_resources.working_set: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt') + ) + for link in find_links: + if '#egg=' in link: + dependency_links.append(link) + for link in find_links: + yield '-f %s' % link + installations = {} + for dist in get_installed_distributions(local_only=local_only, + skip=(), + user_only=user_only): + try: + req = FrozenRequirement.from_dist( + dist, + dependency_links + ) + except RequirementParseError: + logger.warning( + "Could not parse requirement: %s", + dist.project_name + ) + continue + if exclude_editable and req.editable: + continue + installations[req.name] = req + + if requirement: + # the options that don't get turned into an InstallRequirement + # should only be emitted once, even if the same option is in multiple + # requirements files, so we need to keep track of what has been emitted + # so that we don't emit it again if it's seen again + emitted_options = set() + # keep track of which files a requirement is in so that we can + # give an accurate warning if a requirement appears multiple times. + req_files = collections.defaultdict(list) + for req_file_path in requirement: + with open(req_file_path) as req_file: + for line in req_file: + if (not line.strip() or + line.strip().startswith('#') or + (skip_match and skip_match(line)) or + line.startswith(( + '-r', '--requirement', + '-Z', '--always-unzip', + '-f', '--find-links', + '-i', '--index-url', + '--pre', + '--trusted-host', + '--process-dependency-links', + '--extra-index-url'))): + line = line.rstrip() + if line not in emitted_options: + emitted_options.add(line) + yield line + continue + + if line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + line_req = InstallRequirement.from_editable( + line, + isolated=isolated, + wheel_cache=wheel_cache, + ) + else: + line_req = InstallRequirement.from_line( + COMMENT_RE.sub('', line).strip(), + isolated=isolated, + wheel_cache=wheel_cache, + ) + + if not line_req.name: + logger.info( + "Skipping line in requirement file [%s] because " + "it's not clear what it would install: %s", + req_file_path, line.strip(), + ) + logger.info( + " (add #egg=PackageName to the URL to avoid" + " this warning)" + ) + elif line_req.name not in installations: + # either it's not installed, or it is installed + # but has been processed already + if not req_files[line_req.name]: + logger.warning( + "Requirement file [%s] contains %s, but that " + "package is not installed", + req_file_path, + COMMENT_RE.sub('', line).strip(), + ) + else: + req_files[line_req.name].append(req_file_path) + else: + yield str(installations[line_req.name]).rstrip() + del installations[line_req.name] + req_files[line_req.name].append(req_file_path) + + # Warn about requirements that were included multiple times (in a + # single requirements file or in different requirements files). + for name, files in six.iteritems(req_files): + if len(files) > 1: + logger.warning("Requirement %s included multiple times [%s]", + name, ', '.join(sorted(set(files)))) + + yield( + '## The following requirements were added by ' + 'pip freeze:' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + if canonicalize_name(installation.name) not in skip: + yield str(installation).rstrip() + + +class FrozenRequirement(object): + def __init__(self, name, req, editable, comments=()): + self.name = name + self.req = req + self.editable = editable + self.comments = comments + + _rev_re = re.compile(r'-r(\d+)$') + _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') + + @classmethod + def from_dist(cls, dist, dependency_links): + location = os.path.normcase(os.path.abspath(dist.location)) + comments = [] + from pip._internal.vcs import vcs, get_src_requirement + if dist_is_editable(dist) and vcs.get_backend_name(location): + editable = True + try: + req = get_src_requirement(dist, location) + except InstallationError as exc: + logger.warning( + "Error when trying to get requirement for VCS system %s, " + "falling back to uneditable format", exc + ) + req = None + if req is None: + logger.warning( + 'Could not determine repository location of %s', location + ) + comments.append( + '## !! Could not determine repository location' + ) + req = dist.as_requirement() + editable = False + else: + editable = False + req = dist.as_requirement() + specs = req.specs + assert len(specs) == 1 and specs[0][0] in ["==", "==="], \ + 'Expected 1 spec with == or ===; specs = %r; dist = %r' % \ + (specs, dist) + version = specs[0][1] + ver_match = cls._rev_re.search(version) + date_match = cls._date_re.search(version) + if ver_match or date_match: + svn_backend = vcs.get_backend('svn') + if svn_backend: + svn_location = svn_backend().get_location( + dist, + dependency_links, + ) + if not svn_location: + logger.warning( + 'Warning: cannot find svn location for %s', req, + ) + comments.append( + '## FIXME: could not find svn URL in dependency_links ' + 'for this package:' + ) + else: + warnings.warn( + "SVN editable detection based on dependency links " + "will be dropped in the future.", + RemovedInPip11Warning, + ) + comments.append( + '# Installing as editable to satisfy requirement %s:' % + req + ) + if ver_match: + rev = ver_match.group(1) + else: + rev = '{%s}' % date_match.group(1) + editable = True + req = '%s@%s#egg=%s' % ( + svn_location, + rev, + cls.egg_name(dist) + ) + return cls(dist.project_name, req, editable, comments) + + @staticmethod + def egg_name(dist): + name = dist.egg_name() + match = re.search(r'-py\d\.\d$', name) + if match: + name = name[:match.start()] + return name + + def __str__(self): + req = self.req + if self.editable: + req = '-e %s' % req + return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/prepare.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/prepare.py new file mode 100644 index 0000000..27e3a5d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/operations/prepare.py @@ -0,0 +1,380 @@ +"""Prepares a distribution for installation +""" + +import itertools +import logging +import os +import sys +from copy import copy + +from pip._vendor import pkg_resources, requests + +from pip._internal.build_env import NoOpBuildEnvironment +from pip._internal.compat import expanduser +from pip._internal.download import ( + is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path, +) +from pip._internal.exceptions import ( + DirectoryUrlHashUnsupported, HashUnpinned, InstallationError, + PreviousBuildDirError, VcsHashUnsupported, +) +from pip._internal.index import FormatControl +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.hashes import MissingHashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + call_subprocess, display_path, normalize_path, +) +from pip._internal.utils.ui import open_spinner +from pip._internal.vcs import vcs + +logger = logging.getLogger(__name__) + + +def make_abstract_dist(req): + """Factory to make an abstract dist object. + + Preconditions: Either an editable req with a source_dir, or satisfied_by or + a wheel link, or a non-editable req with a source_dir. + + :return: A concrete DistAbstraction. + """ + if req.editable: + return IsSDist(req) + elif req.link and req.link.is_wheel: + return IsWheel(req) + else: + return IsSDist(req) + + +def _install_build_reqs(finder, prefix, build_requirements): + # NOTE: What follows is not a very good thing. + # Eventually, this should move into the BuildEnvironment class and + # that should handle all the isolation and sub-process invocation. + finder = copy(finder) + finder.format_control = FormatControl(set(), set([":all:"])) + urls = [ + finder.find_requirement( + InstallRequirement.from_line(r), upgrade=False).url + for r in build_requirements + ] + args = [ + sys.executable, '-m', 'pip', 'install', '--ignore-installed', + '--no-user', '--prefix', prefix, + ] + list(urls) + + with open_spinner("Installing build dependencies") as spinner: + call_subprocess(args, show_stdout=False, spinner=spinner) + + +class DistAbstraction(object): + """Abstracts out the wheel vs non-wheel Resolver.resolve() logic. + + The requirements for anything installable are as follows: + - we must be able to determine the requirement name + (or we can't correctly handle the non-upgrade case). + - we must be able to generate a list of run-time dependencies + without installing any additional packages (or we would + have to either burn time by doing temporary isolated installs + or alternatively violate pips 'don't start installing unless + all requirements are available' rule - neither of which are + desirable). + - for packages with setup requirements, we must also be able + to determine their requirements without installing additional + packages (for the same reason as run-time dependencies) + - we must be able to create a Distribution object exposing the + above metadata. + """ + + def __init__(self, req): + self.req = req + + def dist(self, finder): + """Return a setuptools Dist object.""" + raise NotImplementedError(self.dist) + + def prep_for_dist(self, finder): + """Ensure that we can get a Dist for this requirement.""" + raise NotImplementedError(self.dist) + + +class IsWheel(DistAbstraction): + + def dist(self, finder): + return list(pkg_resources.find_distributions( + self.req.source_dir))[0] + + def prep_for_dist(self, finder, build_isolation): + # FIXME:https://github.com/pypa/pip/issues/1112 + pass + + +class IsSDist(DistAbstraction): + + def dist(self, finder): + dist = self.req.get_dist() + # FIXME: shouldn't be globally added. + if finder and dist.has_metadata('dependency_links.txt'): + finder.add_dependency_links( + dist.get_metadata_lines('dependency_links.txt') + ) + return dist + + def prep_for_dist(self, finder, build_isolation): + # Before calling "setup.py egg_info", we need to set-up the build + # environment. + build_requirements, isolate = self.req.get_pep_518_info() + should_isolate = build_isolation and isolate + + minimum_requirements = ('setuptools', 'wheel') + missing_requirements = set(minimum_requirements) - set( + pkg_resources.Requirement(r).key + for r in build_requirements + ) + if missing_requirements: + def format_reqs(rs): + return ' and '.join(map(repr, sorted(rs))) + logger.warning( + "Missing build time requirements in pyproject.toml for %s: " + "%s.", self.req, format_reqs(missing_requirements) + ) + logger.warning( + "This version of pip does not implement PEP 517 so it cannot " + "build a wheel without %s.", format_reqs(minimum_requirements) + ) + + if should_isolate: + with self.req.build_env: + pass + _install_build_reqs(finder, self.req.build_env.path, + build_requirements) + else: + self.req.build_env = NoOpBuildEnvironment(no_clean=False) + + self.req.run_egg_info() + self.req.assert_source_matches_version() + + +class Installed(DistAbstraction): + + def dist(self, finder): + return self.req.satisfied_by + + def prep_for_dist(self, finder): + pass + + +class RequirementPreparer(object): + """Prepares a Requirement + """ + + def __init__(self, build_dir, download_dir, src_dir, wheel_download_dir, + progress_bar, build_isolation): + super(RequirementPreparer, self).__init__() + + self.src_dir = src_dir + self.build_dir = build_dir + + # Where still packed archives should be written to. If None, they are + # not saved, and are deleted immediately after unpacking. + self.download_dir = download_dir + + # Where still-packed .whl files should be written to. If None, they are + # written to the download_dir parameter. Separate to download_dir to + # permit only keeping wheel archives for pip wheel. + if wheel_download_dir: + wheel_download_dir = normalize_path(wheel_download_dir) + self.wheel_download_dir = wheel_download_dir + + # NOTE + # download_dir and wheel_download_dir overlap semantically and may + # be combined if we're willing to have non-wheel archives present in + # the wheelhouse output by 'pip wheel'. + + self.progress_bar = progress_bar + + # Is build isolation allowed? + self.build_isolation = build_isolation + + @property + def _download_should_save(self): + # TODO: Modify to reduce indentation needed + if self.download_dir: + self.download_dir = expanduser(self.download_dir) + if os.path.exists(self.download_dir): + return True + else: + logger.critical('Could not find download directory') + raise InstallationError( + "Could not find or access download directory '%s'" + % display_path(self.download_dir)) + return False + + def prepare_linked_requirement(self, req, session, finder, + upgrade_allowed, require_hashes): + """Prepare a requirement that would be obtained from req.link + """ + # TODO: Breakup into smaller functions + if req.link and req.link.scheme == 'file': + path = url_to_path(req.link.url) + logger.info('Processing %s', display_path(path)) + else: + logger.info('Collecting %s', req) + + with indent_log(): + # @@ if filesystem packages are not marked + # editable in a req, a non deterministic error + # occurs when the script attempts to unpack the + # build directory + req.ensure_has_source_dir(self.build_dir) + # If a checkout exists, it's unwise to keep going. version + # inconsistencies are logged later, but do not fail the + # installation. + # FIXME: this won't upgrade when there's an existing + # package unpacked in `req.source_dir` + # package unpacked in `req.source_dir` + if os.path.exists(os.path.join(req.source_dir, 'setup.py')): + raise PreviousBuildDirError( + "pip can't proceed with requirements '%s' due to a" + " pre-existing build directory (%s). This is " + "likely due to a previous installation that failed" + ". pip is being responsible and not assuming it " + "can delete this. Please delete it and try again." + % (req, req.source_dir) + ) + req.populate_link(finder, upgrade_allowed, require_hashes) + + # We can't hit this spot and have populate_link return None. + # req.satisfied_by is None here (because we're + # guarded) and upgrade has no impact except when satisfied_by + # is not None. + # Then inside find_requirement existing_applicable -> False + # If no new versions are found, DistributionNotFound is raised, + # otherwise a result is guaranteed. + assert req.link + link = req.link + + # Now that we have the real link, we can tell what kind of + # requirements we have and raise some more informative errors + # than otherwise. (For example, we can raise VcsHashUnsupported + # for a VCS URL rather than HashMissing.) + if require_hashes: + # We could check these first 2 conditions inside + # unpack_url and save repetition of conditions, but then + # we would report less-useful error messages for + # unhashable requirements, complaining that there's no + # hash provided. + if is_vcs_url(link): + raise VcsHashUnsupported() + elif is_file_url(link) and is_dir_url(link): + raise DirectoryUrlHashUnsupported() + if not req.original_link and not req.is_pinned: + # Unpinned packages are asking for trouble when a new + # version is uploaded. This isn't a security check, but + # it saves users a surprising hash mismatch in the + # future. + # + # file:/// URLs aren't pinnable, so don't complain + # about them not being pinned. + raise HashUnpinned() + + hashes = req.hashes(trust_internet=not require_hashes) + if require_hashes and not hashes: + # Known-good hashes are missing for this requirement, so + # shim it with a facade object that will provoke hash + # computation and then raise a HashMissing exception + # showing the user what the hash should be. + hashes = MissingHashes() + + try: + download_dir = self.download_dir + # We always delete unpacked sdists after pip ran. + autodelete_unpacked = True + if req.link.is_wheel and self.wheel_download_dir: + # when doing 'pip wheel` we download wheels to a + # dedicated dir. + download_dir = self.wheel_download_dir + if req.link.is_wheel: + if download_dir: + # When downloading, we only unpack wheels to get + # metadata. + autodelete_unpacked = True + else: + # When installing a wheel, we use the unpacked + # wheel. + autodelete_unpacked = False + unpack_url( + req.link, req.source_dir, + download_dir, autodelete_unpacked, + session=session, hashes=hashes, + progress_bar=self.progress_bar + ) + except requests.HTTPError as exc: + logger.critical( + 'Could not install requirement %s because of error %s', + req, + exc, + ) + raise InstallationError( + 'Could not install requirement %s because of HTTP ' + 'error %s for URL %s' % + (req, exc, req.link) + ) + abstract_dist = make_abstract_dist(req) + abstract_dist.prep_for_dist(finder, self.build_isolation) + if self._download_should_save: + # Make a .zip of the source_dir we already created. + if req.link.scheme in vcs.all_schemes: + req.archive(self.download_dir) + return abstract_dist + + def prepare_editable_requirement(self, req, require_hashes, use_user_site, + finder): + """Prepare an editable requirement + """ + assert req.editable, "cannot prepare a non-editable req as editable" + + logger.info('Obtaining %s', req) + + with indent_log(): + if require_hashes: + raise InstallationError( + 'The editable requirement %s cannot be installed when ' + 'requiring hashes, because there is no single file to ' + 'hash.' % req + ) + req.ensure_has_source_dir(self.src_dir) + req.update_editable(not self._download_should_save) + + abstract_dist = make_abstract_dist(req) + abstract_dist.prep_for_dist(finder, self.build_isolation) + + if self._download_should_save: + req.archive(self.download_dir) + req.check_if_exists(use_user_site) + + return abstract_dist + + def prepare_installed_requirement(self, req, require_hashes, skip_reason): + """Prepare an already-installed requirement + """ + assert req.satisfied_by, "req should have been satisfied but isn't" + assert skip_reason is not None, ( + "did not get skip reason skipped but req.satisfied_by " + "is set to %r" % (req.satisfied_by,) + ) + logger.info( + 'Requirement %s: %s (%s)', + skip_reason, req, req.satisfied_by.version + ) + with indent_log(): + if require_hashes: + logger.debug( + 'Since it is already installed, we are trusting this ' + 'package without checking its hash. To ensure a ' + 'completely repeatable environment, install into an ' + 'empty virtualenv.' + ) + abstract_dist = Installed(req) + + return abstract_dist diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/pep425tags.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/pep425tags.py new file mode 100644 index 0000000..0b5c783 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/pep425tags.py @@ -0,0 +1,317 @@ +"""Generate and work with PEP 425 Compatibility Tags.""" +from __future__ import absolute_import + +import distutils.util +import logging +import platform +import re +import sys +import sysconfig +import warnings +from collections import OrderedDict + +import pip._internal.utils.glibc + +logger = logging.getLogger(__name__) + +_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') + + +def get_config_var(var): + try: + return sysconfig.get_config_var(var) + except IOError as e: # Issue #1074 + warnings.warn("{}".format(e), RuntimeWarning) + return None + + +def get_abbr_impl(): + """Return abbreviated implementation name.""" + if hasattr(sys, 'pypy_version_info'): + pyimpl = 'pp' + elif sys.platform.startswith('java'): + pyimpl = 'jy' + elif sys.platform == 'cli': + pyimpl = 'ip' + else: + pyimpl = 'cp' + return pyimpl + + +def get_impl_ver(): + """Return implementation version.""" + impl_ver = get_config_var("py_version_nodot") + if not impl_ver or get_abbr_impl() == 'pp': + impl_ver = ''.join(map(str, get_impl_version_info())) + return impl_ver + + +def get_impl_version_info(): + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + if get_abbr_impl() == 'pp': + # as per https://github.com/pypa/pip/issues/2882 + return (sys.version_info[0], sys.pypy_version_info.major, + sys.pypy_version_info.minor) + else: + return sys.version_info[0], sys.version_info[1] + + +def get_impl_tag(): + """ + Returns the Tag for this specific implementation. + """ + return "{}{}".format(get_abbr_impl(), get_impl_ver()) + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + logger.debug("Config variable '%s' is unset, Python ABI tag may " + "be incorrect", var) + return fallback() + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp')): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def _is_running_32bit(): + return sys.maxsize == 2147483647 + + +def get_platform(): + """Return our platform name 'win32', 'linux_x86_64'""" + if sys.platform == 'darwin': + # distutils.util.get_platform() returns the release based on the value + # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may + # be significantly older than the user's current machine. + release, _, machine = platform.mac_ver() + split_ver = release.split('.') + + if machine == "x86_64" and _is_running_32bit(): + machine = "i386" + elif machine == "ppc64" and _is_running_32bit(): + machine = "ppc" + + return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) + + # XXX remove distutils dependency + result = distutils.util.get_platform().replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and _is_running_32bit(): + # 32 bit Python program (running on a 64 bit Linux): pip should only + # install and run 32 bit compiled extensions in that case. + result = "linux_i686" + + return result + + +def is_manylinux1_compatible(): + # Only Linux, and only x86-64 / i686 + if get_platform() not in {"linux_x86_64", "linux_i686"}: + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux1_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 5 uses glibc 2.5. + return pip._internal.utils.glibc.have_compatible_glibc(2, 5) + + +def get_darwin_arches(major, minor, machine): + """Return a list of supported arches (including group arches) for + the given major, minor and machine architecture of an macOS machine. + """ + arches = [] + + def _supports_arch(major, minor, arch): + # Looking at the application support for macOS versions in the chart + # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears + # our timeline looks roughly like: + # + # 10.0 - Introduces ppc support. + # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 + # and x86_64 support is CLI only, and cannot be used for GUI + # applications. + # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. + # 10.6 - Drops support for ppc64 + # 10.7 - Drops support for ppc + # + # Given that we do not know if we're installing a CLI or a GUI + # application, we must be conservative and assume it might be a GUI + # application and behave as if ppc64 and x86_64 support did not occur + # until 10.5. + # + # Note: The above information is taken from the "Application support" + # column in the chart not the "Processor support" since I believe + # that we care about what instruction sets an application can use + # not which processors the OS supports. + if arch == 'ppc': + return (major, minor) <= (10, 5) + if arch == 'ppc64': + return (major, minor) == (10, 5) + if arch == 'i386': + return (major, minor) >= (10, 4) + if arch == 'x86_64': + return (major, minor) >= (10, 5) + if arch in groups: + for garch in groups[arch]: + if _supports_arch(major, minor, garch): + return True + return False + + groups = OrderedDict([ + ("fat", ("i386", "ppc")), + ("intel", ("x86_64", "i386")), + ("fat64", ("x86_64", "ppc64")), + ("fat32", ("x86_64", "i386", "ppc")), + ]) + + if _supports_arch(major, minor, machine): + arches.append(machine) + + for garch in groups: + if machine in groups[garch] and _supports_arch(major, minor, garch): + arches.append(garch) + + arches.append('universal') + + return arches + + +def get_supported(versions=None, noarch=False, platform=None, + impl=None, abi=None): + """Return a list of supported tags for each version specified in + `versions`. + + :param versions: a list of string versions, of the form ["33", "32"], + or None. The first version will be assumed to support our ABI. + :param platform: specify the exact platform you want valid + tags for, or None. If None, use the local system platform. + :param impl: specify the exact implementation you want valid + tags for, or None. If None, use the local interpreter impl. + :param abi: specify the exact abi you want valid + tags for, or None. If None, use the local interpreter abi. + """ + supported = [] + + # Versions must be given with respect to the preference + if versions is None: + versions = [] + version_info = get_impl_version_info() + major = version_info[:-1] + # Support all previous minor Python versions. + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) + + impl = impl or get_abbr_impl() + + abis = [] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + abi3s = set() + import imp + for suffix in imp.get_suffixes(): + if suffix[0].startswith('.abi'): + abi3s.add(suffix[0].split('.', 2)[1]) + + abis.extend(sorted(list(abi3s))) + + abis.append('none') + + if not noarch: + arch = platform or get_platform() + if arch.startswith('macosx'): + # support macosx-10.6-intel on macosx-10.9-x86_64 + match = _osx_arch_pat.match(arch) + if match: + name, major, minor, actual_arch = match.groups() + tpl = '{}_{}_%i_%s'.format(name, major) + arches = [] + for m in reversed(range(int(minor) + 1)): + for a in get_darwin_arches(int(major), m, actual_arch): + arches.append(tpl % (m, a)) + else: + # arch pattern didn't match (?!) + arches = [arch] + elif platform is None and is_manylinux1_compatible(): + arches = [arch.replace('linux', 'manylinux1'), arch] + else: + arches = [arch] + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + + # abi3 modules compatible with older version of Python + for version in versions[1:]: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for abi in abi3s: # empty set if not Python 3 + for arch in arches: + supported.append(("%s%s" % (impl, version), abi, arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + + # No abi / arch, generic Python + for i, version in enumerate(versions): + supported.append(('py%s' % (version,), 'none', 'any')) + if i == 0: + supported.append(('py%s' % (version[0]), 'none', 'any')) + + return supported + + +implementation_tag = get_impl_tag() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__init__.py new file mode 100644 index 0000000..c9b4c3c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__init__.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import + +import logging + +from .req_install import InstallRequirement +from .req_set import RequirementSet +from .req_file import parse_requirements +from pip._internal.utils.logging import indent_log + + +__all__ = [ + "RequirementSet", "InstallRequirement", + "parse_requirements", "install_given_reqs", +] + +logger = logging.getLogger(__name__) + + +def install_given_reqs(to_install, install_options, global_options=(), + *args, **kwargs): + """ + Install everything in the given list. + + (to be called after having downloaded and unpacked the packages) + """ + + if to_install: + logger.info( + 'Installing collected packages: %s', + ', '.join([req.name for req in to_install]), + ) + + with indent_log(): + for requirement in to_install: + if requirement.conflicts_with: + logger.info( + 'Found existing installation: %s', + requirement.conflicts_with, + ) + with indent_log(): + uninstalled_pathset = requirement.uninstall( + auto_confirm=True + ) + try: + requirement.install( + install_options, + global_options, + *args, + **kwargs + ) + except: + should_rollback = ( + requirement.conflicts_with and + not requirement.install_succeeded + ) + # if install did not succeed, rollback previous uninstall + if should_rollback: + uninstalled_pathset.rollback() + raise + else: + should_commit = ( + requirement.conflicts_with and + requirement.install_succeeded + ) + if should_commit: + uninstalled_pathset.commit() + requirement.remove_temporary_source() + + return to_install diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..4ae2f27 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_file.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_file.cpython-37.pyc new file mode 100644 index 0000000..0685cdc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_file.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_install.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_install.cpython-37.pyc new file mode 100644 index 0000000..59cec3f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_install.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_set.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_set.cpython-37.pyc new file mode 100644 index 0000000..d473ce5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_set.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc new file mode 100644 index 0000000..cce37a5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_file.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_file.py new file mode 100644 index 0000000..f868497 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_file.py @@ -0,0 +1,338 @@ +""" +Requirements file parsing +""" + +from __future__ import absolute_import + +import optparse +import os +import re +import shlex +import sys + +from pip._vendor.six.moves import filterfalse +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal import cmdoptions +from pip._internal.download import get_file_content +from pip._internal.exceptions import RequirementsFileParseError +from pip._internal.req.req_install import InstallRequirement + +__all__ = ['parse_requirements'] + +SCHEME_RE = re.compile(r'^(http|https|file):', re.I) +COMMENT_RE = re.compile(r'(^|\s)+#.*$') + +# Matches environment variable-style values in '${MY_VARIABLE_1}' with the +# variable name consisting of only uppercase letters, digits or the '_' +# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, +# 2013 Edition. +ENV_VAR_RE = re.compile(r'(?P\$\{(?P[A-Z0-9_]+)\})') + +SUPPORTED_OPTIONS = [ + cmdoptions.constraints, + cmdoptions.editable, + cmdoptions.requirements, + cmdoptions.no_index, + cmdoptions.index_url, + cmdoptions.find_links, + cmdoptions.extra_index_url, + cmdoptions.always_unzip, + cmdoptions.no_binary, + cmdoptions.only_binary, + cmdoptions.pre, + cmdoptions.process_dependency_links, + cmdoptions.trusted_host, + cmdoptions.require_hashes, +] + +# options to be passed to requirements +SUPPORTED_OPTIONS_REQ = [ + cmdoptions.install_options, + cmdoptions.global_options, + cmdoptions.hash, +] + +# the 'dest' string values +SUPPORTED_OPTIONS_REQ_DEST = [o().dest for o in SUPPORTED_OPTIONS_REQ] + + +def parse_requirements(filename, finder=None, comes_from=None, options=None, + session=None, constraint=False, wheel_cache=None): + """Parse a requirements file and yield InstallRequirement instances. + + :param filename: Path or url of requirements file. + :param finder: Instance of pip.index.PackageFinder. + :param comes_from: Origin description of requirements. + :param options: cli options. + :param session: Instance of pip.download.PipSession. + :param constraint: If true, parsing a constraint file rather than + requirements file. + :param wheel_cache: Instance of pip.wheel.WheelCache + """ + if session is None: + raise TypeError( + "parse_requirements() missing 1 required keyword argument: " + "'session'" + ) + + _, content = get_file_content( + filename, comes_from=comes_from, session=session + ) + + lines_enum = preprocess(content, options) + + for line_number, line in lines_enum: + req_iter = process_line(line, filename, line_number, finder, + comes_from, options, session, wheel_cache, + constraint=constraint) + for req in req_iter: + yield req + + +def preprocess(content, options): + """Split, filter, and join lines, and return a line iterator + + :param content: the content of the requirements file + :param options: cli options + """ + lines_enum = enumerate(content.splitlines(), start=1) + lines_enum = join_lines(lines_enum) + lines_enum = ignore_comments(lines_enum) + lines_enum = skip_regex(lines_enum, options) + lines_enum = expand_env_variables(lines_enum) + return lines_enum + + +def process_line(line, filename, line_number, finder=None, comes_from=None, + options=None, session=None, wheel_cache=None, + constraint=False): + """Process a single requirements line; This can result in creating/yielding + requirements, or updating the finder. + + For lines that contain requirements, the only options that have an effect + are from SUPPORTED_OPTIONS_REQ, and they are scoped to the + requirement. Other options from SUPPORTED_OPTIONS may be present, but are + ignored. + + For lines that do not contain requirements, the only options that have an + effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may + be present, but are ignored. These lines may contain multiple options + (although our docs imply only one is supported), and all our parsed and + affect the finder. + + :param constraint: If True, parsing a constraints file. + :param options: OptionParser options that we may update + """ + parser = build_parser(line) + defaults = parser.get_default_values() + defaults.index_url = None + if finder: + # `finder.format_control` will be updated during parsing + defaults.format_control = finder.format_control + args_str, options_str = break_args_options(line) + if sys.version_info < (2, 7, 3): + # Prior to 2.7.3, shlex cannot deal with unicode entries + options_str = options_str.encode('utf8') + opts, _ = parser.parse_args(shlex.split(options_str), defaults) + + # preserve for the nested code path + line_comes_from = '%s %s (line %s)' % ( + '-c' if constraint else '-r', filename, line_number, + ) + + # yield a line requirement + if args_str: + isolated = options.isolated_mode if options else False + if options: + cmdoptions.check_install_build_global(options, opts) + # get the options that apply to requirements + req_options = {} + for dest in SUPPORTED_OPTIONS_REQ_DEST: + if dest in opts.__dict__ and opts.__dict__[dest]: + req_options[dest] = opts.__dict__[dest] + yield InstallRequirement.from_line( + args_str, line_comes_from, constraint=constraint, + isolated=isolated, options=req_options, wheel_cache=wheel_cache + ) + + # yield an editable requirement + elif opts.editables: + isolated = options.isolated_mode if options else False + yield InstallRequirement.from_editable( + opts.editables[0], comes_from=line_comes_from, + constraint=constraint, isolated=isolated, wheel_cache=wheel_cache + ) + + # parse a nested requirements file + elif opts.requirements or opts.constraints: + if opts.requirements: + req_path = opts.requirements[0] + nested_constraint = False + else: + req_path = opts.constraints[0] + nested_constraint = True + # original file is over http + if SCHEME_RE.search(filename): + # do a url join so relative paths work + req_path = urllib_parse.urljoin(filename, req_path) + # original file and nested file are paths + elif not SCHEME_RE.search(req_path): + # do a join so relative paths work + req_path = os.path.join(os.path.dirname(filename), req_path) + # TODO: Why not use `comes_from='-r {} (line {})'` here as well? + parser = parse_requirements( + req_path, finder, comes_from, options, session, + constraint=nested_constraint, wheel_cache=wheel_cache + ) + for req in parser: + yield req + + # percolate hash-checking option upward + elif opts.require_hashes: + options.require_hashes = opts.require_hashes + + # set finder options + elif finder: + if opts.index_url: + finder.index_urls = [opts.index_url] + if opts.no_index is True: + finder.index_urls = [] + if opts.extra_index_urls: + finder.index_urls.extend(opts.extra_index_urls) + if opts.find_links: + # FIXME: it would be nice to keep track of the source + # of the find_links: support a find-links local path + # relative to a requirements file. + value = opts.find_links[0] + req_dir = os.path.dirname(os.path.abspath(filename)) + relative_to_reqs_file = os.path.join(req_dir, value) + if os.path.exists(relative_to_reqs_file): + value = relative_to_reqs_file + finder.find_links.append(value) + if opts.pre: + finder.allow_all_prereleases = True + if opts.process_dependency_links: + finder.process_dependency_links = True + if opts.trusted_hosts: + finder.secure_origins.extend( + ("*", host, "*") for host in opts.trusted_hosts) + + +def break_args_options(line): + """Break up the line into an args and options string. We only want to shlex + (and then optparse) the options, not the args. args can contain markers + which are corrupted by shlex. + """ + tokens = line.split(' ') + args = [] + options = tokens[:] + for token in tokens: + if token.startswith('-') or token.startswith('--'): + break + else: + args.append(token) + options.pop(0) + return ' '.join(args), ' '.join(options) + + +def build_parser(line): + """ + Return a parser for parsing requirement lines + """ + parser = optparse.OptionParser(add_help_option=False) + + option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ + for option_factory in option_factories: + option = option_factory() + parser.add_option(option) + + # By default optparse sys.exits on parsing errors. We want to wrap + # that in our own exception. + def parser_exit(self, msg): + # add offending line + msg = 'Invalid requirement: %s\n%s' % (line, msg) + raise RequirementsFileParseError(msg) + parser.exit = parser_exit + + return parser + + +def join_lines(lines_enum): + """Joins a line ending in '\' with the previous line (except when following + comments). The joined line takes on the index of the first line. + """ + primary_line_number = None + new_line = [] + for line_number, line in lines_enum: + if not line.endswith('\\') or COMMENT_RE.match(line): + if COMMENT_RE.match(line): + # this ensures comments are always matched later + line = ' ' + line + if new_line: + new_line.append(line) + yield primary_line_number, ''.join(new_line) + new_line = [] + else: + yield line_number, line + else: + if not new_line: + primary_line_number = line_number + new_line.append(line.strip('\\')) + + # last line contains \ + if new_line: + yield primary_line_number, ''.join(new_line) + + # TODO: handle space after '\'. + + +def ignore_comments(lines_enum): + """ + Strips comments and filter empty lines. + """ + for line_number, line in lines_enum: + line = COMMENT_RE.sub('', line) + line = line.strip() + if line: + yield line_number, line + + +def skip_regex(lines_enum, options): + """ + Skip lines that match '--skip-requirements-regex' pattern + + Note: the regex pattern is only built once + """ + skip_regex = options.skip_requirements_regex if options else None + if skip_regex: + pattern = re.compile(skip_regex) + lines_enum = filterfalse(lambda e: pattern.search(e[1]), lines_enum) + return lines_enum + + +def expand_env_variables(lines_enum): + """Replace all environment variables that can be retrieved via `os.getenv`. + + The only allowed format for environment variables defined in the + requirement file is `${MY_VARIABLE_1}` to ensure two things: + + 1. Strings that contain a `$` aren't accidentally (partially) expanded. + 2. Ensure consistency across platforms for requirement files. + + These points are the result of a discusssion on the `github pull + request #3514 `_. + + Valid characters in variable names follow the `POSIX standard + `_ and are limited + to uppercase letter, digits and the `_` (underscore). + """ + for line_number, line in lines_enum: + for env_var, var_name in ENV_VAR_RE.findall(line): + value = os.getenv(var_name) + if not value: + continue + + line = line.replace(env_var, value) + + yield line_number, line diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_install.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_install.py new file mode 100644 index 0000000..ddd167c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_install.py @@ -0,0 +1,1115 @@ +from __future__ import absolute_import + +import logging +import os +import re +import shutil +import sys +import sysconfig +import traceback +import warnings +import zipfile +from distutils.util import change_root +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources, pytoml, six +from pip._vendor.packaging import specifiers +from pip._vendor.packaging.markers import Marker +from pip._vendor.packaging.requirements import InvalidRequirement, Requirement +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.packaging.version import Version +from pip._vendor.pkg_resources import RequirementParseError, parse_requirements + +from pip._internal import wheel +from pip._internal.build_env import BuildEnvironment +from pip._internal.compat import native_str +from pip._internal.download import ( + is_archive_file, is_url, path_to_url, url_to_path, +) +from pip._internal.exceptions import InstallationError, UninstallationError +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, running_under_virtualenv, +) +from pip._internal.req.req_uninstall import UninstallPathSet +from pip._internal.utils.deprecation import RemovedInPip11Warning +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + _make_build_dir, ask_path_exists, backup_dir, call_subprocess, + display_path, dist_in_site_packages, dist_in_usersite, ensure_dir, + get_installed_version, is_installable_dir, read_text_file, rmtree, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import open_spinner +from pip._internal.vcs import vcs +from pip._internal.wheel import Wheel, move_wheel_files + +logger = logging.getLogger(__name__) + +operators = specifiers.Specifier._operators.keys() + + +def _strip_extras(path): + m = re.match(r'^(.+)(\[[^\]]+\])$', path) + extras = None + if m: + path_no_extras = m.group(1) + extras = m.group(2) + else: + path_no_extras = path + + return path_no_extras, extras + + +class InstallRequirement(object): + """ + Represents something that may be installed later on, may have information + about where to fetch the relavant requirement and also contains logic for + installing the said requirement. + """ + + def __init__(self, req, comes_from, source_dir=None, editable=False, + link=None, update=True, markers=None, + isolated=False, options=None, wheel_cache=None, + constraint=False, extras=()): + assert req is None or isinstance(req, Requirement), req + self.req = req + self.comes_from = comes_from + self.constraint = constraint + if source_dir is not None: + self.source_dir = os.path.normpath(os.path.abspath(source_dir)) + else: + self.source_dir = None + self.editable = editable + + self._wheel_cache = wheel_cache + if link is not None: + self.link = self.original_link = link + else: + from pip._internal.index import Link + self.link = self.original_link = req and req.url and Link(req.url) + + if extras: + self.extras = extras + elif req: + self.extras = { + pkg_resources.safe_extra(extra) for extra in req.extras + } + else: + self.extras = set() + if markers is not None: + self.markers = markers + else: + self.markers = req and req.marker + self._egg_info_path = None + # This holds the pkg_resources.Distribution object if this requirement + # is already available: + self.satisfied_by = None + # This hold the pkg_resources.Distribution object if this requirement + # conflicts with another installed distribution: + self.conflicts_with = None + # Temporary build location + self._temp_build_dir = TempDirectory(kind="req-build") + # Used to store the global directory where the _temp_build_dir should + # have been created. Cf _correct_build_location method. + self._ideal_build_dir = None + # True if the editable should be updated: + self.update = update + # Set to True after successful installation + self.install_succeeded = None + # UninstallPathSet of uninstalled distribution (for possible rollback) + self.uninstalled_pathset = None + self.options = options if options else {} + # Set to True after successful preparation of this requirement + self.prepared = False + self.is_direct = False + + self.isolated = isolated + self.build_env = BuildEnvironment(no_clean=True) + + @classmethod + def from_editable(cls, editable_req, comes_from=None, isolated=False, + options=None, wheel_cache=None, constraint=False): + from pip._internal.index import Link + + name, url, extras_override = parse_editable(editable_req) + if url.startswith('file:'): + source_dir = url_to_path(url) + else: + source_dir = None + + if name is not None: + try: + req = Requirement(name) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % name) + else: + req = None + return cls( + req, comes_from, source_dir=source_dir, + editable=True, + link=Link(url), + constraint=constraint, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + extras=extras_override or (), + ) + + @classmethod + def from_req(cls, req, comes_from=None, isolated=False, wheel_cache=None): + try: + req = Requirement(req) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % req) + if req.url: + raise InstallationError( + "Direct url requirement (like %s) are not allowed for " + "dependencies" % req + ) + return cls(req, comes_from, isolated=isolated, wheel_cache=wheel_cache) + + @classmethod + def from_line( + cls, name, comes_from=None, isolated=False, options=None, + wheel_cache=None, constraint=False): + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + """ + from pip._internal.index import Link + + if is_url(name): + marker_sep = '; ' + else: + marker_sep = ';' + if marker_sep in name: + name, markers = name.split(marker_sep, 1) + markers = markers.strip() + if not markers: + markers = None + else: + markers = Marker(markers) + else: + markers = None + name = name.strip() + req = None + path = os.path.normpath(os.path.abspath(name)) + link = None + extras = None + + if is_url(name): + link = Link(name) + else: + p, extras = _strip_extras(path) + looks_like_dir = os.path.isdir(p) and ( + os.path.sep in name or + (os.path.altsep is not None and os.path.altsep in name) or + name.startswith('.') + ) + if looks_like_dir: + if not is_installable_dir(p): + raise InstallationError( + "Directory %r is not installable. File 'setup.py' " + "not found." % name + ) + link = Link(path_to_url(p)) + elif is_archive_file(p): + if not os.path.isfile(p): + logger.warning( + 'Requirement %r looks like a filename, but the ' + 'file does not exist', + name + ) + link = Link(path_to_url(p)) + + # it's a local file, dir, or url + if link: + # Handle relative file URLs + if link.scheme == 'file' and re.search(r'\.\./', link.url): + link = Link( + path_to_url(os.path.normpath(os.path.abspath(link.path)))) + # wheel file + if link.is_wheel: + wheel = Wheel(link.filename) # can raise InvalidWheelFilename + req = "%s==%s" % (wheel.name, wheel.version) + else: + # set the req to the egg fragment. when it's not there, this + # will become an 'unnamed' requirement + req = link.egg_fragment + + # a requirement specifier + else: + req = name + + if extras: + extras = Requirement("placeholder" + extras.lower()).extras + else: + extras = () + if req is not None: + try: + req = Requirement(req) + except InvalidRequirement: + if os.path.sep in req: + add_msg = "It looks like a path." + add_msg += deduce_helpful_msg(req) + elif '=' in req and not any(op in req for op in operators): + add_msg = "= is not a valid operator. Did you mean == ?" + else: + add_msg = traceback.format_exc() + raise InstallationError( + "Invalid requirement: '%s'\n%s" % (req, add_msg)) + return cls( + req, comes_from, link=link, markers=markers, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + constraint=constraint, + extras=extras, + ) + + def __str__(self): + if self.req: + s = str(self.req) + if self.link: + s += ' from %s' % self.link.url + else: + s = self.link.url if self.link else None + if self.satisfied_by is not None: + s += ' in %s' % display_path(self.satisfied_by.location) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += ' (from %s)' % comes_from + return s + + def __repr__(self): + return '<%s object: %s editable=%r>' % ( + self.__class__.__name__, str(self), self.editable) + + def populate_link(self, finder, upgrade, require_hashes): + """Ensure that if a link can be found for this, that it is found. + + Note that self.link may still be None - if Upgrade is False and the + requirement is already installed. + + If require_hashes is True, don't use the wheel cache, because cached + wheels, always built locally, have different hashes than the files + downloaded from the index server and thus throw false hash mismatches. + Furthermore, cached wheels at present have undeterministic contents due + to file modification times. + """ + if self.link is None: + self.link = finder.find_requirement(self, upgrade) + if self._wheel_cache is not None and not require_hashes: + old_link = self.link + self.link = self._wheel_cache.get(self.link, self.name) + if old_link != self.link: + logger.debug('Using cached wheel link: %s', self.link) + + @property + def specifier(self): + return self.req.specifier + + @property + def is_pinned(self): + """Return whether I am pinned to an exact version. + + For example, some-package==1.2 is pinned; some-package>1.2 is not. + """ + specifiers = self.specifier + return (len(specifiers) == 1 and + next(iter(specifiers)).operator in {'==', '==='}) + + def from_path(self): + if self.req is None: + return None + s = str(self.req) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += '->' + comes_from + return s + + def build_location(self, build_dir): + assert build_dir is not None + if self._temp_build_dir.path is not None: + return self._temp_build_dir.path + if self.req is None: + # for requirement via a path to a directory: the name of the + # package is not available yet so we create a temp directory + # Once run_egg_info will have run, we'll be able + # to fix it via _correct_build_location + # Some systems have /tmp as a symlink which confuses custom + # builds (such as numpy). Thus, we ensure that the real path + # is returned. + self._temp_build_dir.create() + self._ideal_build_dir = build_dir + + return self._temp_build_dir.path + if self.editable: + name = self.name.lower() + else: + name = self.name + # FIXME: Is there a better place to create the build_dir? (hg and bzr + # need this) + if not os.path.exists(build_dir): + logger.debug('Creating directory %s', build_dir) + _make_build_dir(build_dir) + return os.path.join(build_dir, name) + + def _correct_build_location(self): + """Move self._temp_build_dir to self._ideal_build_dir/self.req.name + + For some requirements (e.g. a path to a directory), the name of the + package is not available until we run egg_info, so the build_location + will return a temporary directory and store the _ideal_build_dir. + + This is only called by self.egg_info_path to fix the temporary build + directory. + """ + if self.source_dir is not None: + return + assert self.req is not None + assert self._temp_build_dir.path + assert self._ideal_build_dir.path + old_location = self._temp_build_dir.path + self._temp_build_dir.path = None + + new_location = self.build_location(self._ideal_build_dir) + if os.path.exists(new_location): + raise InstallationError( + 'A package already exists in %s; please remove it to continue' + % display_path(new_location)) + logger.debug( + 'Moving package %s from %s to new location %s', + self, display_path(old_location), display_path(new_location), + ) + shutil.move(old_location, new_location) + self._temp_build_dir.path = new_location + self._ideal_build_dir = None + self.source_dir = os.path.normpath(os.path.abspath(new_location)) + self._egg_info_path = None + + @property + def name(self): + if self.req is None: + return None + return native_str(pkg_resources.safe_name(self.req.name)) + + @property + def setup_py_dir(self): + return os.path.join( + self.source_dir, + self.link and self.link.subdirectory_fragment or '') + + @property + def setup_py(self): + assert self.source_dir, "No source dir for %s" % self + + setup_py = os.path.join(self.setup_py_dir, 'setup.py') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(setup_py, six.text_type): + setup_py = setup_py.encode(sys.getfilesystemencoding()) + + return setup_py + + @property + def pyproject_toml(self): + assert self.source_dir, "No source dir for %s" % self + + pp_toml = os.path.join(self.setup_py_dir, 'pyproject.toml') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(pp_toml, six.text_type): + pp_toml = pp_toml.encode(sys.getfilesystemencoding()) + + return pp_toml + + def get_pep_518_info(self): + """Get a list of the packages required to build the project, if any, + and a flag indicating whether pyproject.toml is present, indicating + that the build should be isolated. + + Build requirements can be specified in a pyproject.toml, as described + in PEP 518. If this file exists but doesn't specify build + requirements, pip will default to installing setuptools and wheel. + """ + if os.path.isfile(self.pyproject_toml): + with open(self.pyproject_toml) as f: + pp_toml = pytoml.load(f) + build_sys = pp_toml.get('build-system', {}) + return (build_sys.get('requires', ['setuptools', 'wheel']), True) + return (['setuptools', 'wheel'], False) + + def run_egg_info(self): + assert self.source_dir + if self.name: + logger.debug( + 'Running setup.py (path:%s) egg_info for package %s', + self.setup_py, self.name, + ) + else: + logger.debug( + 'Running setup.py (path:%s) egg_info for package from %s', + self.setup_py, self.link, + ) + + with indent_log(): + script = SETUPTOOLS_SHIM % self.setup_py + base_cmd = [sys.executable, '-c', script] + if self.isolated: + base_cmd += ["--no-user-cfg"] + egg_info_cmd = base_cmd + ['egg_info'] + # We can't put the .egg-info files at the root, because then the + # source code will be mistaken for an installed egg, causing + # problems + if self.editable: + egg_base_option = [] + else: + egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info') + ensure_dir(egg_info_dir) + egg_base_option = ['--egg-base', 'pip-egg-info'] + with self.build_env: + call_subprocess( + egg_info_cmd + egg_base_option, + cwd=self.setup_py_dir, + show_stdout=False, + command_desc='python setup.py egg_info') + + if not self.req: + if isinstance(parse_version(self.pkg_info()["Version"]), Version): + op = "==" + else: + op = "===" + self.req = Requirement( + "".join([ + self.pkg_info()["Name"], + op, + self.pkg_info()["Version"], + ]) + ) + self._correct_build_location() + else: + metadata_name = canonicalize_name(self.pkg_info()["Name"]) + if canonicalize_name(self.req.name) != metadata_name: + logger.warning( + 'Running setup.py (path:%s) egg_info for package %s ' + 'produced metadata for project name %s. Fix your ' + '#egg=%s fragments.', + self.setup_py, self.name, metadata_name, self.name + ) + self.req = Requirement(metadata_name) + + def egg_info_data(self, filename): + if self.satisfied_by is not None: + if not self.satisfied_by.has_metadata(filename): + return None + return self.satisfied_by.get_metadata(filename) + assert self.source_dir + filename = self.egg_info_path(filename) + if not os.path.exists(filename): + return None + data = read_text_file(filename) + return data + + def egg_info_path(self, filename): + if self._egg_info_path is None: + if self.editable: + base = self.source_dir + else: + base = os.path.join(self.setup_py_dir, 'pip-egg-info') + filenames = os.listdir(base) + if self.editable: + filenames = [] + for root, dirs, files in os.walk(base): + for dir in vcs.dirnames: + if dir in dirs: + dirs.remove(dir) + # Iterate over a copy of ``dirs``, since mutating + # a list while iterating over it can cause trouble. + # (See https://github.com/pypa/pip/pull/462.) + for dir in list(dirs): + # Don't search in anything that looks like a virtualenv + # environment + if ( + os.path.lexists( + os.path.join(root, dir, 'bin', 'python') + ) or + os.path.exists( + os.path.join( + root, dir, 'Scripts', 'Python.exe' + ) + )): + dirs.remove(dir) + # Also don't search through tests + elif dir == 'test' or dir == 'tests': + dirs.remove(dir) + filenames.extend([os.path.join(root, dir) + for dir in dirs]) + filenames = [f for f in filenames if f.endswith('.egg-info')] + + if not filenames: + raise InstallationError( + 'No files/directories in %s (from %s)' % (base, filename) + ) + assert filenames, \ + "No files/directories in %s (from %s)" % (base, filename) + + # if we have more than one match, we pick the toplevel one. This + # can easily be the case if there is a dist folder which contains + # an extracted tarball for testing purposes. + if len(filenames) > 1: + filenames.sort( + key=lambda x: x.count(os.path.sep) + + (os.path.altsep and x.count(os.path.altsep) or 0) + ) + self._egg_info_path = os.path.join(base, filenames[0]) + return os.path.join(self._egg_info_path, filename) + + def pkg_info(self): + p = FeedParser() + data = self.egg_info_data('PKG-INFO') + if not data: + logger.warning( + 'No PKG-INFO file found in %s', + display_path(self.egg_info_path('PKG-INFO')), + ) + p.feed(data or '') + return p.close() + + _requirements_section_re = re.compile(r'\[(.*?)\]') + + @property + def installed_version(self): + return get_installed_version(self.name) + + def assert_source_matches_version(self): + assert self.source_dir + version = self.pkg_info()['version'] + if self.req.specifier and version not in self.req.specifier: + logger.warning( + 'Requested %s, but installing version %s', + self, + version, + ) + else: + logger.debug( + 'Source in %s has version %s, which satisfies requirement %s', + display_path(self.source_dir), + version, + self, + ) + + def update_editable(self, obtain=True): + if not self.link: + logger.debug( + "Cannot update repository at %s; repository location is " + "unknown", + self.source_dir, + ) + return + assert self.editable + assert self.source_dir + if self.link.scheme == 'file': + # Static paths don't get updated + return + assert '+' in self.link.url, "bad url: %r" % self.link.url + if not self.update: + return + vc_type, url = self.link.url.split('+', 1) + backend = vcs.get_backend(vc_type) + if backend: + vcs_backend = backend(self.link.url) + if obtain: + vcs_backend.obtain(self.source_dir) + else: + vcs_backend.export(self.source_dir) + else: + assert 0, ( + 'Unexpected version control type (in %s): %s' + % (self.link, vc_type)) + + def uninstall(self, auto_confirm=False, verbose=False, + use_user_site=False): + """ + Uninstall the distribution currently satisfying this requirement. + + Prompts before removing or modifying files unless + ``auto_confirm`` is True. + + Refuses to delete or modify files outside of ``sys.prefix`` - + thus uninstallation within a virtual environment can only + modify that virtual environment, even if the virtualenv is + linked to global site-packages. + + """ + if not self.check_if_exists(use_user_site): + logger.warning("Skipping %s as it is not installed.", self.name) + return + dist = self.satisfied_by or self.conflicts_with + + uninstalled_pathset = UninstallPathSet.from_dist(dist) + uninstalled_pathset.remove(auto_confirm, verbose) + return uninstalled_pathset + + def archive(self, build_dir): + assert self.source_dir + create_archive = True + archive_name = '%s-%s.zip' % (self.name, self.pkg_info()["version"]) + archive_path = os.path.join(build_dir, archive_name) + if os.path.exists(archive_path): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' % + display_path(archive_path), ('i', 'w', 'b', 'a')) + if response == 'i': + create_archive = False + elif response == 'w': + logger.warning('Deleting %s', display_path(archive_path)) + os.remove(archive_path) + elif response == 'b': + dest_file = backup_dir(archive_path) + logger.warning( + 'Backing up %s to %s', + display_path(archive_path), + display_path(dest_file), + ) + shutil.move(archive_path, dest_file) + elif response == 'a': + sys.exit(-1) + if create_archive: + zip = zipfile.ZipFile( + archive_path, 'w', zipfile.ZIP_DEFLATED, + allowZip64=True + ) + dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) + for dirpath, dirnames, filenames in os.walk(dir): + if 'pip-egg-info' in dirnames: + dirnames.remove('pip-egg-info') + for dirname in dirnames: + dirname = os.path.join(dirpath, dirname) + name = self._clean_zip_name(dirname, dir) + zipdir = zipfile.ZipInfo(self.name + '/' + name + '/') + zipdir.external_attr = 0x1ED << 16 # 0o755 + zip.writestr(zipdir, '') + for filename in filenames: + if filename == PIP_DELETE_MARKER_FILENAME: + continue + filename = os.path.join(dirpath, filename) + name = self._clean_zip_name(filename, dir) + zip.write(filename, self.name + '/' + name) + zip.close() + logger.info('Saved %s', display_path(archive_path)) + + def _clean_zip_name(self, name, prefix): + assert name.startswith(prefix + os.path.sep), ( + "name %r doesn't start with prefix %r" % (name, prefix) + ) + name = name[len(prefix) + 1:] + name = name.replace(os.path.sep, '/') + return name + + def match_markers(self, extras_requested=None): + if not extras_requested: + # Provide an extra to safely evaluate the markers + # without matching any extra + extras_requested = ('',) + if self.markers is not None: + return any( + self.markers.evaluate({'extra': extra}) + for extra in extras_requested) + else: + return True + + def install(self, install_options, global_options=None, root=None, + home=None, prefix=None, warn_script_location=True, + use_user_site=False, pycompile=True): + global_options = global_options if global_options is not None else [] + if self.editable: + self.install_editable( + install_options, global_options, prefix=prefix, + ) + return + if self.is_wheel: + version = wheel.wheel_version(self.source_dir) + wheel.check_compatibility(version, self.name) + + self.move_wheel_files( + self.source_dir, root=root, prefix=prefix, home=home, + warn_script_location=warn_script_location, + use_user_site=use_user_site, pycompile=pycompile, + ) + self.install_succeeded = True + return + + # Extend the list of global and install options passed on to + # the setup.py call with the ones from the requirements file. + # Options specified in requirements file override those + # specified on the command line, since the last option given + # to setup.py is the one that is used. + global_options = list(global_options) + \ + self.options.get('global_options', []) + install_options = list(install_options) + \ + self.options.get('install_options', []) + + if self.isolated: + global_options = global_options + ["--no-user-cfg"] + + with TempDirectory(kind="record") as temp_dir: + record_filename = os.path.join(temp_dir.path, 'install-record.txt') + install_args = self.get_install_args( + global_options, record_filename, root, prefix, pycompile, + ) + msg = 'Running setup.py install for %s' % (self.name,) + with open_spinner(msg) as spinner: + with indent_log(): + with self.build_env: + call_subprocess( + install_args + install_options, + cwd=self.setup_py_dir, + show_stdout=False, + spinner=spinner, + ) + + if not os.path.exists(record_filename): + logger.debug('Record file %s not found', record_filename) + return + self.install_succeeded = True + + def prepend_root(path): + if root is None or not os.path.isabs(path): + return path + else: + return change_root(root, path) + + with open(record_filename) as f: + for line in f: + directory = os.path.dirname(line) + if directory.endswith('.egg-info'): + egg_info_dir = prepend_root(directory) + break + else: + logger.warning( + 'Could not find .egg-info directory in install record' + ' for %s', + self, + ) + # FIXME: put the record somewhere + # FIXME: should this be an error? + return + new_lines = [] + with open(record_filename) as f: + for line in f: + filename = line.strip() + if os.path.isdir(filename): + filename += os.path.sep + new_lines.append( + os.path.relpath(prepend_root(filename), egg_info_dir) + ) + new_lines.sort() + ensure_dir(egg_info_dir) + inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') + with open(inst_files_path, 'w') as f: + f.write('\n'.join(new_lines) + '\n') + + def ensure_has_source_dir(self, parent_dir): + """Ensure that a source_dir is set. + + This will create a temporary build dir if the name of the requirement + isn't known yet. + + :param parent_dir: The ideal pip parent_dir for the source_dir. + Generally src_dir for editables and build_dir for sdists. + :return: self.source_dir + """ + if self.source_dir is None: + self.source_dir = self.build_location(parent_dir) + return self.source_dir + + def get_install_args(self, global_options, record_filename, root, prefix, + pycompile): + install_args = [sys.executable, "-u"] + install_args.append('-c') + install_args.append(SETUPTOOLS_SHIM % self.setup_py) + install_args += list(global_options) + \ + ['install', '--record', record_filename] + install_args += ['--single-version-externally-managed'] + + if root is not None: + install_args += ['--root', root] + if prefix is not None: + install_args += ['--prefix', prefix] + + if pycompile: + install_args += ["--compile"] + else: + install_args += ["--no-compile"] + + if running_under_virtualenv(): + py_ver_str = 'python' + sysconfig.get_python_version() + install_args += ['--install-headers', + os.path.join(sys.prefix, 'include', 'site', + py_ver_str, self.name)] + + return install_args + + def remove_temporary_source(self): + """Remove the source files from this requirement, if they are marked + for deletion""" + if self.source_dir and os.path.exists( + os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)): + logger.debug('Removing source in %s', self.source_dir) + rmtree(self.source_dir) + self.source_dir = None + self._temp_build_dir.cleanup() + self.build_env.cleanup() + + def install_editable(self, install_options, + global_options=(), prefix=None): + logger.info('Running setup.py develop for %s', self.name) + + if self.isolated: + global_options = list(global_options) + ["--no-user-cfg"] + + if prefix: + prefix_param = ['--prefix={}'.format(prefix)] + install_options = list(install_options) + prefix_param + + with indent_log(): + # FIXME: should we do --install-headers here too? + with self.build_env: + call_subprocess( + [ + sys.executable, + '-c', + SETUPTOOLS_SHIM % self.setup_py + ] + + list(global_options) + + ['develop', '--no-deps'] + + list(install_options), + + cwd=self.setup_py_dir, + show_stdout=False, + ) + + self.install_succeeded = True + + def check_if_exists(self, use_user_site): + """Find an installed distribution that satisfies or conflicts + with this requirement, and set self.satisfied_by or + self.conflicts_with appropriately. + """ + if self.req is None: + return False + try: + # get_distribution() will resolve the entire list of requirements + # anyway, and we've already determined that we need the requirement + # in question, so strip the marker so that we don't try to + # evaluate it. + no_marker = Requirement(str(self.req)) + no_marker.marker = None + self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) + if self.editable and self.satisfied_by: + self.conflicts_with = self.satisfied_by + # when installing editables, nothing pre-existing should ever + # satisfy + self.satisfied_by = None + return True + except pkg_resources.DistributionNotFound: + return False + except pkg_resources.VersionConflict: + existing_dist = pkg_resources.get_distribution( + self.req.name + ) + if use_user_site: + if dist_in_usersite(existing_dist): + self.conflicts_with = existing_dist + elif (running_under_virtualenv() and + dist_in_site_packages(existing_dist)): + raise InstallationError( + "Will not install to the user site because it will " + "lack sys.path precedence to %s in %s" % + (existing_dist.project_name, existing_dist.location) + ) + else: + self.conflicts_with = existing_dist + return True + + @property + def is_wheel(self): + return self.link and self.link.is_wheel + + def move_wheel_files(self, wheeldir, root=None, home=None, prefix=None, + warn_script_location=True, use_user_site=False, + pycompile=True): + move_wheel_files( + self.name, self.req, wheeldir, + user=use_user_site, + home=home, + root=root, + prefix=prefix, + pycompile=pycompile, + isolated=self.isolated, + warn_script_location=warn_script_location, + ) + + def get_dist(self): + """Return a pkg_resources.Distribution built from self.egg_info_path""" + egg_info = self.egg_info_path('').rstrip(os.path.sep) + base_dir = os.path.dirname(egg_info) + metadata = pkg_resources.PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + return pkg_resources.Distribution( + os.path.dirname(egg_info), + project_name=dist_name, + metadata=metadata, + ) + + @property + def has_hash_options(self): + """Return whether any known-good hashes are specified as options. + + These activate --require-hashes mode; hashes specified as part of a + URL do not. + + """ + return bool(self.options.get('hashes', {})) + + def hashes(self, trust_internet=True): + """Return a hash-comparer that considers my option- and URL-based + hashes to be known-good. + + Hashes in URLs--ones embedded in the requirements file, not ones + downloaded from an index server--are almost peers with ones from + flags. They satisfy --require-hashes (whether it was implicitly or + explicitly activated) but do not activate it. md5 and sha224 are not + allowed in flags, which should nudge people toward good algos. We + always OR all hashes together, even ones from URLs. + + :param trust_internet: Whether to trust URL-based (#md5=...) hashes + downloaded from the internet, as by populate_link() + + """ + good_hashes = self.options.get('hashes', {}).copy() + link = self.link if trust_internet else self.original_link + if link and link.hash: + good_hashes.setdefault(link.hash_name, []).append(link.hash) + return Hashes(good_hashes) + + +def _strip_postfix(req): + """ + Strip req postfix ( -dev, 0.2, etc ) + """ + # FIXME: use package_to_requirement? + match = re.search(r'^(.*?)(?:-dev|-\d.*)$', req) + if match: + # Strip off -dev, -0.2, etc. + warnings.warn( + "#egg cleanup for editable urls will be dropped in the future", + RemovedInPip11Warning, + ) + req = match.group(1) + return req + + +def parse_editable(editable_req): + """Parses an editable requirement into: + - a requirement name + - an URL + - extras + - editable options + Accepted requirements: + svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir + .[some_extra] + """ + + from pip._internal.index import Link + + url = editable_req + + # If a file path is specified with extras, strip off the extras. + url_no_extras, extras = _strip_extras(url) + + if os.path.isdir(url_no_extras): + if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): + raise InstallationError( + "Directory %r is not installable. File 'setup.py' not found." % + url_no_extras + ) + # Treating it as code that has already been checked out + url_no_extras = path_to_url(url_no_extras) + + if url_no_extras.lower().startswith('file:'): + package_name = Link(url_no_extras).egg_fragment + if extras: + return ( + package_name, + url_no_extras, + Requirement("placeholder" + extras.lower()).extras, + ) + else: + return package_name, url_no_extras, None + + for version_control in vcs: + if url.lower().startswith('%s:' % version_control): + url = '%s+%s' % (version_control, url) + break + + if '+' not in url: + raise InstallationError( + '%s should either be a path to a local project or a VCS url ' + 'beginning with svn+, git+, hg+, or bzr+' % + editable_req + ) + + vc_type = url.split('+', 1)[0].lower() + + if not vcs.get_backend(vc_type): + error_message = 'For --editable=%s only ' % editable_req + \ + ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \ + ' is currently supported' + raise InstallationError(error_message) + + package_name = Link(url).egg_fragment + if not package_name: + raise InstallationError( + "Could not detect requirement name for '%s', please specify one " + "with #egg=your_package_name" % editable_req + ) + return _strip_postfix(package_name), url, None + + +def deduce_helpful_msg(req): + """Returns helpful msg in case requirements file does not exist, + or cannot be parsed. + + :params req: Requirements file path + """ + msg = "" + if os.path.exists(req): + msg = " It does exist." + # Try to parse and check if it is a requirements file. + try: + with open(req, 'r') as fp: + # parse first line only + next(parse_requirements(fp.read())) + msg += " The argument you provided " + \ + "(%s) appears to be a" % (req) + \ + " requirements file. If that is the" + \ + " case, use the '-r' flag to install" + \ + " the packages specified within it." + except RequirementParseError: + logger.debug("Cannot parse '%s' as requirements \ + file" % (req), exc_info=1) + else: + msg += " File '%s' does not exist." % (req) + return msg diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_set.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_set.py new file mode 100644 index 0000000..b2b55f8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_set.py @@ -0,0 +1,164 @@ +from __future__ import absolute_import + +import logging +from collections import OrderedDict + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.logging import indent_log +from pip._internal.wheel import Wheel + +logger = logging.getLogger(__name__) + + +class RequirementSet(object): + + def __init__(self, require_hashes=False): + """Create a RequirementSet. + + :param wheel_cache: The pip wheel cache, for passing to + InstallRequirement. + """ + + self.requirements = OrderedDict() + self.require_hashes = require_hashes + + # Mapping of alias: real_name + self.requirement_aliases = {} + self.unnamed_requirements = [] + self.successfully_downloaded = [] + self.reqs_to_cleanup = [] + + def __str__(self): + reqs = [req for req in self.requirements.values() + if not req.comes_from] + reqs.sort(key=lambda req: req.name.lower()) + return ' '.join([str(req.req) for req in reqs]) + + def __repr__(self): + reqs = [req for req in self.requirements.values()] + reqs.sort(key=lambda req: req.name.lower()) + reqs_str = ', '.join([str(req.req) for req in reqs]) + return ('<%s object; %d requirement(s): %s>' + % (self.__class__.__name__, len(reqs), reqs_str)) + + def add_requirement(self, install_req, parent_req_name=None, + extras_requested=None): + """Add install_req as a requirement to install. + + :param parent_req_name: The name of the requirement that needed this + added. The name is used because when multiple unnamed requirements + resolve to the same name, we could otherwise end up with dependency + links that point outside the Requirements set. parent_req must + already be added. Note that None implies that this is a user + supplied requirement, vs an inferred one. + :param extras_requested: an iterable of extras used to evaluate the + environment markers. + :return: Additional requirements to scan. That is either [] if + the requirement is not applicable, or [install_req] if the + requirement is applicable and has just been added. + """ + name = install_req.name + if not install_req.match_markers(extras_requested): + logger.info("Ignoring %s: markers '%s' don't match your " + "environment", install_req.name, + install_req.markers) + return [], None + + # This check has to come after we filter requirements with the + # environment markers. + if install_req.link and install_req.link.is_wheel: + wheel = Wheel(install_req.link.filename) + if not wheel.supported(): + raise InstallationError( + "%s is not a supported wheel on this platform." % + wheel.filename + ) + + # This next bit is really a sanity check. + assert install_req.is_direct == (parent_req_name is None), ( + "a direct req shouldn't have a parent and also, " + "a non direct req should have a parent" + ) + + if not name: + # url or path requirement w/o an egg fragment + self.unnamed_requirements.append(install_req) + return [install_req], None + else: + try: + existing_req = self.get_requirement(name) + except KeyError: + existing_req = None + if (parent_req_name is None and existing_req and not + existing_req.constraint and + existing_req.extras == install_req.extras and not + existing_req.req.specifier == install_req.req.specifier): + raise InstallationError( + 'Double requirement given: %s (already in %s, name=%r)' + % (install_req, existing_req, name)) + if not existing_req: + # Add requirement + self.requirements[name] = install_req + # FIXME: what about other normalizations? E.g., _ vs. -? + if name.lower() != name: + self.requirement_aliases[name.lower()] = name + result = [install_req] + else: + # Assume there's no need to scan, and that we've already + # encountered this for scanning. + result = [] + if not install_req.constraint and existing_req.constraint: + if (install_req.link and not (existing_req.link and + install_req.link.path == existing_req.link.path)): + self.reqs_to_cleanup.append(install_req) + raise InstallationError( + "Could not satisfy constraints for '%s': " + "installation from path or url cannot be " + "constrained to a version" % name, + ) + # If we're now installing a constraint, mark the existing + # object for real installation. + existing_req.constraint = False + existing_req.extras = tuple( + sorted(set(existing_req.extras).union( + set(install_req.extras)))) + logger.debug("Setting %s extras to: %s", + existing_req, existing_req.extras) + # And now we need to scan this. + result = [existing_req] + # Canonicalise to the already-added object for the backref + # check below. + install_req = existing_req + + # We return install_req here to allow for the caller to add it to + # the dependency information for the parent package. + return result, install_req + + def has_requirement(self, project_name): + name = project_name.lower() + if (name in self.requirements and + not self.requirements[name].constraint or + name in self.requirement_aliases and + not self.requirements[self.requirement_aliases[name]].constraint): + return True + return False + + @property + def has_requirements(self): + return list(req for req in self.requirements.values() if not + req.constraint) or self.unnamed_requirements + + def get_requirement(self, project_name): + for name in project_name, project_name.lower(): + if name in self.requirements: + return self.requirements[name] + if name in self.requirement_aliases: + return self.requirements[self.requirement_aliases[name]] + raise KeyError("No project with the name %r" % project_name) + + def cleanup_files(self): + """Clean up files, remove builds.""" + logger.debug('Cleaning up...') + with indent_log(): + for req in self.reqs_to_cleanup: + req.remove_temporary_source() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_uninstall.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_uninstall.py new file mode 100644 index 0000000..a3cc7bf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/req/req_uninstall.py @@ -0,0 +1,455 @@ +from __future__ import absolute_import + +import csv +import functools +import logging +import os +import sys +import sysconfig + +from pip._vendor import pkg_resources + +from pip._internal.compat import WINDOWS, cache_from_source, uses_pycache +from pip._internal.exceptions import UninstallationError +from pip._internal.locations import bin_py, bin_user +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local, + normalize_path, renames, +) +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +def _script_names(dist, script_name, is_gui): + """Create the fully qualified name of the files created by + {console,gui}_scripts for the given ``dist``. + Returns the list of file names + """ + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + exe_name = os.path.join(bin_dir, script_name) + paths_to_remove = [exe_name] + if WINDOWS: + paths_to_remove.append(exe_name + '.exe') + paths_to_remove.append(exe_name + '.exe.manifest') + if is_gui: + paths_to_remove.append(exe_name + '-script.pyw') + else: + paths_to_remove.append(exe_name + '-script.py') + return paths_to_remove + + +def _unique(fn): + @functools.wraps(fn) + def unique(*args, **kw): + seen = set() + for item in fn(*args, **kw): + if item not in seen: + seen.add(item) + yield item + return unique + + +@_unique +def uninstallation_paths(dist): + """ + Yield all the uninstallation paths for dist based on RECORD-without-.pyc + + Yield paths to all the files in RECORD. For each .py file in RECORD, add + the .pyc in the same directory. + + UninstallPathSet.add() takes care of the __pycache__ .pyc. + """ + r = csv.reader(FakeFile(dist.get_metadata_lines('RECORD'))) + for row in r: + path = os.path.join(dist.location, row[0]) + yield path + if path.endswith('.py'): + dn, fn = os.path.split(path) + base = fn[:-3] + path = os.path.join(dn, base + '.pyc') + yield path + + +def compact(paths): + """Compact a path set to contain the minimal number of paths + necessary to contain all paths in the set. If /a/path/ and + /a/path/to/a/file.txt are both in the set, leave only the + shorter path.""" + + sep = os.path.sep + short_paths = set() + for path in sorted(paths, key=len): + should_add = any( + path.startswith(shortpath.rstrip("*")) and + path[len(shortpath.rstrip("*").rstrip(sep))] == sep + for shortpath in short_paths + ) + if not should_add: + short_paths.add(path) + return short_paths + + +def compress_for_output_listing(paths): + """Returns a tuple of 2 sets of which paths to display to user + + The first set contains paths that would be deleted. Files of a package + are not added and the top-level directory of the package has a '*' added + at the end - to signify that all it's contents are removed. + + The second set contains files that would have been skipped in the above + folders. + """ + + will_remove = list(paths) + will_skip = set() + + # Determine folders and files + folders = set() + files = set() + for path in will_remove: + if path.endswith(".pyc"): + continue + if path.endswith("__init__.py") or ".dist-info" in path: + folders.add(os.path.dirname(path)) + files.add(path) + + folders = compact(folders) + + # This walks the tree using os.walk to not miss extra folders + # that might get added. + for folder in folders: + for dirpath, _, dirfiles in os.walk(folder): + for fname in dirfiles: + if fname.endswith(".pyc"): + continue + + file_ = os.path.normcase(os.path.join(dirpath, fname)) + if os.path.isfile(file_) and file_ not in files: + # We are skipping this file. Add it to the set. + will_skip.add(file_) + + will_remove = files | { + os.path.join(folder, "*") for folder in folders + } + + return will_remove, will_skip + + +class UninstallPathSet(object): + """A set of file paths to be removed in the uninstallation of a + requirement.""" + def __init__(self, dist): + self.paths = set() + self._refuse = set() + self.pth = {} + self.dist = dist + self.save_dir = TempDirectory(kind="uninstall") + self._moved_paths = [] + + def _permitted(self, path): + """ + Return True if the given path is one we are permitted to + remove/modify, False otherwise. + + """ + return is_local(path) + + def add(self, path): + head, tail = os.path.split(path) + + # we normalize the head to resolve parent directory symlinks, but not + # the tail, since we only want to uninstall symlinks, not their targets + path = os.path.join(normalize_path(head), os.path.normcase(tail)) + + if not os.path.exists(path): + return + if self._permitted(path): + self.paths.add(path) + else: + self._refuse.add(path) + + # __pycache__ files can show up after 'installed-files.txt' is created, + # due to imports + if os.path.splitext(path)[1] == '.py' and uses_pycache: + self.add(cache_from_source(path)) + + def add_pth(self, pth_file, entry): + pth_file = normalize_path(pth_file) + if self._permitted(pth_file): + if pth_file not in self.pth: + self.pth[pth_file] = UninstallPthEntries(pth_file) + self.pth[pth_file].add(entry) + else: + self._refuse.add(pth_file) + + def _stash(self, path): + return os.path.join( + self.save_dir.path, os.path.splitdrive(path)[1].lstrip(os.path.sep) + ) + + def remove(self, auto_confirm=False, verbose=False): + """Remove paths in ``self.paths`` with confirmation (unless + ``auto_confirm`` is True).""" + + if not self.paths: + logger.info( + "Can't uninstall '%s'. No files were found to uninstall.", + self.dist.project_name, + ) + return + + dist_name_version = ( + self.dist.project_name + "-" + self.dist.version + ) + logger.info('Uninstalling %s:', dist_name_version) + + with indent_log(): + if auto_confirm or self._allowed_to_proceed(verbose): + self.save_dir.create() + + for path in sorted(compact(self.paths)): + new_path = self._stash(path) + logger.debug('Removing file or directory %s', path) + self._moved_paths.append(path) + renames(path, new_path) + for pth in self.pth.values(): + pth.remove() + + logger.info('Successfully uninstalled %s', dist_name_version) + + def _allowed_to_proceed(self, verbose): + """Display which files would be deleted and prompt for confirmation + """ + + def _display(msg, paths): + if not paths: + return + + logger.info(msg) + with indent_log(): + for path in sorted(compact(paths)): + logger.info(path) + + if not verbose: + will_remove, will_skip = compress_for_output_listing(self.paths) + else: + # In verbose mode, display all the files that are going to be + # deleted. + will_remove = list(self.paths) + will_skip = set() + + _display('Would remove:', will_remove) + _display('Would not remove (might be manually added):', will_skip) + _display('Would not remove (outside of prefix):', self._refuse) + + return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' + + def rollback(self): + """Rollback the changes previously made by remove().""" + if self.save_dir.path is None: + logger.error( + "Can't roll back %s; was not uninstalled", + self.dist.project_name, + ) + return False + logger.info('Rolling back uninstall of %s', self.dist.project_name) + for path in self._moved_paths: + tmp_path = self._stash(path) + logger.debug('Replacing %s', path) + renames(tmp_path, path) + for pth in self.pth.values(): + pth.rollback() + + def commit(self): + """Remove temporary save dir: rollback will no longer be possible.""" + self.save_dir.cleanup() + self._moved_paths = [] + + @classmethod + def from_dist(cls, dist): + dist_path = normalize_path(dist.location) + if not dist_is_local(dist): + logger.info( + "Not uninstalling %s at %s, outside environment %s", + dist.key, + dist_path, + sys.prefix, + ) + return cls(dist) + + if dist_path in {p for p in {sysconfig.get_path("stdlib"), + sysconfig.get_path("platstdlib")} + if p}: + logger.info( + "Not uninstalling %s at %s, as it is in the standard library.", + dist.key, + dist_path, + ) + return cls(dist) + + paths_to_remove = cls(dist) + develop_egg_link = egg_link_path(dist) + develop_egg_link_egg_info = '{}.egg-info'.format( + pkg_resources.to_filename(dist.project_name)) + egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) + # Special case for distutils installed package + distutils_egg_info = getattr(dist._provider, 'path', None) + + # Uninstall cases order do matter as in the case of 2 installs of the + # same package, pip needs to uninstall the currently detected version + if (egg_info_exists and dist.egg_info.endswith('.egg-info') and + not dist.egg_info.endswith(develop_egg_link_egg_info)): + # if dist.egg_info.endswith(develop_egg_link_egg_info), we + # are in fact in the develop_egg_link case + paths_to_remove.add(dist.egg_info) + if dist.has_metadata('installed-files.txt'): + for installed_file in dist.get_metadata( + 'installed-files.txt').splitlines(): + path = os.path.normpath( + os.path.join(dist.egg_info, installed_file) + ) + paths_to_remove.add(path) + # FIXME: need a test for this elif block + # occurs with --single-version-externally-managed/--record outside + # of pip + elif dist.has_metadata('top_level.txt'): + if dist.has_metadata('namespace_packages.txt'): + namespaces = dist.get_metadata('namespace_packages.txt') + else: + namespaces = [] + for top_level_pkg in [ + p for p + in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces]: + path = os.path.join(dist.location, top_level_pkg) + paths_to_remove.add(path) + paths_to_remove.add(path + '.py') + paths_to_remove.add(path + '.pyc') + paths_to_remove.add(path + '.pyo') + + elif distutils_egg_info: + raise UninstallationError( + "Cannot uninstall {!r}. It is a distutils installed project " + "and thus we cannot accurately determine which files belong " + "to it which would lead to only a partial uninstall.".format( + dist.project_name, + ) + ) + + elif dist.location.endswith('.egg'): + # package installed by easy_install + # We cannot match on dist.egg_name because it can slightly vary + # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg + paths_to_remove.add(dist.location) + easy_install_egg = os.path.split(dist.location)[1] + easy_install_pth = os.path.join(os.path.dirname(dist.location), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) + + elif egg_info_exists and dist.egg_info.endswith('.dist-info'): + for path in uninstallation_paths(dist): + paths_to_remove.add(path) + + elif develop_egg_link: + # develop egg + with open(develop_egg_link, 'r') as fh: + link_pointer = os.path.normcase(fh.readline().strip()) + assert (link_pointer == dist.location), ( + 'Egg-link %s does not match installed location of %s ' + '(at %s)' % (link_pointer, dist.project_name, dist.location) + ) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + + else: + logger.debug( + 'Not sure how to uninstall: %s - Check: %s', + dist, dist.location, + ) + + # find distutils scripts= scripts + if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): + for script in dist.metadata_listdir('scripts'): + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + paths_to_remove.add(os.path.join(bin_dir, script)) + if WINDOWS: + paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') + + # find console_scripts + _scripts_to_remove = [] + console_scripts = dist.get_entry_map(group='console_scripts') + for name in console_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, False)) + # find gui_scripts + gui_scripts = dist.get_entry_map(group='gui_scripts') + for name in gui_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, True)) + + for s in _scripts_to_remove: + paths_to_remove.add(s) + + return paths_to_remove + + +class UninstallPthEntries(object): + def __init__(self, pth_file): + if not os.path.isfile(pth_file): + raise UninstallationError( + "Cannot remove entries from nonexistent file %s" % pth_file + ) + self.file = pth_file + self.entries = set() + self._saved_lines = None + + def add(self, entry): + entry = os.path.normcase(entry) + # On Windows, os.path.normcase converts the entry to use + # backslashes. This is correct for entries that describe absolute + # paths outside of site-packages, but all the others use forward + # slashes. + if WINDOWS and not os.path.splitdrive(entry)[0]: + entry = entry.replace('\\', '/') + self.entries.add(entry) + + def remove(self): + logger.debug('Removing pth entries from %s:', self.file) + with open(self.file, 'rb') as fh: + # windows uses '\r\n' with py3k, but uses '\n' with py2.x + lines = fh.readlines() + self._saved_lines = lines + if any(b'\r\n' in line for line in lines): + endline = '\r\n' + else: + endline = '\n' + # handle missing trailing newline + if lines and not lines[-1].endswith(endline.encode("utf-8")): + lines[-1] = lines[-1] + endline.encode("utf-8") + for entry in self.entries: + try: + logger.debug('Removing entry: %s', entry) + lines.remove((entry + endline).encode("utf-8")) + except ValueError: + pass + with open(self.file, 'wb') as fh: + fh.writelines(lines) + + def rollback(self): + if self._saved_lines is None: + logger.error( + 'Cannot roll back changes to %s, none were made', self.file + ) + return False + logger.debug('Rolling %s back to previous state', self.file) + with open(self.file, 'wb') as fh: + fh.writelines(self._saved_lines) + return True diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/resolve.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/resolve.py new file mode 100644 index 0000000..3200fca --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/resolve.py @@ -0,0 +1,354 @@ +"""Dependency Resolution + +The dependency resolution in pip is performed as follows: + +for top-level requirements: + a. only one spec allowed per project, regardless of conflicts or not. + otherwise a "double requirement" exception is raised + b. they override sub-dependency requirements. +for sub-dependencies + a. "first found, wins" (where the order is breadth first) +""" + +import logging +from collections import defaultdict +from itertools import chain + +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, + UnsupportedPythonVersion, +) + +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import dist_in_usersite, ensure_dir +from pip._internal.utils.packaging import check_dist_requires_python + +logger = logging.getLogger(__name__) + + +class Resolver(object): + """Resolves which packages need to be installed/uninstalled to perform \ + the requested operation without breaking the requirements of any package. + """ + + _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} + + def __init__(self, preparer, session, finder, wheel_cache, use_user_site, + ignore_dependencies, ignore_installed, ignore_requires_python, + force_reinstall, isolated, upgrade_strategy): + super(Resolver, self).__init__() + assert upgrade_strategy in self._allowed_strategies + + self.preparer = preparer + self.finder = finder + self.session = session + + # NOTE: This would eventually be replaced with a cache that can give + # information about both sdist and wheels transparently. + self.wheel_cache = wheel_cache + + self.require_hashes = None # This is set in resolve + + self.upgrade_strategy = upgrade_strategy + self.force_reinstall = force_reinstall + self.isolated = isolated + self.ignore_dependencies = ignore_dependencies + self.ignore_installed = ignore_installed + self.ignore_requires_python = ignore_requires_python + self.use_user_site = use_user_site + + self._discovered_dependencies = defaultdict(list) + + def resolve(self, requirement_set): + """Resolve what operations need to be done + + As a side-effect of this method, the packages (and their dependencies) + are downloaded, unpacked and prepared for installation. This + preparation is done by ``pip.operations.prepare``. + + Once PyPI has static dependency metadata available, it would be + possible to move the preparation to become a step separated from + dependency resolution. + """ + # make the wheelhouse + if self.preparer.wheel_download_dir: + ensure_dir(self.preparer.wheel_download_dir) + + # If any top-level requirement has a hash specified, enter + # hash-checking mode, which requires hashes from all. + root_reqs = ( + requirement_set.unnamed_requirements + + list(requirement_set.requirements.values()) + ) + self.require_hashes = ( + requirement_set.require_hashes or + any(req.has_hash_options for req in root_reqs) + ) + + # Display where finder is looking for packages + locations = self.finder.get_formatted_locations() + if locations: + logger.info(locations) + + # Actually prepare the files, and collect any exceptions. Most hash + # exceptions cannot be checked ahead of time, because + # req.populate_link() needs to be called before we can make decisions + # based on link type. + discovered_reqs = [] + hash_errors = HashErrors() + for req in chain(root_reqs, discovered_reqs): + try: + discovered_reqs.extend( + self._resolve_one(requirement_set, req) + ) + except HashError as exc: + exc.req = req + hash_errors.append(exc) + + if hash_errors: + raise hash_errors + + def _is_upgrade_allowed(self, req): + if self.upgrade_strategy == "to-satisfy-only": + return False + elif self.upgrade_strategy == "eager": + return True + else: + assert self.upgrade_strategy == "only-if-needed" + return req.is_direct + + def _set_req_to_reinstall(self, req): + """ + Set a requirement to be installed. + """ + # Don't uninstall the conflict if doing a user install and the + # conflict is not a user install. + if not self.use_user_site or dist_in_usersite(req.satisfied_by): + req.conflicts_with = req.satisfied_by + req.satisfied_by = None + + # XXX: Stop passing requirement_set for options + def _check_skip_installed(self, req_to_install): + """Check if req_to_install should be skipped. + + This will check if the req is installed, and whether we should upgrade + or reinstall it, taking into account all the relevant user options. + + After calling this req_to_install will only have satisfied_by set to + None if the req_to_install is to be upgraded/reinstalled etc. Any + other value will be a dist recording the current thing installed that + satisfies the requirement. + + Note that for vcs urls and the like we can't assess skipping in this + routine - we simply identify that we need to pull the thing down, + then later on it is pulled down and introspected to assess upgrade/ + reinstalls etc. + + :return: A text reason for why it was skipped, or None. + """ + if self.ignore_installed: + return None + + req_to_install.check_if_exists(self.use_user_site) + if not req_to_install.satisfied_by: + return None + + if self.force_reinstall: + self._set_req_to_reinstall(req_to_install) + return None + + if not self._is_upgrade_allowed(req_to_install): + if self.upgrade_strategy == "only-if-needed": + return 'not upgraded as not directly required' + return 'already satisfied' + + # Check for the possibility of an upgrade. For link-based + # requirements we have to pull the tree down and inspect to assess + # the version #, so it's handled way down. + if not req_to_install.link: + try: + self.finder.find_requirement(req_to_install, upgrade=True) + except BestVersionAlreadyInstalled: + # Then the best version is installed. + return 'already up-to-date' + except DistributionNotFound: + # No distribution found, so we squash the error. It will + # be raised later when we re-try later to do the install. + # Why don't we just raise here? + pass + + self._set_req_to_reinstall(req_to_install) + return None + + def _get_abstract_dist_for(self, req): + """Takes a InstallRequirement and returns a single AbstractDist \ + representing a prepared variant of the same. + """ + assert self.require_hashes is not None, ( + "require_hashes should have been set in Resolver.resolve()" + ) + + if req.editable: + return self.preparer.prepare_editable_requirement( + req, self.require_hashes, self.use_user_site, self.finder, + ) + + # satisfied_by is only evaluated by calling _check_skip_installed, + # so it must be None here. + assert req.satisfied_by is None + skip_reason = self._check_skip_installed(req) + + if req.satisfied_by: + return self.preparer.prepare_installed_requirement( + req, self.require_hashes, skip_reason + ) + + upgrade_allowed = self._is_upgrade_allowed(req) + abstract_dist = self.preparer.prepare_linked_requirement( + req, self.session, self.finder, upgrade_allowed, + self.require_hashes + ) + + # NOTE + # The following portion is for determining if a certain package is + # going to be re-installed/upgraded or not and reporting to the user. + # This should probably get cleaned up in a future refactor. + + # req.req is only avail after unpack for URL + # pkgs repeat check_if_exists to uninstall-on-upgrade + # (#14) + if not self.ignore_installed: + req.check_if_exists(self.use_user_site) + + if req.satisfied_by: + should_modify = ( + self.upgrade_strategy != "to-satisfy-only" or + self.force_reinstall or + self.ignore_installed or + req.link.scheme == 'file' + ) + if should_modify: + self._set_req_to_reinstall(req) + else: + logger.info( + 'Requirement already satisfied (use --upgrade to upgrade):' + ' %s', req, + ) + + return abstract_dist + + def _resolve_one(self, requirement_set, req_to_install): + """Prepare a single requirements file. + + :return: A list of additional InstallRequirements to also install. + """ + # Tell user what we are doing for this requirement: + # obtain (editable), skipping, processing (local url), collecting + # (remote url or package name) + if req_to_install.constraint or req_to_install.prepared: + return [] + + req_to_install.prepared = True + + # register tmp src for cleanup in case something goes wrong + requirement_set.reqs_to_cleanup.append(req_to_install) + + abstract_dist = self._get_abstract_dist_for(req_to_install) + + # Parse and return dependencies + dist = abstract_dist.dist(self.finder) + try: + check_dist_requires_python(dist) + except UnsupportedPythonVersion as err: + if self.ignore_requires_python: + logger.warning(err.args[0]) + else: + raise + + more_reqs = [] + + def add_req(subreq, extras_requested): + sub_install_req = InstallRequirement.from_req( + str(subreq), + req_to_install, + isolated=self.isolated, + wheel_cache=self.wheel_cache, + ) + parent_req_name = req_to_install.name + to_scan_again, add_to_parent = requirement_set.add_requirement( + sub_install_req, + parent_req_name=parent_req_name, + extras_requested=extras_requested, + ) + if parent_req_name and add_to_parent: + self._discovered_dependencies[parent_req_name].append( + add_to_parent + ) + more_reqs.extend(to_scan_again) + + with indent_log(): + # We add req_to_install before its dependencies, so that we + # can refer to it when adding dependencies. + if not requirement_set.has_requirement(req_to_install.name): + # 'unnamed' requirements will get added here + req_to_install.is_direct = True + requirement_set.add_requirement( + req_to_install, parent_req_name=None, + ) + + if not self.ignore_dependencies: + if req_to_install.extras: + logger.debug( + "Installing extra requirements: %r", + ','.join(req_to_install.extras), + ) + missing_requested = sorted( + set(req_to_install.extras) - set(dist.extras) + ) + for missing in missing_requested: + logger.warning( + '%s does not provide the extra \'%s\'', + dist, missing + ) + + available_requested = sorted( + set(dist.extras) & set(req_to_install.extras) + ) + for subreq in dist.requires(available_requested): + add_req(subreq, extras_requested=available_requested) + + if not req_to_install.editable and not req_to_install.satisfied_by: + # XXX: --no-install leads this to report 'Successfully + # downloaded' for only non-editable reqs, even though we took + # action on them. + requirement_set.successfully_downloaded.append(req_to_install) + + return more_reqs + + def get_installation_order(self, req_set): + """Create the installation order. + + The installation order is topological - requirements are installed + before the requiring thing. We break cycles at an arbitrary point, + and make no other guarantees. + """ + # The current implementation, which we may change at any point + # installs the user specified things in the order given, except when + # dependencies must come earlier to achieve topological order. + order = [] + ordered_reqs = set() + + def schedule(req): + if req.satisfied_by or req in ordered_reqs: + return + if req.constraint: + return + ordered_reqs.add(req) + for dep in self._discovered_dependencies[req.name]: + schedule(dep) + order.append(req) + + for install_req in req_set.requirements.values(): + schedule(install_req) + return order diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/status_codes.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/status_codes.py new file mode 100644 index 0000000..275360a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/status_codes.py @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +SUCCESS = 0 +ERROR = 1 +UNKNOWN_ERROR = 2 +VIRTUALENV_NOT_FOUND = 3 +PREVIOUS_BUILD_DIR_ERROR = 4 +NO_MATCHES_FOUND = 23 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..a3d1166 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000..1a62594 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc new file mode 100644 index 0000000..9a36f5e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc new file mode 100644 index 0000000..bbab09a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc new file mode 100644 index 0000000..58b8b22 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc new file mode 100644 index 0000000..653f5e9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc new file mode 100644 index 0000000..3d87893 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/logging.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/logging.cpython-37.pyc new file mode 100644 index 0000000..fb73278 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/logging.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/misc.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/misc.cpython-37.pyc new file mode 100644 index 0000000..71a5da5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/misc.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc new file mode 100644 index 0000000..0d7e2eb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc new file mode 100644 index 0000000..f149b67 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc new file mode 100644 index 0000000..783eab7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc new file mode 100644 index 0000000..dfbc041 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/typing.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/typing.cpython-37.pyc new file mode 100644 index 0000000..2d9dbae Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/typing.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/ui.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/ui.cpython-37.pyc new file mode 100644 index 0000000..97e529d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/__pycache__/ui.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/appdirs.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/appdirs.py new file mode 100644 index 0000000..28c5d4b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/appdirs.py @@ -0,0 +1,258 @@ +""" +This code was taken from https://github.com/ActiveState/appdirs and modified +to suit our purposes. +""" +from __future__ import absolute_import + +import os +import sys + +from pip._vendor.six import PY2, text_type + +from pip._internal.compat import WINDOWS, expanduser + + +def user_cache_dir(appname): + r""" + Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + + Typical user cache directories are: + macOS: ~/Library/Caches/ + Unix: ~/.cache/ (XDG default) + Windows: C:\Users\\AppData\Local\\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go + in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the + non-roaming app data dir (the default returned by `user_data_dir`). Apps + typically put cache data somewhere *under* the given dir here. Some + examples: + ...\Mozilla\Firefox\Profiles\\Cache + ...\Acme\SuperApp\Cache\1.0 + + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + """ + if WINDOWS: + # Get the base path + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + + # When using Python 2, return paths as bytes on Windows like we do on + # other operating systems. See helper function docs for more details. + if PY2 and isinstance(path, text_type): + path = _win_path_to_bytes(path) + + # Add our app name and Cache directory to it + path = os.path.join(path, appname, "Cache") + elif sys.platform == "darwin": + # Get the base path + path = expanduser("~/Library/Caches") + + # Add our app name to it + path = os.path.join(path, appname) + else: + # Get the base path + path = os.getenv("XDG_CACHE_HOME", expanduser("~/.cache")) + + # Add our app name to it + path = os.path.join(path, appname) + + return path + + +def user_data_dir(appname, roaming=False): + r""" + Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: ~/Library/Application Support/ + if it exists, else ~/.config/ + Unix: ~/.local/share/ # or in + $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\\ ... + ...Application Data\ + Win XP (roaming): C:\Documents and Settings\\Local ... + ...Settings\Application Data\ + Win 7 (not roaming): C:\\Users\\AppData\Local\ + Win 7 (roaming): C:\\Users\\AppData\Roaming\ + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/". + """ + if WINDOWS: + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) + elif sys.platform == "darwin": + path = os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) if os.path.isdir(os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) + ) else os.path.join( + expanduser('~/.config/'), + appname, + ) + else: + path = os.path.join( + os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), + appname, + ) + + return path + + +def user_config_dir(appname, roaming=True): + """Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default True) can be set False to not use the + Windows roaming appdata directory. That means that for users on a + Windows network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: same as user_data_dir + Unix: ~/.config/ + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/". + """ + if WINDOWS: + path = user_data_dir(appname, roaming=roaming) + elif sys.platform == "darwin": + path = user_data_dir(appname) + else: + path = os.getenv('XDG_CONFIG_HOME', expanduser("~/.config")) + path = os.path.join(path, appname) + + return path + + +# for the discussion regarding site_config_dirs locations +# see +def site_config_dirs(appname): + r"""Return a list of potential user-shared config dirs for this application. + + "appname" is the name of application. + + Typical user config directories are: + macOS: /Library/Application Support// + Unix: /etc or $XDG_CONFIG_DIRS[i]// for each value in + $XDG_CONFIG_DIRS + Win XP: C:\Documents and Settings\All Users\Application ... + ...Data\\ + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory + on Vista.) + Win 7: Hidden, but writeable on Win 7: + C:\ProgramData\\ + """ + if WINDOWS: + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + pathlist = [os.path.join(path, appname)] + elif sys.platform == 'darwin': + pathlist = [os.path.join('/Library/Application Support', appname)] + else: + # try looking in $XDG_CONFIG_DIRS + xdg_config_dirs = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + if xdg_config_dirs: + pathlist = [ + os.path.join(expanduser(x), appname) + for x in xdg_config_dirs.split(os.pathsep) + ] + else: + pathlist = [] + + # always look in /etc directly as well + pathlist.append('/etc') + + return pathlist + + +# -- Windows support functions -- + +def _get_win_folder_from_registry(csidl_name): + """ + This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + directory, _type = _winreg.QueryValueEx(key, shell_folder_name) + return directory + + +def _get_win_folder_with_ctypes(csidl_name): + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # . + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + + +if WINDOWS: + try: + import ctypes + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +def _win_path_to_bytes(path): + """Encode Windows paths to bytes. Only used on Python 2. + + Motivation is to be consistent with other operating systems where paths + are also returned as bytes. This avoids problems mixing bytes and Unicode + elsewhere in the codebase. For more details and discussion see + . + + If encoding using ASCII and MBCS fails, return the original Unicode path. + """ + for encoding in ('ASCII', 'MBCS'): + try: + return path.encode(encoding) + except (UnicodeEncodeError, LookupError): + pass + return path diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/deprecation.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/deprecation.py new file mode 100644 index 0000000..a907172 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/deprecation.py @@ -0,0 +1,77 @@ +""" +A module that implements tooling to enable easy warnings about deprecations. +""" +from __future__ import absolute_import + +import logging +import warnings + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any + + +class PipDeprecationWarning(Warning): + pass + + +class Pending(object): + pass + + +class RemovedInPip11Warning(PipDeprecationWarning): + pass + + +class RemovedInPip12Warning(PipDeprecationWarning, Pending): + pass + + +# Warnings <-> Logging Integration + + +_warnings_showwarning = None # type: Any + + +def _showwarning(message, category, filename, lineno, file=None, line=None): + if file is not None: + if _warnings_showwarning is not None: + _warnings_showwarning( + message, category, filename, lineno, file, line, + ) + else: + if issubclass(category, PipDeprecationWarning): + # We use a specially named logger which will handle all of the + # deprecation messages for pip. + logger = logging.getLogger("pip._internal.deprecations") + + # This is purposely using the % formatter here instead of letting + # the logging module handle the interpolation. This is because we + # want it to appear as if someone typed this entire message out. + log_message = "DEPRECATION: %s" % message + + # PipDeprecationWarnings that are Pending still have at least 2 + # versions to go until they are removed so they can just be + # warnings. Otherwise, they will be removed in the very next + # version of pip. We want these to be more obvious so we use the + # ERROR logging level. + if issubclass(category, Pending): + logger.warning(log_message) + else: + logger.error(log_message) + else: + _warnings_showwarning( + message, category, filename, lineno, file, line, + ) + + +def install_warning_logger(): + # Enable our Deprecation Warnings + warnings.simplefilter("default", PipDeprecationWarning, append=True) + + global _warnings_showwarning + + if _warnings_showwarning is None: + _warnings_showwarning = warnings.showwarning + warnings.showwarning = _showwarning diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/encoding.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/encoding.py new file mode 100644 index 0000000..56f6036 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/encoding.py @@ -0,0 +1,33 @@ +import codecs +import locale +import re +import sys + +BOMS = [ + (codecs.BOM_UTF8, 'utf8'), + (codecs.BOM_UTF16, 'utf16'), + (codecs.BOM_UTF16_BE, 'utf16-be'), + (codecs.BOM_UTF16_LE, 'utf16-le'), + (codecs.BOM_UTF32, 'utf32'), + (codecs.BOM_UTF32_BE, 'utf32-be'), + (codecs.BOM_UTF32_LE, 'utf32-le'), +] + +ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') + + +def auto_decode(data): + """Check a bytes string for a BOM to correctly detect the encoding + + Fallback to locale.getpreferredencoding(False) like open() on Python3""" + for bom, encoding in BOMS: + if data.startswith(bom): + return data[len(bom):].decode(encoding) + # Lets check the first two lines as in PEP263 + for line in data.split(b'\n')[:2]: + if line[0:1] == b'#' and ENCODING_RE.search(line): + encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') + return data.decode(encoding) + return data.decode( + locale.getpreferredencoding(False) or sys.getdefaultencoding(), + ) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/filesystem.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/filesystem.py new file mode 100644 index 0000000..ee45501 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/filesystem.py @@ -0,0 +1,28 @@ +import os +import os.path + +from pip._internal.compat import get_path_uid + + +def check_path_owner(path): + # If we don't have a way to check the effective uid of this process, then + # we'll just assume that we own the directory. + if not hasattr(os, "geteuid"): + return True + + previous = None + while path != previous: + if os.path.lexists(path): + # Check if path is writable by current user. + if os.geteuid() == 0: + # Special handling for root user in order to handle properly + # cases where users use sudo without -H flag. + try: + path_uid = get_path_uid(path) + except OSError: + return False + return path_uid == 0 + else: + return os.access(path, os.W_OK) + else: + previous, path = path, os.path.dirname(path) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/glibc.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/glibc.py new file mode 100644 index 0000000..ebcfc5b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/glibc.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import + +import ctypes +import re +import warnings + + +def glibc_version_string(): + "Returns glibc version string, or None if not using glibc." + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +# Separated out from have_compatible_glibc for easier unit testing +def check_glibc_version(version_str, required_major, minimum_minor): + # Parse string and check against requested version. + # + # We use a regexp instead of str.split because we want to discard any + # random junk that might come after the minor version -- this might happen + # in patched/forked versions of glibc (e.g. Linaro's version of glibc + # uses version strings like "2.20-2014.11"). See gh-3588. + m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) + if not m: + warnings.warn("Expected glibc version with 2 components major.minor," + " got: %s" % version_str, RuntimeWarning) + return False + return (int(m.group("major")) == required_major and + int(m.group("minor")) >= minimum_minor) + + +def have_compatible_glibc(required_major, minimum_minor): + version_str = glibc_version_string() + if version_str is None: + return False + return check_glibc_version(version_str, required_major, minimum_minor) + + +# platform.libc_ver regularly returns completely nonsensical glibc +# versions. E.g. on my computer, platform says: +# +# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.7') +# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.9') +# +# But the truth is: +# +# ~$ ldd --version +# ldd (Debian GLIBC 2.22-11) 2.22 +# +# This is unfortunate, because it means that the linehaul data on libc +# versions that was generated by pip 8.1.2 and earlier is useless and +# misleading. Solution: instead of using platform, use our code that actually +# works. +def libc_ver(): + """Try to determine the glibc version + + Returns a tuple of strings (lib, version) which default to empty strings + in case the lookup fails. + """ + glibc_version = glibc_version_string() + if glibc_version is None: + return ("", "") + else: + return ("glibc", glibc_version) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/hashes.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/hashes.py new file mode 100644 index 0000000..8b909ba --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/hashes.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import + +import hashlib + +from pip._vendor.six import iteritems, iterkeys, itervalues + +from pip._internal.exceptions import ( + HashMismatch, HashMissing, InstallationError, +) +from pip._internal.utils.misc import read_chunks + +# The recommended hash algo of the moment. Change this whenever the state of +# the art changes; it won't hurt backward compatibility. +FAVORITE_HASH = 'sha256' + + +# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` +# Currently, those are the ones at least as collision-resistant as sha256. +STRONG_HASHES = ['sha256', 'sha384', 'sha512'] + + +class Hashes(object): + """A wrapper that builds multiple hashes at once and checks them against + known-good values + + """ + def __init__(self, hashes=None): + """ + :param hashes: A dict of algorithm names pointing to lists of allowed + hex digests + """ + self._allowed = {} if hashes is None else hashes + + def check_against_chunks(self, chunks): + """Check good hashes against ones built from iterable of chunks of + data. + + Raise HashMismatch if none match. + + """ + gots = {} + for hash_name in iterkeys(self._allowed): + try: + gots[hash_name] = hashlib.new(hash_name) + except (ValueError, TypeError): + raise InstallationError('Unknown hash name: %s' % hash_name) + + for chunk in chunks: + for hash in itervalues(gots): + hash.update(chunk) + + for hash_name, got in iteritems(gots): + if got.hexdigest() in self._allowed[hash_name]: + return + self._raise(gots) + + def _raise(self, gots): + raise HashMismatch(self._allowed, gots) + + def check_against_file(self, file): + """Check good hashes against a file-like object + + Raise HashMismatch if none match. + + """ + return self.check_against_chunks(read_chunks(file)) + + def check_against_path(self, path): + with open(path, 'rb') as file: + return self.check_against_file(file) + + def __nonzero__(self): + """Return whether I know any known-good hashes.""" + return bool(self._allowed) + + def __bool__(self): + return self.__nonzero__() + + +class MissingHashes(Hashes): + """A workalike for Hashes used when we're missing a hash for a requirement + + It computes the actual hash of the requirement and raises a HashMissing + exception showing it to the user. + + """ + def __init__(self): + """Don't offer the ``hashes`` kwarg.""" + # Pass our favorite hash in to generate a "gotten hash". With the + # empty list, it will never match, so an error will always raise. + super(MissingHashes, self).__init__(hashes={FAVORITE_HASH: []}) + + def _raise(self, gots): + raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/logging.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/logging.py new file mode 100644 index 0000000..5a5a7d7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/logging.py @@ -0,0 +1,132 @@ +from __future__ import absolute_import + +import contextlib +import logging +import logging.handlers +import os + +from pip._internal.compat import WINDOWS +from pip._internal.utils.misc import ensure_dir + +try: + import threading +except ImportError: + import dummy_threading as threading # type: ignore + + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + + +_log_state = threading.local() +_log_state.indentation = 0 + + +@contextlib.contextmanager +def indent_log(num=2): + """ + A context manager which will cause the log output to be indented for any + log messages emitted inside it. + """ + _log_state.indentation += num + try: + yield + finally: + _log_state.indentation -= num + + +def get_indentation(): + return getattr(_log_state, 'indentation', 0) + + +class IndentingFormatter(logging.Formatter): + + def format(self, record): + """ + Calls the standard formatter, but will indent all of the log messages + by our current indentation level. + """ + formatted = logging.Formatter.format(self, record) + formatted = "".join([ + (" " * get_indentation()) + line + for line in formatted.splitlines(True) + ]) + return formatted + + +def _color_wrap(*colors): + def wrapped(inp): + return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) + return wrapped + + +class ColorizedStreamHandler(logging.StreamHandler): + + # Don't build up a list of colors if we don't have colorama + if colorama: + COLORS = [ + # This needs to be in order from highest logging level to lowest. + (logging.ERROR, _color_wrap(colorama.Fore.RED)), + (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), + ] + else: + COLORS = [] + + def __init__(self, stream=None, no_color=None): + logging.StreamHandler.__init__(self, stream) + self._no_color = no_color + + if WINDOWS and colorama: + self.stream = colorama.AnsiToWin32(self.stream) + + def should_color(self): + # Don't colorize things if we do not have colorama or if told not to + if not colorama or self._no_color: + return False + + real_stream = ( + self.stream if not isinstance(self.stream, colorama.AnsiToWin32) + else self.stream.wrapped + ) + + # If the stream is a tty we should color it + if hasattr(real_stream, "isatty") and real_stream.isatty(): + return True + + # If we have an ASNI term we should color it + if os.environ.get("TERM") == "ANSI": + return True + + # If anything else we should not color it + return False + + def format(self, record): + msg = logging.StreamHandler.format(self, record) + + if self.should_color(): + for level, color in self.COLORS: + if record.levelno >= level: + msg = color(msg) + break + + return msg + + +class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): + + def _open(self): + ensure_dir(os.path.dirname(self.baseFilename)) + return logging.handlers.RotatingFileHandler._open(self) + + +class MaxLevelFilter(logging.Filter): + + def __init__(self, level): + self.level = level + + def filter(self, record): + return record.levelno < self.level diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/misc.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/misc.py new file mode 100644 index 0000000..9d4c9b1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/misc.py @@ -0,0 +1,851 @@ +from __future__ import absolute_import + +import contextlib +import errno +import io +import locale +# we have a submodule named 'logging' which would shadow this if we used the +# regular name: +import logging as std_logging +import os +import posixpath +import re +import shutil +import stat +import subprocess +import sys +import tarfile +import zipfile +from collections import deque + +from pip._vendor import pkg_resources +# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import. +from pip._vendor.retrying import retry # type: ignore +from pip._vendor.six import PY2 +from pip._vendor.six.moves import input + +from pip._internal.compat import console_to_str, expanduser, stdlib_pkgs +from pip._internal.exceptions import InstallationError +from pip._internal.locations import ( + running_under_virtualenv, site_packages, user_site, virtualenv_no_global, + write_delete_marker_file, +) + +if PY2: + from io import BytesIO as StringIO +else: + from io import StringIO + +__all__ = ['rmtree', 'display_path', 'backup_dir', + 'ask', 'splitext', + 'format_size', 'is_installable_dir', + 'is_svn_page', 'file_contents', + 'split_leading_dir', 'has_leading_dir', + 'normalize_path', + 'renames', 'get_prog', + 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', + 'captured_stdout', 'ensure_dir', + 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', + 'get_installed_version'] + + +logger = std_logging.getLogger(__name__) + +BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') +XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') +ZIP_EXTENSIONS = ('.zip', '.whl') +TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') +ARCHIVE_EXTENSIONS = ( + ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) +SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS +try: + import bz2 # noqa + SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS +except ImportError: + logger.debug('bz2 module is not available') + +try: + # Only for Python 3.3+ + import lzma # noqa + SUPPORTED_EXTENSIONS += XZ_EXTENSIONS +except ImportError: + logger.debug('lzma module is not available') + + +def import_or_raise(pkg_or_module_string, ExceptionType, *args, **kwargs): + try: + return __import__(pkg_or_module_string) + except ImportError: + raise ExceptionType(*args, **kwargs) + + +def ensure_dir(path): + """os.path.makedirs without EEXIST.""" + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + +def get_prog(): + try: + prog = os.path.basename(sys.argv[0]) + if prog in ('__main__.py', '-c'): + return "%s -m pip" % sys.executable + else: + return prog + except (AttributeError, TypeError, IndexError): + pass + return 'pip' + + +# Retry every half second for up to 3 seconds +@retry(stop_max_delay=3000, wait_fixed=500) +def rmtree(dir, ignore_errors=False): + shutil.rmtree(dir, ignore_errors=ignore_errors, + onerror=rmtree_errorhandler) + + +def rmtree_errorhandler(func, path, exc_info): + """On Windows, the files in .svn are read-only, so when rmtree() tries to + remove them, an exception is thrown. We catch that here, remove the + read-only attribute, and hopefully continue without problems.""" + # if file type currently read only + if os.stat(path).st_mode & stat.S_IREAD: + # convert to read/write + os.chmod(path, stat.S_IWRITE) + # use the original function to repeat the operation + func(path) + return + else: + raise + + +def display_path(path): + """Gives the display value for a given path, making it relative to cwd + if possible.""" + path = os.path.normcase(os.path.abspath(path)) + if sys.version_info[0] == 2: + path = path.decode(sys.getfilesystemencoding(), 'replace') + path = path.encode(sys.getdefaultencoding(), 'replace') + if path.startswith(os.getcwd() + os.path.sep): + path = '.' + path[len(os.getcwd()):] + return path + + +def backup_dir(dir, ext='.bak'): + """Figure out the name of a directory to back up the given dir to + (adding .bak, .bak2, etc)""" + n = 1 + extension = ext + while os.path.exists(dir + extension): + n += 1 + extension = ext + str(n) + return dir + extension + + +def ask_path_exists(message, options): + for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): + if action in options: + return action + return ask(message, options) + + +def ask(message, options): + """Ask the message interactively, with the given possible responses""" + while 1: + if os.environ.get('PIP_NO_INPUT'): + raise Exception( + 'No input was expected ($PIP_NO_INPUT set); question: %s' % + message + ) + response = input(message) + response = response.strip().lower() + if response not in options: + print( + 'Your response (%r) was not one of the expected responses: ' + '%s' % (response, ', '.join(options)) + ) + else: + return response + + +def format_size(bytes): + if bytes > 1000 * 1000: + return '%.1fMB' % (bytes / 1000.0 / 1000) + elif bytes > 10 * 1000: + return '%ikB' % (bytes / 1000) + elif bytes > 1000: + return '%.1fkB' % (bytes / 1000.0) + else: + return '%ibytes' % bytes + + +def is_installable_dir(path): + """Return True if `path` is a directory containing a setup.py file.""" + if not os.path.isdir(path): + return False + setup_py = os.path.join(path, 'setup.py') + if os.path.isfile(setup_py): + return True + return False + + +def is_svn_page(html): + """ + Returns true if the page appears to be the index page of an svn repository + """ + return (re.search(r'[^<]*Revision \d+:', html) and + re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) + + +def file_contents(filename): + with open(filename, 'rb') as fp: + return fp.read().decode('utf-8') + + +def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): + """Yield pieces of data from a file-like object until EOF.""" + while True: + chunk = file.read(size) + if not chunk: + break + yield chunk + + +def split_leading_dir(path): + path = path.lstrip('/').lstrip('\\') + if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or + '\\' not in path): + return path.split('/', 1) + elif '\\' in path: + return path.split('\\', 1) + else: + return path, '' + + +def has_leading_dir(paths): + """Returns true if all the paths have the same leading path name + (i.e., everything is in one subdirectory in an archive)""" + common_prefix = None + for path in paths: + prefix, rest = split_leading_dir(path) + if not prefix: + return False + elif common_prefix is None: + common_prefix = prefix + elif prefix != common_prefix: + return False + return True + + +def normalize_path(path, resolve_symlinks=True): + """ + Convert a path to its canonical, case-normalized, absolute version. + + """ + path = expanduser(path) + if resolve_symlinks: + path = os.path.realpath(path) + else: + path = os.path.abspath(path) + return os.path.normcase(path) + + +def splitext(path): + """Like os.path.splitext, but take off .tar too""" + base, ext = posixpath.splitext(path) + if base.lower().endswith('.tar'): + ext = base[-4:] + ext + base = base[:-4] + return base, ext + + +def renames(old, new): + """Like os.renames(), but handles renaming across devices.""" + # Implementation borrowed from os.renames(). + head, tail = os.path.split(new) + if head and tail and not os.path.exists(head): + os.makedirs(head) + + shutil.move(old, new) + + head, tail = os.path.split(old) + if head and tail: + try: + os.removedirs(head) + except OSError: + pass + + +def is_local(path): + """ + Return True if path is within sys.prefix, if we're running in a virtualenv. + + If we're not in a virtualenv, all paths are considered "local." + + """ + if not running_under_virtualenv(): + return True + return normalize_path(path).startswith(normalize_path(sys.prefix)) + + +def dist_is_local(dist): + """ + Return True if given Distribution object is installed locally + (i.e. within current virtualenv). + + Always True if we're not in a virtualenv. + + """ + return is_local(dist_location(dist)) + + +def dist_in_usersite(dist): + """ + Return True if given Distribution is installed in user site. + """ + norm_path = normalize_path(dist_location(dist)) + return norm_path.startswith(normalize_path(user_site)) + + +def dist_in_site_packages(dist): + """ + Return True if given Distribution is installed in + sysconfig.get_python_lib(). + """ + return normalize_path( + dist_location(dist) + ).startswith(normalize_path(site_packages)) + + +def dist_is_editable(dist): + """Is distribution an editable install?""" + for path_item in sys.path: + egg_link = os.path.join(path_item, dist.project_name + '.egg-link') + if os.path.isfile(egg_link): + return True + return False + + +def get_installed_distributions(local_only=True, + skip=stdlib_pkgs, + include_editables=True, + editables_only=False, + user_only=False): + """ + Return a list of installed Distribution objects. + + If ``local_only`` is True (default), only return installations + local to the current virtualenv, if in a virtualenv. + + ``skip`` argument is an iterable of lower-case project names to + ignore; defaults to stdlib_pkgs + + If ``include_editables`` is False, don't report editables. + + If ``editables_only`` is True , only report editables. + + If ``user_only`` is True , only report installations in the user + site directory. + + """ + if local_only: + local_test = dist_is_local + else: + def local_test(d): + return True + + if include_editables: + def editable_test(d): + return True + else: + def editable_test(d): + return not dist_is_editable(d) + + if editables_only: + def editables_only_test(d): + return dist_is_editable(d) + else: + def editables_only_test(d): + return True + + if user_only: + user_test = dist_in_usersite + else: + def user_test(d): + return True + + return [d for d in pkg_resources.working_set + if local_test(d) and + d.key not in skip and + editable_test(d) and + editables_only_test(d) and + user_test(d) + ] + + +def egg_link_path(dist): + """ + Return the path for the .egg-link file if it exists, otherwise, None. + + There's 3 scenarios: + 1) not in a virtualenv + try to find in site.USER_SITE, then site_packages + 2) in a no-global virtualenv + try to find in site_packages + 3) in a yes-global virtualenv + try to find in site_packages, then site.USER_SITE + (don't look in global location) + + For #1 and #3, there could be odd cases, where there's an egg-link in 2 + locations. + + This method will just return the first one found. + """ + sites = [] + if running_under_virtualenv(): + if virtualenv_no_global(): + sites.append(site_packages) + else: + sites.append(site_packages) + if user_site: + sites.append(user_site) + else: + if user_site: + sites.append(user_site) + sites.append(site_packages) + + for site in sites: + egglink = os.path.join(site, dist.project_name) + '.egg-link' + if os.path.isfile(egglink): + return egglink + + +def dist_location(dist): + """ + Get the site-packages location of this distribution. Generally + this is dist.location, except in the case of develop-installed + packages, where dist.location is the source code location, and we + want to know where the egg-link file is. + + """ + egg_link = egg_link_path(dist) + if egg_link: + return egg_link + return dist.location + + +def current_umask(): + """Get the current umask which involves having to set it temporarily.""" + mask = os.umask(0) + os.umask(mask) + return mask + + +def unzip_file(filename, location, flatten=True): + """ + Unzip the file (with path `filename`) to the destination `location`. All + files are written based on system defaults and umask (i.e. permissions are + not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + zipfp = open(filename, 'rb') + try: + zip = zipfile.ZipFile(zipfp, allowZip64=True) + leading = has_leading_dir(zip.namelist()) and flatten + for info in zip.infolist(): + name = info.filename + data = zip.read(name) + fn = name + if leading: + fn = split_leading_dir(name)[1] + fn = os.path.join(location, fn) + dir = os.path.dirname(fn) + if fn.endswith('/') or fn.endswith('\\'): + # A directory + ensure_dir(fn) + else: + ensure_dir(dir) + fp = open(fn, 'wb') + try: + fp.write(data) + finally: + fp.close() + mode = info.external_attr >> 16 + # if mode and regular file and any execute permissions for + # user/group/world? + if mode and stat.S_ISREG(mode) and mode & 0o111: + # make dest file have execute for user/group/world + # (chmod +x) no-op on windows per python docs + os.chmod(fn, (0o777 - current_umask() | 0o111)) + finally: + zipfp.close() + + +def untar_file(filename, location): + """ + Untar the file (with path `filename`) to the destination `location`. + All files are written based on system defaults and umask (i.e. permissions + are not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): + mode = 'r:gz' + elif filename.lower().endswith(BZ2_EXTENSIONS): + mode = 'r:bz2' + elif filename.lower().endswith(XZ_EXTENSIONS): + mode = 'r:xz' + elif filename.lower().endswith('.tar'): + mode = 'r' + else: + logger.warning( + 'Cannot determine compression type for file %s', filename, + ) + mode = 'r:*' + tar = tarfile.open(filename, mode) + try: + # note: python<=2.5 doesn't seem to know about pax headers, filter them + leading = has_leading_dir([ + member.name for member in tar.getmembers() + if member.name != 'pax_global_header' + ]) + for member in tar.getmembers(): + fn = member.name + if fn == 'pax_global_header': + continue + if leading: + fn = split_leading_dir(fn)[1] + path = os.path.join(location, fn) + if member.isdir(): + ensure_dir(path) + elif member.issym(): + try: + tar._extract_member(member, path) + except Exception as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + else: + try: + fp = tar.extractfile(member) + except (KeyError, AttributeError) as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + ensure_dir(os.path.dirname(path)) + with open(path, 'wb') as destfp: + shutil.copyfileobj(fp, destfp) + fp.close() + # Update the timestamp (useful for cython compiled files) + tar.utime(member, path) + # member have any execute permissions for user/group/world? + if member.mode & 0o111: + # make dest file have execute for user/group/world + # no-op on windows per python docs + os.chmod(path, (0o777 - current_umask() | 0o111)) + finally: + tar.close() + + +def unpack_file(filename, location, content_type, link): + filename = os.path.realpath(filename) + if (content_type == 'application/zip' or + filename.lower().endswith(ZIP_EXTENSIONS) or + zipfile.is_zipfile(filename)): + unzip_file( + filename, + location, + flatten=not filename.endswith('.whl') + ) + elif (content_type == 'application/x-gzip' or + tarfile.is_tarfile(filename) or + filename.lower().endswith( + TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): + untar_file(filename, location) + elif (content_type and content_type.startswith('text/html') and + is_svn_page(file_contents(filename))): + # We don't really care about this + from pip._internal.vcs.subversion import Subversion + Subversion('svn+' + link.url).unpack(location) + else: + # FIXME: handle? + # FIXME: magic signatures? + logger.critical( + 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' + 'cannot detect archive format', + filename, location, content_type, + ) + raise InstallationError( + 'Cannot determine archive format of %s' % location + ) + + +def call_subprocess(cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, unset_environ=None, spinner=None): + """ + Args: + unset_environ: an iterable of environment variable names to unset + prior to calling subprocess.Popen(). + """ + if unset_environ is None: + unset_environ = [] + # This function's handling of subprocess output is confusing and I + # previously broke it terribly, so as penance I will write a long comment + # explaining things. + # + # The obvious thing that affects output is the show_stdout= + # kwarg. show_stdout=True means, let the subprocess write directly to our + # stdout. Even though it is nominally the default, it is almost never used + # inside pip (and should not be used in new code without a very good + # reason); as of 2016-02-22 it is only used in a few places inside the VCS + # wrapper code. Ideally we should get rid of it entirely, because it + # creates a lot of complexity here for a rarely used feature. + # + # Most places in pip set show_stdout=False. What this means is: + # - We connect the child stdout to a pipe, which we read. + # - By default, we hide the output but show a spinner -- unless the + # subprocess exits with an error, in which case we show the output. + # - If the --verbose option was passed (= loglevel is DEBUG), then we show + # the output unconditionally. (But in this case we don't want to show + # the output a second time if it turns out that there was an error.) + # + # stderr is always merged with stdout (even if show_stdout=True). + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE + if command_desc is None: + cmd_parts = [] + for part in cmd: + if ' ' in part or '\n' in part or '"' in part or "'" in part: + part = '"%s"' % part.replace('"', '\\"') + cmd_parts.append(part) + command_desc = ' '.join(cmd_parts) + logger.debug("Running command %s", command_desc) + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + for name in unset_environ: + env.pop(name, None) + try: + proc = subprocess.Popen( + cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, + stdout=stdout, cwd=cwd, env=env, + ) + proc.stdin.close() + except Exception as exc: + logger.critical( + "Error %s while executing command %s", exc, command_desc, + ) + raise + all_output = [] + if stdout is not None: + while True: + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + if logger.getEffectiveLevel() <= std_logging.DEBUG: + # Show the line immediately + logger.debug(line) + else: + # Update the spinner + if spinner is not None: + spinner.spin() + try: + proc.wait() + finally: + if proc.stdout: + proc.stdout.close() + if spinner is not None: + if proc.returncode: + spinner.finish("error") + else: + spinner.finish("done") + if proc.returncode: + if on_returncode == 'raise': + if (logger.getEffectiveLevel() > std_logging.DEBUG and + not show_stdout): + logger.info( + 'Complete output from command %s:', command_desc, + ) + logger.info( + ''.join(all_output) + + '\n----------------------------------------' + ) + raise InstallationError( + 'Command "%s" failed with error code %s in %s' + % (command_desc, proc.returncode, cwd)) + elif on_returncode == 'warn': + logger.warning( + 'Command "%s" had error code %s in %s', + command_desc, proc.returncode, cwd, + ) + elif on_returncode == 'ignore': + pass + else: + raise ValueError('Invalid value: on_returncode=%s' % + repr(on_returncode)) + if not show_stdout: + return ''.join(all_output) + + +def read_text_file(filename): + """Return the contents of *filename*. + + Try to decode the file contents with utf-8, the preferred system encoding + (e.g., cp1252 on some Windows machines), and latin1, in that order. + Decoding a byte string with latin1 will never raise an error. In the worst + case, the returned string will contain some garbage characters. + + """ + with open(filename, 'rb') as fp: + data = fp.read() + + encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] + for enc in encodings: + try: + data = data.decode(enc) + except UnicodeDecodeError: + continue + break + + assert type(data) != bytes # Latin1 should have worked. + return data + + +def _make_build_dir(build_dir): + os.makedirs(build_dir) + write_delete_marker_file(build_dir) + + +class FakeFile(object): + """Wrap a list of lines in an object with readline() to make + ConfigParser happy.""" + def __init__(self, lines): + self._gen = (l for l in lines) + + def readline(self): + try: + try: + return next(self._gen) + except NameError: + return self._gen.next() + except StopIteration: + return '' + + def __iter__(self): + return self._gen + + +class StreamWrapper(StringIO): + + @classmethod + def from_stream(cls, orig_stream): + cls.orig_stream = orig_stream + return cls() + + # compileall.compile_dir() needs stdout.encoding to print to stdout + @property + def encoding(self): + return self.orig_stream.encoding + + +@contextlib.contextmanager +def captured_output(stream_name): + """Return a context manager used by captured_stdout/stdin/stderr + that temporarily replaces the sys stream *stream_name* with a StringIO. + + Taken from Lib/support/__init__.py in the CPython repo. + """ + orig_stdout = getattr(sys, stream_name) + setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) + try: + yield getattr(sys, stream_name) + finally: + setattr(sys, stream_name, orig_stdout) + + +def captured_stdout(): + """Capture the output of sys.stdout: + + with captured_stdout() as stdout: + print('hello') + self.assertEqual(stdout.getvalue(), 'hello\n') + + Taken from Lib/support/__init__.py in the CPython repo. + """ + return captured_output('stdout') + + +class cached_property(object): + """A property that is only computed once per instance and then replaces + itself with an ordinary attribute. Deleting the attribute resets the + property. + + Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 + """ + + def __init__(self, func): + self.__doc__ = getattr(func, '__doc__') + self.func = func + + def __get__(self, obj, cls): + if obj is None: + # We're being accessed from the class itself, not from an object + return self + value = obj.__dict__[self.func.__name__] = self.func(obj) + return value + + +def get_installed_version(dist_name, lookup_dirs=None): + """Get the installed version of dist_name avoiding pkg_resources cache""" + # Create a requirement that we'll look for inside of setuptools. + req = pkg_resources.Requirement.parse(dist_name) + + # We want to avoid having this cached, so we need to construct a new + # working set each time. + if lookup_dirs is None: + working_set = pkg_resources.WorkingSet() + else: + working_set = pkg_resources.WorkingSet(lookup_dirs) + + # Get the installed distribution from our working set + dist = working_set.find(req) + + # Check to see if we got an installed distribution or not, if we did + # we want to return it's version. + return dist.version if dist else None + + +def consume(iterator): + """Consume an iterable at C speed.""" + deque(iterator, maxlen=0) + + +# Simulates an enum +def enum(*sequential, **named): + enums = dict(zip(sequential, range(len(sequential))), **named) + reverse = {value: key for key, value in enums.items()} + enums['reverse_mapping'] = reverse + return type('Enum', (), enums) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/outdated.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/outdated.py new file mode 100644 index 0000000..f8f6466 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/outdated.py @@ -0,0 +1,163 @@ +from __future__ import absolute_import + +import datetime +import json +import logging +import os.path +import sys + +from pip._vendor import lockfile +from pip._vendor.packaging import version as packaging_version + +from pip._internal.compat import WINDOWS +from pip._internal.index import PackageFinder +from pip._internal.locations import USER_CACHE_DIR, running_under_virtualenv +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, get_installed_version + +SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" + + +logger = logging.getLogger(__name__) + + +class VirtualenvSelfCheckState(object): + def __init__(self): + self.statefile_path = os.path.join(sys.prefix, "pip-selfcheck.json") + + # Load the existing state + try: + with open(self.statefile_path) as statefile: + self.state = json.load(statefile) + except (IOError, ValueError): + self.state = {} + + def save(self, pypi_version, current_time): + # Attempt to write out our version check file + with open(self.statefile_path, "w") as statefile: + json.dump( + { + "last_check": current_time.strftime(SELFCHECK_DATE_FMT), + "pypi_version": pypi_version, + }, + statefile, + sort_keys=True, + separators=(",", ":") + ) + + +class GlobalSelfCheckState(object): + def __init__(self): + self.statefile_path = os.path.join(USER_CACHE_DIR, "selfcheck.json") + + # Load the existing state + try: + with open(self.statefile_path) as statefile: + self.state = json.load(statefile)[sys.prefix] + except (IOError, ValueError, KeyError): + self.state = {} + + def save(self, pypi_version, current_time): + # Check to make sure that we own the directory + if not check_path_owner(os.path.dirname(self.statefile_path)): + return + + # Now that we've ensured the directory is owned by this user, we'll go + # ahead and make sure that all our directories are created. + ensure_dir(os.path.dirname(self.statefile_path)) + + # Attempt to write out our version check file + with lockfile.LockFile(self.statefile_path): + if os.path.exists(self.statefile_path): + with open(self.statefile_path) as statefile: + state = json.load(statefile) + else: + state = {} + + state[sys.prefix] = { + "last_check": current_time.strftime(SELFCHECK_DATE_FMT), + "pypi_version": pypi_version, + } + + with open(self.statefile_path, "w") as statefile: + json.dump(state, statefile, sort_keys=True, + separators=(",", ":")) + + +def load_selfcheck_statefile(): + if running_under_virtualenv(): + return VirtualenvSelfCheckState() + else: + return GlobalSelfCheckState() + + +def pip_version_check(session, options): + """Check for an update for pip. + + Limit the frequency of checks to once per week. State is stored either in + the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix + of the pip script path. + """ + installed_version = get_installed_version("pip") + if not installed_version: + return + + pip_version = packaging_version.parse(installed_version) + pypi_version = None + + try: + state = load_selfcheck_statefile() + + current_time = datetime.datetime.utcnow() + # Determine if we need to refresh the state + if "last_check" in state.state and "pypi_version" in state.state: + last_check = datetime.datetime.strptime( + state.state["last_check"], + SELFCHECK_DATE_FMT + ) + if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: + pypi_version = state.state["pypi_version"] + + # Refresh the version if we need to or just see if we need to warn + if pypi_version is None: + # Lets use PackageFinder to see what the latest pip version is + finder = PackageFinder( + find_links=options.find_links, + index_urls=[options.index_url] + options.extra_index_urls, + allow_all_prereleases=False, # Explicitly set to False + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + all_candidates = finder.find_all_candidates("pip") + if not all_candidates: + return + pypi_version = str( + max(all_candidates, key=lambda c: c.version).version + ) + + # save that we've performed a check + state.save(pypi_version, current_time) + + remote_version = packaging_version.parse(pypi_version) + + # Determine if our pypi_version is older + if (pip_version < remote_version and + pip_version.base_version != remote_version.base_version): + # Advise "python -m pip" on Windows to avoid issues + # with overwriting pip.exe. + if WINDOWS: + pip_cmd = "python -m pip" + else: + pip_cmd = "pip" + logger.warning( + "You are using pip version %s, however version %s is " + "available.\nYou should consider upgrading via the " + "'%s install --upgrade pip' command.", + pip_version, pypi_version, pip_cmd + ) + except Exception: + logger.debug( + "There was an error checking the latest version of pip", + exc_info=True, + ) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/packaging.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/packaging.py new file mode 100644 index 0000000..5f9bb93 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/packaging.py @@ -0,0 +1,70 @@ +from __future__ import absolute_import + +import logging +import sys +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging import specifiers, version + +from pip._internal import exceptions + +logger = logging.getLogger(__name__) + + +def check_requires_python(requires_python): + """ + Check if the python version in use match the `requires_python` specifier. + + Returns `True` if the version of python in use matches the requirement. + Returns `False` if the version of python in use does not matches the + requirement. + + Raises an InvalidSpecifier if `requires_python` have an invalid format. + """ + if requires_python is None: + # The package provides no information + return True + requires_python_specifier = specifiers.SpecifierSet(requires_python) + + # We only use major.minor.micro + python_version = version.parse('.'.join(map(str, sys.version_info[:3]))) + return python_version in requires_python_specifier + + +def get_metadata(dist): + if (isinstance(dist, pkg_resources.DistInfoDistribution) and + dist.has_metadata('METADATA')): + return dist.get_metadata('METADATA') + elif dist.has_metadata('PKG-INFO'): + return dist.get_metadata('PKG-INFO') + + +def check_dist_requires_python(dist): + metadata = get_metadata(dist) + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + requires_python = pkg_info_dict.get('Requires-Python') + try: + if not check_requires_python(requires_python): + raise exceptions.UnsupportedPythonVersion( + "%s requires Python '%s' but the running Python is %s" % ( + dist.project_name, + requires_python, + '.'.join(map(str, sys.version_info[:3])),) + ) + except specifiers.InvalidSpecifier as e: + logger.warning( + "Package %s has an invalid Requires-Python entry %s - %s", + dist.project_name, requires_python, e, + ) + return + + +def get_installer(dist): + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + return line.strip() + return '' diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/setuptools_build.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/setuptools_build.py new file mode 100644 index 0000000..03973e9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/setuptools_build.py @@ -0,0 +1,8 @@ +# Shim to wrap setup.py invocation with setuptools +SETUPTOOLS_SHIM = ( + "import setuptools, tokenize;__file__=%r;" + "f=getattr(tokenize, 'open', open)(__file__);" + "code=f.read().replace('\\r\\n', '\\n');" + "f.close();" + "exec(compile(code, __file__, 'exec'))" +) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/temp_dir.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/temp_dir.py new file mode 100644 index 0000000..edc506b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/temp_dir.py @@ -0,0 +1,82 @@ +from __future__ import absolute_import + +import logging +import os.path +import tempfile + +from pip._internal.utils.misc import rmtree + +logger = logging.getLogger(__name__) + + +class TempDirectory(object): + """Helper class that owns and cleans up a temporary directory. + + This class can be used as a context manager or as an OO representation of a + temporary directory. + + Attributes: + path + Location to the created temporary directory or None + delete + Whether the directory should be deleted when exiting + (when used as a contextmanager) + + Methods: + create() + Creates a temporary directory and stores its path in the path + attribute. + cleanup() + Deletes the temporary directory and sets path attribute to None + + When used as a context manager, a temporary directory is created on + entering the context and, if the delete attribute is True, on exiting the + context the created directory is deleted. + """ + + def __init__(self, path=None, delete=None, kind="temp"): + super(TempDirectory, self).__init__() + + if path is None and delete is None: + # If we were not given an explicit directory, and we were not given + # an explicit delete option, then we'll default to deleting. + delete = True + + self.path = path + self.delete = delete + self.kind = kind + + def __repr__(self): + return "<{} {!r}>".format(self.__class__.__name__, self.path) + + def __enter__(self): + self.create() + return self + + def __exit__(self, exc, value, tb): + if self.delete: + self.cleanup() + + def create(self): + """Create a temporary directory and store it's path in self.path + """ + if self.path is not None: + logger.debug( + "Skipped creation of temporary directory: {}".format(self.path) + ) + return + # We realpath here because some systems have their default tmpdir + # symlinked to another directory. This tends to confuse build + # scripts, so we canonicalize the path by traversing potential + # symlinks here. + self.path = os.path.realpath( + tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) + ) + logger.debug("Created temporary directory: {}".format(self.path)) + + def cleanup(self): + """Remove the temporary directory created and reset state + """ + if self.path is not None and os.path.exists(self.path): + rmtree(self.path) + self.path = None diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/typing.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/typing.py new file mode 100644 index 0000000..cb57f8f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/typing.py @@ -0,0 +1,29 @@ +"""For neatly implementing static typing in pip. + +`mypy` - the static type analysis tool we use - uses the `typing` module, which +provides core functionality fundamental to mypy's functioning. + +Generally, `typing` would be imported at runtime and used in that fashion - +it acts as a no-op at runtime and does not have any run-time overhead by +design. + +As it turns out, `typing` is not vendorable - it uses separate sources for +Python 2/Python 3. Thus, this codebase can not expect it to be present. +To work around this, mypy allows the typing import to be behind a False-y +optional to prevent it from running at runtime and type-comments can be used +to remove the need for the types to be accessible directly during runtime. + +This module provides the False-y guard in a nicely named fashion so that a +curious maintainer can reach here to read this. + +In pip, all static-typing related imports should be guarded as follows: + + from pip.utils.typing import MYPY_CHECK_RUNNING + + if MYPY_CHECK_RUNNING: + from typing import ... + +Ref: https://github.com/python/mypy/issues/3216 +""" + +MYPY_CHECK_RUNNING = False diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py new file mode 100644 index 0000000..8ade1e2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py @@ -0,0 +1,421 @@ +from __future__ import absolute_import, division + +import contextlib +import itertools +import logging +import sys +import time +from signal import SIGINT, default_int_handler, signal + +from pip._vendor import six +from pip._vendor.progress.bar import ( + Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, + ShadyBar, +) +from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin +from pip._vendor.progress.spinner import Spinner + +from pip._internal.compat import WINDOWS +from pip._internal.utils.logging import get_indentation +from pip._internal.utils.misc import format_size +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + +logger = logging.getLogger(__name__) + + +def _select_progress_class(preferred, fallback): + encoding = getattr(preferred.file, "encoding", None) + + # If we don't know what encoding this file is in, then we'll just assume + # that it doesn't support unicode and use the ASCII bar. + if not encoding: + return fallback + + # Collect all of the possible characters we want to use with the preferred + # bar. + characters = [ + getattr(preferred, "empty_fill", six.text_type()), + getattr(preferred, "fill", six.text_type()), + ] + characters += list(getattr(preferred, "phases", [])) + + # Try to decode the characters we're using for the bar using the encoding + # of the given file, if this works then we'll assume that we can use the + # fancier bar and if not we'll fall back to the plaintext bar. + try: + six.text_type().join(characters).encode(encoding) + except UnicodeEncodeError: + return fallback + else: + return preferred + + +_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any + + +class InterruptibleMixin(object): + """ + Helper to ensure that self.finish() gets called on keyboard interrupt. + + This allows downloads to be interrupted without leaving temporary state + (like hidden cursors) behind. + + This class is similar to the progress library's existing SigIntMixin + helper, but as of version 1.2, that helper has the following problems: + + 1. It calls sys.exit(). + 2. It discards the existing SIGINT handler completely. + 3. It leaves its own handler in place even after an uninterrupted finish, + which will have unexpected delayed effects if the user triggers an + unrelated keyboard interrupt some time after a progress-displaying + download has already completed, for example. + """ + + def __init__(self, *args, **kwargs): + """ + Save the original SIGINT handler for later. + """ + super(InterruptibleMixin, self).__init__(*args, **kwargs) + + self.original_handler = signal(SIGINT, self.handle_sigint) + + # If signal() returns None, the previous handler was not installed from + # Python, and we cannot restore it. This probably should not happen, + # but if it does, we must restore something sensible instead, at least. + # The least bad option should be Python's default SIGINT handler, which + # just raises KeyboardInterrupt. + if self.original_handler is None: + self.original_handler = default_int_handler + + def finish(self): + """ + Restore the original SIGINT handler after finishing. + + This should happen regardless of whether the progress display finishes + normally, or gets interrupted. + """ + super(InterruptibleMixin, self).finish() + signal(SIGINT, self.original_handler) + + def handle_sigint(self, signum, frame): + """ + Call self.finish() before delegating to the original SIGINT handler. + + This handler should only be in place while the progress display is + active. + """ + self.finish() + self.original_handler(signum, frame) + + +class SilentBar(Bar): + + def update(self): + pass + + +class BlueEmojiBar(IncrementalBar): + + suffix = "%(percent)d%%" + bar_prefix = " " + bar_suffix = " " + phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any + + +class DownloadProgressMixin(object): + + def __init__(self, *args, **kwargs): + super(DownloadProgressMixin, self).__init__(*args, **kwargs) + self.message = (" " * (get_indentation() + 2)) + self.message + + @property + def downloaded(self): + return format_size(self.index) + + @property + def download_speed(self): + # Avoid zero division errors... + if self.avg == 0.0: + return "..." + return format_size(1 / self.avg) + "/s" + + @property + def pretty_eta(self): + if self.eta: + return "eta %s" % self.eta_td + return "" + + def iter(self, it, n=1): + for x in it: + yield x + self.next(n) + self.finish() + + +class WindowsMixin(object): + + def __init__(self, *args, **kwargs): + # The Windows terminal does not support the hide/show cursor ANSI codes + # even with colorama. So we'll ensure that hide_cursor is False on + # Windows. + # This call neds to go before the super() call, so that hide_cursor + # is set in time. The base progress bar class writes the "hide cursor" + # code to the terminal in its init, so if we don't set this soon + # enough, we get a "hide" with no corresponding "show"... + if WINDOWS and self.hide_cursor: + self.hide_cursor = False + + super(WindowsMixin, self).__init__(*args, **kwargs) + + # Check if we are running on Windows and we have the colorama module, + # if we do then wrap our file with it. + if WINDOWS and colorama: + self.file = colorama.AnsiToWin32(self.file) + # The progress code expects to be able to call self.file.isatty() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.isatty = lambda: self.file.wrapped.isatty() + # The progress code expects to be able to call self.file.flush() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.flush = lambda: self.file.wrapped.flush() + + +class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin): + + file = sys.stdout + message = "%(percent)d%%" + suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" + +# NOTE: The "type: ignore" comments on the following classes are there to +# work around https://github.com/python/typing/issues/241 + + +class DefaultDownloadProgressBar(BaseDownloadProgressBar, + _BaseBar): # type: ignore + pass + + +class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore + pass + + +class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore + IncrementalBar): + pass + + +class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore + ChargingBar): + pass + + +class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore + pass + + +class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore + FillingSquaresBar): + pass + + +class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore + FillingCirclesBar): + pass + + +class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore + BlueEmojiBar): + pass + + +class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin, WritelnMixin, Spinner): + + file = sys.stdout + suffix = "%(downloaded)s %(download_speed)s" + + def next_phase(self): + if not hasattr(self, "_phaser"): + self._phaser = itertools.cycle(self.phases) + return next(self._phaser) + + def update(self): + message = self.message % self + phase = self.next_phase() + suffix = self.suffix % self + line = ''.join([ + message, + " " if message else "", + phase, + " " if suffix else "", + suffix, + ]) + + self.writeln(line) + + +BAR_TYPES = { + "off": (DownloadSilentBar, DownloadSilentBar), + "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), + "ascii": (DownloadIncrementalBar, DownloadProgressSpinner), + "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), + "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) +} + + +def DownloadProgressProvider(progress_bar, max=None): + if max is None or max == 0: + return BAR_TYPES[progress_bar][1]().iter + else: + return BAR_TYPES[progress_bar][0](max=max).iter + + +################################################################ +# Generic "something is happening" spinners +# +# We don't even try using progress.spinner.Spinner here because it's actually +# simpler to reimplement from scratch than to coerce their code into doing +# what we need. +################################################################ + +@contextlib.contextmanager +def hidden_cursor(file): + # The Windows terminal does not support the hide/show cursor ANSI codes, + # even via colorama. So don't even try. + if WINDOWS: + yield + # We don't want to clutter the output with control characters if we're + # writing to a file, or if the user is running with --quiet. + # See https://github.com/pypa/pip/issues/3418 + elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: + yield + else: + file.write(HIDE_CURSOR) + try: + yield + finally: + file.write(SHOW_CURSOR) + + +class RateLimiter(object): + def __init__(self, min_update_interval_seconds): + self._min_update_interval_seconds = min_update_interval_seconds + self._last_update = 0 + + def ready(self): + now = time.time() + delta = now - self._last_update + return delta >= self._min_update_interval_seconds + + def reset(self): + self._last_update = time.time() + + +class InteractiveSpinner(object): + def __init__(self, message, file=None, spin_chars="-\\|/", + # Empirically, 8 updates/second looks nice + min_update_interval_seconds=0.125): + self._message = message + if file is None: + file = sys.stdout + self._file = file + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._finished = False + + self._spin_cycle = itertools.cycle(spin_chars) + + self._file.write(" " * get_indentation() + self._message + " ... ") + self._width = 0 + + def _write(self, status): + assert not self._finished + # Erase what we wrote before by backspacing to the beginning, writing + # spaces to overwrite the old text, and then backspacing again + backup = "\b" * self._width + self._file.write(backup + " " * self._width + backup) + # Now we have a blank slate to add our status + self._file.write(status) + self._width = len(status) + self._file.flush() + self._rate_limiter.reset() + + def spin(self): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._write(next(self._spin_cycle)) + + def finish(self, final_status): + if self._finished: + return + self._write(final_status) + self._file.write("\n") + self._file.flush() + self._finished = True + + +# Used for dumb terminals, non-interactive installs (no tty), etc. +# We still print updates occasionally (once every 60 seconds by default) to +# act as a keep-alive for systems like Travis-CI that take lack-of-output as +# an indication that a task has frozen. +class NonInteractiveSpinner(object): + def __init__(self, message, min_update_interval_seconds=60): + self._message = message + self._finished = False + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._update("started") + + def _update(self, status): + assert not self._finished + self._rate_limiter.reset() + logger.info("%s: %s", self._message, status) + + def spin(self): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._update("still running...") + + def finish(self, final_status): + if self._finished: + return + self._update("finished with status '%s'" % (final_status,)) + self._finished = True + + +@contextlib.contextmanager +def open_spinner(message): + # Interactive spinner goes directly to sys.stdout rather than being routed + # through the logging system, but it acts like it has level INFO, + # i.e. it's only displayed if we're at level INFO or better. + # Non-interactive spinner goes through the logging system, so it is always + # in sync with logging configuration. + if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: + spinner = InteractiveSpinner(message) + else: + spinner = NonInteractiveSpinner(message) + try: + with hidden_cursor(sys.stdout): + yield spinner + except KeyboardInterrupt: + spinner.finish("canceled") + raise + except Exception: + spinner.finish("error") + raise + else: + spinner.finish("done") diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__init__.py new file mode 100644 index 0000000..8b159cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__init__.py @@ -0,0 +1,471 @@ +"""Handles all VCS (version control) support""" +from __future__ import absolute_import + +import copy +import errno +import logging +import os +import shutil +import sys + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.exceptions import BadCommand +from pip._internal.utils.misc import ( + display_path, backup_dir, call_subprocess, rmtree, ask_path_exists, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, Optional, Tuple + from pip._internal.basecommand import Command + +__all__ = ['vcs', 'get_src_requirement'] + + +logger = logging.getLogger(__name__) + + +class RevOptions(object): + + """ + Encapsulates a VCS-specific revision to install, along with any VCS + install options. + + Instances of this class should be treated as if immutable. + """ + + def __init__(self, vcs, rev=None, extra_args=None): + """ + Args: + vcs: a VersionControl object. + rev: the name of the revision to install. + extra_args: a list of extra options. + """ + if extra_args is None: + extra_args = [] + + self.extra_args = extra_args + self.rev = rev + self.vcs = vcs + + def __repr__(self): + return '<RevOptions {}: rev={!r}>'.format(self.vcs.name, self.rev) + + @property + def arg_rev(self): + if self.rev is None: + return self.vcs.default_arg_rev + + return self.rev + + def to_args(self): + """ + Return the VCS-specific command arguments. + """ + args = [] + rev = self.arg_rev + if rev is not None: + args += self.vcs.get_base_rev_args(rev) + args += self.extra_args + + return args + + def to_display(self): + if not self.rev: + return '' + + return ' (to revision {})'.format(self.rev) + + def make_new(self, rev): + """ + Make a copy of the current instance, but with a new rev. + + Args: + rev: the name of the revision for the new object. + """ + return self.vcs.make_rev_options(rev, extra_args=self.extra_args) + + +class VcsSupport(object): + _registry = {} # type: Dict[str, Command] + schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] + + def __init__(self): + # Register more schemes with urlparse for various version control + # systems + urllib_parse.uses_netloc.extend(self.schemes) + # Python >= 2.7.4, 3.3 doesn't have uses_fragment + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(self.schemes) + super(VcsSupport, self).__init__() + + def __iter__(self): + return self._registry.__iter__() + + @property + def backends(self): + return list(self._registry.values()) + + @property + def dirnames(self): + return [backend.dirname for backend in self.backends] + + @property + def all_schemes(self): + schemes = [] + for backend in self.backends: + schemes.extend(backend.schemes) + return schemes + + def register(self, cls): + if not hasattr(cls, 'name'): + logger.warning('Cannot register VCS %s', cls.__name__) + return + if cls.name not in self._registry: + self._registry[cls.name] = cls + logger.debug('Registered VCS backend: %s', cls.name) + + def unregister(self, cls=None, name=None): + if name in self._registry: + del self._registry[name] + elif cls in self._registry.values(): + del self._registry[cls.name] + else: + logger.warning('Cannot unregister because no class or name given') + + def get_backend_name(self, location): + """ + Return the name of the version control backend if found at given + location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') + """ + for vc_type in self._registry.values(): + if vc_type.controls_location(location): + logger.debug('Determine that %s uses VCS: %s', + location, vc_type.name) + return vc_type.name + return None + + def get_backend(self, name): + name = name.lower() + if name in self._registry: + return self._registry[name] + + def get_backend_from_location(self, location): + vc_type = self.get_backend_name(location) + if vc_type: + return self.get_backend(vc_type) + return None + + +vcs = VcsSupport() + + +class VersionControl(object): + name = '' + dirname = '' + # List of supported schemes for this Version Control + schemes = () # type: Tuple[str, ...] + # Iterable of environment variable names to pass to call_subprocess(). + unset_environ = () # type: Tuple[str, ...] + default_arg_rev = None # type: Optional[str] + + def __init__(self, url=None, *args, **kwargs): + self.url = url + super(VersionControl, self).__init__(*args, **kwargs) + + def get_base_rev_args(self, rev): + """ + Return the base revision arguments for a vcs command. + + Args: + rev: the name of a revision to install. Cannot be None. + """ + raise NotImplementedError + + def make_rev_options(self, rev=None, extra_args=None): + """ + Return a RevOptions object. + + Args: + rev: the name of a revision to install. + extra_args: a list of extra options. + """ + return RevOptions(self, rev, extra_args=extra_args) + + def _is_local_repository(self, repo): + """ + posix absolute paths start with os.path.sep, + win32 ones start with drive (like c:\\folder) + """ + drive, tail = os.path.splitdrive(repo) + return repo.startswith(os.path.sep) or drive + + # See issue #1083 for why this method was introduced: + # https://github.com/pypa/pip/issues/1083 + def translate_egg_surname(self, surname): + # For example, Django has branches of the form "stable/1.7.x". + return surname.replace('/', '_') + + def export(self, location): + """ + Export the repository at the url to the destination location + i.e. only download the files, without vcs informations + """ + raise NotImplementedError + + def get_url_rev(self): + """ + Returns the correct repository URL and revision by parsing the given + repository URL + """ + error_message = ( + "Sorry, '%s' is a malformed VCS url. " + "The format is <vcs>+<protocol>://<url>, " + "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp" + ) + assert '+' in self.url, error_message % self.url + url = self.url.split('+', 1)[1] + scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) + return url, rev + + def get_info(self, location): + """ + Returns (url, revision), where both are strings + """ + assert not location.rstrip('/').endswith(self.dirname), \ + 'Bad directory: %s' % location + return self.get_url(location), self.get_revision(location) + + def normalize_url(self, url): + """ + Normalize a URL for comparison by unquoting it and removing any + trailing slash. + """ + return urllib_parse.unquote(url).rstrip('/') + + def compare_urls(self, url1, url2): + """ + Compare two repo URLs for identity, ignoring incidental differences. + """ + return (self.normalize_url(url1) == self.normalize_url(url2)) + + def obtain(self, dest): + """ + Called when installing or updating an editable package, takes the + source path of the checkout. + """ + raise NotImplementedError + + def switch(self, dest, url, rev_options): + """ + Switch the repo at ``dest`` to point to ``URL``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def update(self, dest, rev_options): + """ + Update an already-existing repo to the given ``rev_options``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def is_commit_id_equal(self, dest, name): + """ + Return whether the id of the current commit equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + raise NotImplementedError + + def check_destination(self, dest, url, rev_options): + """ + Prepare a location to receive a checkout/clone. + + Return True if the location is ready for (and requires) a + checkout/clone, False otherwise. + + Args: + rev_options: a RevOptions object. + """ + checkout = True + prompt = False + rev_display = rev_options.to_display() + if os.path.exists(dest): + checkout = False + if os.path.exists(os.path.join(dest, self.dirname)): + existing_url = self.get_url(dest) + if self.compare_urls(existing_url, url): + logger.debug( + '%s in %s exists, and has correct URL (%s)', + self.repo_name.title(), + display_path(dest), + url, + ) + if not self.is_commit_id_equal(dest, rev_options.rev): + logger.info( + 'Updating %s %s%s', + display_path(dest), + self.repo_name, + rev_display, + ) + self.update(dest, rev_options) + else: + logger.info( + 'Skipping because already up-to-date.') + else: + logger.warning( + '%s %s in %s exists with URL %s', + self.name, + self.repo_name, + display_path(dest), + existing_url, + ) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b')) + else: + logger.warning( + 'Directory %s already exists, and is not a %s %s.', + dest, + self.name, + self.repo_name, + ) + prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) + if prompt: + logger.warning( + 'The plan is to install the %s repository %s', + self.name, + url, + ) + response = ask_path_exists('What to do? %s' % prompt[0], + prompt[1]) + + if response == 's': + logger.info( + 'Switching %s %s to %s%s', + self.repo_name, + display_path(dest), + url, + rev_display, + ) + self.switch(dest, url, rev_options) + elif response == 'i': + # do nothing + pass + elif response == 'w': + logger.warning('Deleting %s', display_path(dest)) + rmtree(dest) + checkout = True + elif response == 'b': + dest_dir = backup_dir(dest) + logger.warning( + 'Backing up %s to %s', display_path(dest), dest_dir, + ) + shutil.move(dest, dest_dir) + checkout = True + elif response == 'a': + sys.exit(-1) + return checkout + + def unpack(self, location): + """ + Clean up current location and download the url repository + (and vcs infos) into location + """ + if os.path.exists(location): + rmtree(location) + self.obtain(location) + + def get_src_requirement(self, dist, location): + """ + Return a string representing the requirement needed to + redownload the files currently present in location, something + like: + {repository_url}@{revision}#egg={project_name}-{version_identifier} + """ + raise NotImplementedError + + def get_url(self, location): + """ + Return the url used at location + Used in get_info or check_destination + """ + raise NotImplementedError + + def get_revision(self, location): + """ + Return the current commit id of the files at the given location. + """ + raise NotImplementedError + + def run_command(self, cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, spinner=None): + """ + Run a VCS subcommand + This is simply a wrapper around call_subprocess that adds the VCS + command name, and checks that the VCS is available + """ + cmd = [self.name] + cmd + try: + return call_subprocess(cmd, show_stdout, cwd, + on_returncode, + command_desc, extra_environ, + unset_environ=self.unset_environ, + spinner=spinner) + except OSError as e: + # errno.ENOENT = no such file or directory + # In other words, the VCS executable isn't available + if e.errno == errno.ENOENT: + raise BadCommand( + 'Cannot find command %r - do you have ' + '%r installed and in your ' + 'PATH?' % (self.name, self.name)) + else: + raise # re-raise exception if a different error occurred + + @classmethod + def controls_location(cls, location): + """ + Check if a location is controlled by the vcs. + It is meant to be overridden to implement smarter detection + mechanisms for specific vcs. + """ + logger.debug('Checking in %s for %s (%s)...', + location, cls.dirname, cls.name) + path = os.path.join(location, cls.dirname) + return os.path.exists(path) + + +def get_src_requirement(dist, location): + version_control = vcs.get_backend_from_location(location) + if version_control: + try: + return version_control().get_src_requirement(dist, + location) + except BadCommand: + logger.warning( + 'cannot determine version of editable source in %s ' + '(%s command not found in path)', + location, + version_control.name, + ) + return dist.as_requirement() + logger.warning( + 'cannot determine version of editable source in %s (is not SVN ' + 'checkout, Git clone, Mercurial clone or Bazaar branch)', + location, + ) + return dist.as_requirement() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..2989d47 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc new file mode 100644 index 0000000..529b28b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/git.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/git.cpython-37.pyc new file mode 100644 index 0000000..754377a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/git.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc new file mode 100644 index 0000000..c24047d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc new file mode 100644 index 0000000..fe54152 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/bazaar.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/bazaar.py new file mode 100644 index 0000000..b4e46e0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/bazaar.py @@ -0,0 +1,113 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import display_path, rmtree +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Bazaar(VersionControl): + name = 'bzr' + dirname = '.bzr' + repo_name = 'branch' + schemes = ( + 'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', + 'bzr+lp', + ) + + def __init__(self, url=None, *args, **kwargs): + super(Bazaar, self).__init__(url, *args, **kwargs) + # This is only needed for python <2.7.5 + # Register lp but do not expose as a scheme to support bzr+lp. + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(['lp']) + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """ + Export the Bazaar repository at the url to the destination location + """ + # Remove the location to make sure Bazaar can export it correctly + if os.path.exists(location): + rmtree(location) + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['export', location], + cwd=temp_dir.path, show_stdout=False, + ) + + def switch(self, dest, url, rev_options): + self.run_command(['switch', url], cwd=dest) + + def update(self, dest, rev_options): + cmd_args = ['pull', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = self.make_rev_options(rev) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['branch', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def get_url_rev(self): + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + url, rev = super(Bazaar, self).get_url_rev() + if url.startswith('ssh://'): + url = 'bzr+' + url + return url, rev + + def get_url(self, location): + urls = self.run_command(['info'], show_stdout=False, cwd=location) + for line in urls.splitlines(): + line = line.strip() + for x in ('checkout of branch: ', + 'parent branch: '): + if line.startswith(x): + repo = line.split(x)[1] + if self._is_local_repository(repo): + return path_to_url(repo) + return repo + return None + + def get_revision(self, location): + revision = self.run_command( + ['revno'], show_stdout=False, cwd=location, + ) + return revision.splitlines()[-1] + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo: + return None + if not repo.lower().startswith('bzr:'): + repo = 'bzr+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + current_rev = self.get_revision(location) + return '%s@%s#egg=%s' % (repo, current_rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Bazaar) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/git.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/git.py new file mode 100644 index 0000000..33c6806 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/git.py @@ -0,0 +1,311 @@ +from __future__ import absolute_import + +import logging +import os.path +import re + +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.compat import samefile +from pip._internal.exceptions import BadCommand +from pip._internal.utils.misc import display_path +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +urlsplit = urllib_parse.urlsplit +urlunsplit = urllib_parse.urlunsplit + + +logger = logging.getLogger(__name__) + + +HASH_REGEX = re.compile('[a-fA-F0-9]{40}') + + +def looks_like_hash(sha): + return bool(HASH_REGEX.match(sha)) + + +class Git(VersionControl): + name = 'git' + dirname = '.git' + repo_name = 'clone' + schemes = ( + 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', + ) + # Prevent the user's environment variables from interfering with pip: + # https://github.com/pypa/pip/issues/1130 + unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') + default_arg_rev = 'HEAD' + + def __init__(self, url=None, *args, **kwargs): + + # Works around an apparent Git bug + # (see http://article.gmane.org/gmane.comp.version-control.git/146500) + if url: + scheme, netloc, path, query, fragment = urlsplit(url) + if scheme.endswith('file'): + initial_slashes = path[:-len(path.lstrip('/'))] + newpath = ( + initial_slashes + + urllib_request.url2pathname(path) + .replace('\\', '/').lstrip('/') + ) + url = urlunsplit((scheme, netloc, newpath, query, fragment)) + after_plus = scheme.find('+') + 1 + url = scheme[:after_plus] + urlunsplit( + (scheme[after_plus:], netloc, newpath, query, fragment), + ) + + super(Git, self).__init__(url, *args, **kwargs) + + def get_base_rev_args(self, rev): + return [rev] + + def get_git_version(self): + VERSION_PFX = 'git version ' + version = self.run_command(['version'], show_stdout=False) + if version.startswith(VERSION_PFX): + version = version[len(VERSION_PFX):].split()[0] + else: + version = '' + # get first 3 positions of the git version becasue + # on windows it is x.y.z.windows.t, and this parses as + # LegacyVersion which always smaller than a Version. + version = '.'.join(version.split('.')[:3]) + return parse_version(version) + + def export(self, location): + """Export the Git repository at the url to the destination location""" + if not location.endswith('/'): + location = location + '/' + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + self.run_command( + ['checkout-index', '-a', '-f', '--prefix', location], + show_stdout=False, cwd=temp_dir.path + ) + + def get_revision_sha(self, dest, rev): + """ + Return a commit hash for the given revision if it names a remote + branch or tag. Otherwise, return None. + + Args: + dest: the repository directory. + rev: the revision name. + """ + # Pass rev to pre-filter the list. + output = self.run_command(['show-ref', rev], cwd=dest, + show_stdout=False, on_returncode='ignore') + refs = {} + for line in output.strip().splitlines(): + try: + sha, ref = line.split() + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. + raise ValueError('unexpected show-ref line: {!r}'.format(line)) + + refs[ref] = sha + + branch_ref = 'refs/remotes/origin/{}'.format(rev) + tag_ref = 'refs/tags/{}'.format(rev) + + return refs.get(branch_ref) or refs.get(tag_ref) + + def check_rev_options(self, dest, rev_options): + """Check the revision options before checkout. + + Returns a new RevOptions object for the SHA1 of the branch or tag + if found. + + Args: + rev_options: a RevOptions object. + """ + rev = rev_options.arg_rev + sha = self.get_revision_sha(dest, rev) + + if sha is not None: + return rev_options.make_new(sha) + + # Do not show a warning for the common case of something that has + # the form of a Git commit hash. + if not looks_like_hash(rev): + logger.warning( + "Did not find branch or tag '%s', assuming revision or ref.", + rev, + ) + return rev_options + + def is_commit_id_equal(self, dest, name): + """ + Return whether the current commit hash equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + if not name: + # Then avoid an unnecessary subprocess call. + return False + + return self.get_revision(dest) == name + + def switch(self, dest, url, rev_options): + self.run_command(['config', 'remote.origin.url', url], cwd=dest) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + self.update_submodules(dest) + + def update(self, dest, rev_options): + # First fetch changes from the default remote + if self.get_git_version() >= parse_version('1.9.0'): + # fetch tags in addition to everything else + self.run_command(['fetch', '-q', '--tags'], cwd=dest) + else: + self.run_command(['fetch', '-q'], cwd=dest) + # Then reset to wanted revision (maybe even origin/master) + rev_options = self.check_rev_options(dest, rev_options) + cmd_args = ['reset', '--hard', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + #: update submodules + self.update_submodules(dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = self.make_rev_options(rev) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning %s%s to %s', url, rev_display, display_path(dest), + ) + self.run_command(['clone', '-q', url, dest]) + + if rev: + rev_options = self.check_rev_options(dest, rev_options) + # Only do a checkout if the current commit id doesn't match + # the requested revision. + if not self.is_commit_id_equal(dest, rev_options.rev): + rev = rev_options.rev + # Only fetch the revision if it's a ref + if rev.startswith('refs/'): + self.run_command( + ['fetch', '-q', url] + rev_options.to_args(), + cwd=dest, + ) + # Change the revision to the SHA of the ref we fetched + rev = 'FETCH_HEAD' + self.run_command(['checkout', '-q', rev], cwd=dest) + + #: repo may contain submodules + self.update_submodules(dest) + + def get_url(self, location): + """Return URL of the first remote encountered.""" + remotes = self.run_command( + ['config', '--get-regexp', r'remote\..*\.url'], + show_stdout=False, cwd=location, + ) + remotes = remotes.splitlines() + found_remote = remotes[0] + for remote in remotes: + if remote.startswith('remote.origin.url '): + found_remote = remote + break + url = found_remote.split(' ')[1] + return url.strip() + + def get_revision(self, location): + current_rev = self.run_command( + ['rev-parse', 'HEAD'], show_stdout=False, cwd=location, + ) + return current_rev.strip() + + def _get_subdirectory(self, location): + """Return the relative path of setup.py to the git repo root.""" + # find the repo root + git_dir = self.run_command(['rev-parse', '--git-dir'], + show_stdout=False, cwd=location).strip() + if not os.path.isabs(git_dir): + git_dir = os.path.join(location, git_dir) + root_dir = os.path.join(git_dir, '..') + # find setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + # relative path of setup.py to repo root + if samefile(root_dir, location): + return None + return os.path.relpath(location, root_dir) + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('git:'): + repo = 'git+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + if not repo: + return None + current_rev = self.get_revision(location) + req = '%s@%s#egg=%s' % (repo, current_rev, egg_project_name) + subdirectory = self._get_subdirectory(location) + if subdirectory: + req += '&subdirectory=' + subdirectory + return req + + def get_url_rev(self): + """ + Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. + That's required because although they use SSH they sometimes doesn't + work with a ssh:// scheme (e.g. Github). But we need a scheme for + parsing. Hence we remove it again afterwards and return it as a stub. + """ + if '://' not in self.url: + assert 'file:' not in self.url + self.url = self.url.replace('git+', 'git+ssh://') + url, rev = super(Git, self).get_url_rev() + url = url.replace('ssh://', '') + else: + url, rev = super(Git, self).get_url_rev() + + return url, rev + + def update_submodules(self, location): + if not os.path.exists(os.path.join(location, '.gitmodules')): + return + self.run_command( + ['submodule', 'update', '--init', '--recursive', '-q'], + cwd=location, + ) + + @classmethod + def controls_location(cls, location): + if super(Git, cls).controls_location(location): + return True + try: + r = cls().run_command(['rev-parse'], + cwd=location, + show_stdout=False, + on_returncode='ignore') + return not r + except BadCommand: + logger.debug("could not determine if %s is under git control " + "because git is not available", location) + return False + + +vcs.register(Git) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/mercurial.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/mercurial.py new file mode 100644 index 0000000..52a1cce --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/mercurial.py @@ -0,0 +1,105 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves import configparser + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import display_path +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Mercurial(VersionControl): + name = 'hg' + dirname = '.hg' + repo_name = 'clone' + schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') + + def get_base_rev_args(self, rev): + return [rev] + + def export(self, location): + """Export the Hg repository at the url to the destination location""" + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['archive', location], show_stdout=False, cwd=temp_dir.path + ) + + def switch(self, dest, url, rev_options): + repo_config = os.path.join(dest, self.dirname, 'hgrc') + config = configparser.SafeConfigParser() + try: + config.read(repo_config) + config.set('paths', 'default', url) + with open(repo_config, 'w') as config_file: + config.write(config_file) + except (OSError, configparser.NoSectionError) as exc: + logger.warning( + 'Could not switch Mercurial repository to %s: %s', url, exc, + ) + else: + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def update(self, dest, rev_options): + self.run_command(['pull', '-q'], cwd=dest) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = self.make_rev_options(rev) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning hg %s%s to %s', + url, + rev_display, + display_path(dest), + ) + self.run_command(['clone', '--noupdate', '-q', url, dest]) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def get_url(self, location): + url = self.run_command( + ['showconfig', 'paths.default'], + show_stdout=False, cwd=location).strip() + if self._is_local_repository(url): + url = path_to_url(url) + return url.strip() + + def get_revision(self, location): + current_revision = self.run_command( + ['parents', '--template={rev}'], + show_stdout=False, cwd=location).strip() + return current_revision + + def get_revision_hash(self, location): + current_rev_hash = self.run_command( + ['parents', '--template={node}'], + show_stdout=False, cwd=location).strip() + return current_rev_hash + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('hg:'): + repo = 'hg+' + repo + egg_project_name = dist.egg_name().split('-', 1)[0] + if not repo: + return None + current_rev_hash = self.get_revision_hash(location) + return '%s@%s#egg=%s' % (repo, current_rev_hash, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Mercurial) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/subversion.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/subversion.py new file mode 100644 index 0000000..7f369ef --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/vcs/subversion.py @@ -0,0 +1,271 @@ +from __future__ import absolute_import + +import logging +import os +import re + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.index import Link +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import display_path, rmtree +from pip._internal.vcs import VersionControl, vcs + +_svn_xml_url_re = re.compile('url="([^"]+)"') +_svn_rev_re = re.compile(r'committed-rev="(\d+)"') +_svn_url_re = re.compile(r'URL: (.+)') +_svn_revision_re = re.compile(r'Revision: (.+)') +_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') +_svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') + + +logger = logging.getLogger(__name__) + + +class Subversion(VersionControl): + name = 'svn' + dirname = '.svn' + repo_name = 'checkout' + schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn') + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def get_info(self, location): + """Returns (url, revision), where both are strings""" + assert not location.rstrip('/').endswith(self.dirname), \ + 'Bad directory: %s' % location + output = self.run_command( + ['info', location], + show_stdout=False, + extra_environ={'LANG': 'C'}, + ) + match = _svn_url_re.search(output) + if not match: + logger.warning( + 'Cannot determine URL of svn checkout %s', + display_path(location), + ) + logger.debug('Output that cannot be parsed: \n%s', output) + return None, None + url = match.group(1).strip() + match = _svn_revision_re.search(output) + if not match: + logger.warning( + 'Cannot determine revision of svn checkout %s', + display_path(location), + ) + logger.debug('Output that cannot be parsed: \n%s', output) + return url, None + return url, match.group(1) + + def export(self, location): + """Export the svn repository at the url to the destination location""" + url, rev = self.get_url_rev() + rev_options = get_rev_options(self, url, rev) + url = self.remove_auth_from_url(url) + logger.info('Exporting svn repository %s to %s', url, location) + with indent_log(): + if os.path.exists(location): + # Subversion doesn't like to check out over an existing + # directory --force fixes this, but was only added in svn 1.5 + rmtree(location) + cmd_args = ['export'] + rev_options.to_args() + [url, location] + self.run_command(cmd_args, show_stdout=False) + + def switch(self, dest, url, rev_options): + cmd_args = ['switch'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def update(self, dest, rev_options): + cmd_args = ['update'] + rev_options.to_args() + [dest] + self.run_command(cmd_args) + + def obtain(self, dest): + url, rev = self.get_url_rev() + rev_options = get_rev_options(self, url, rev) + url = self.remove_auth_from_url(url) + if self.check_destination(dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def get_location(self, dist, dependency_links): + for url in dependency_links: + egg_fragment = Link(url).egg_fragment + if not egg_fragment: + continue + if '-' in egg_fragment: + # FIXME: will this work when a package has - in the name? + key = '-'.join(egg_fragment.split('-')[:-1]).lower() + else: + key = egg_fragment + if key == dist.key: + return url.split('#', 1)[0] + return None + + def get_revision(self, location): + """ + Return the maximum revision for all files under a given location + """ + # Note: taken from setuptools.command.egg_info + revision = 0 + + for base, dirs, files in os.walk(location): + if self.dirname not in dirs: + dirs[:] = [] + continue # no sense walking uncontrolled subdirs + dirs.remove(self.dirname) + entries_fn = os.path.join(base, self.dirname, 'entries') + if not os.path.exists(entries_fn): + # FIXME: should we warn? + continue + + dirurl, localrev = self._get_svn_url_rev(base) + + if base == location: + base = dirurl + '/' # save the root url + elif not dirurl or not dirurl.startswith(base): + dirs[:] = [] + continue # not part of the same svn tree, skip it + revision = max(revision, localrev) + return revision + + def get_url_rev(self): + # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + url, rev = super(Subversion, self).get_url_rev() + if url.startswith('ssh://'): + url = 'svn+' + url + return url, rev + + def get_url(self, location): + # In cases where the source is in a subdirectory, not alongside + # setup.py we have to look up in the location until we find a real + # setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + + return self._get_svn_url_rev(location)[0] + + def _get_svn_url_rev(self, location): + from pip._internal.exceptions import InstallationError + + entries_path = os.path.join(location, self.dirname, 'entries') + if os.path.exists(entries_path): + with open(entries_path) as f: + data = f.read() + else: # subversion >= 1.7 does not have the 'entries' file + data = '' + + if (data.startswith('8') or + data.startswith('9') or + data.startswith('10')): + data = list(map(str.splitlines, data.split('\n\x0c\n'))) + del data[0][0] # get rid of the '8' + url = data[0][3] + revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] + elif data.startswith('<?xml'): + match = _svn_xml_url_re.search(data) + if not match: + raise ValueError('Badly formatted data: %r' % data) + url = match.group(1) # get repository URL + revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] + else: + try: + # subversion >= 1.7 + xml = self.run_command( + ['info', '--xml', location], + show_stdout=False, + ) + url = _svn_info_xml_url_re.search(xml).group(1) + revs = [ + int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) + ] + except InstallationError: + url, revs = None, [] + + if revs: + rev = max(revs) + else: + rev = 0 + + return url, rev + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if repo is None: + return None + # FIXME: why not project name? + egg_project_name = dist.egg_name().split('-', 1)[0] + rev = self.get_revision(location) + return 'svn+%s@%s#egg=%s' % (repo, rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + @staticmethod + def remove_auth_from_url(url): + # Return a copy of url with 'username:password@' removed. + # username/pass params are passed to subversion through flags + # and are not recognized in the url. + + # parsed url + purl = urllib_parse.urlsplit(url) + stripped_netloc = \ + purl.netloc.split('@')[-1] + + # stripped url + url_pieces = ( + purl.scheme, stripped_netloc, purl.path, purl.query, purl.fragment + ) + surl = urllib_parse.urlunsplit(url_pieces) + return surl + + +def get_rev_options(vcs, url, rev): + """ + Return a RevOptions object. + """ + r = urllib_parse.urlsplit(url) + if hasattr(r, 'username'): + # >= Python-2.5 + username, password = r.username, r.password + else: + netloc = r[1] + if '@' in netloc: + auth = netloc.split('@')[0] + if ':' in auth: + username, password = auth.split(':', 1) + else: + username, password = auth, None + else: + username, password = None, None + + extra_args = [] + if username: + extra_args += ['--username', username] + if password: + extra_args += ['--password', password] + + return vcs.make_rev_options(rev, extra_args=extra_args) + + +vcs.register(Subversion) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/wheel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/wheel.py new file mode 100644 index 0000000..c71f17d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/wheel.py @@ -0,0 +1,817 @@ +""" +Support for installing and building the "wheel" binary package format. +""" +from __future__ import absolute_import + +import collections +import compileall +import copy +import csv +import hashlib +import logging +import os.path +import re +import shutil +import stat +import sys +import warnings +from base64 import urlsafe_b64encode +from email.parser import Parser + +from pip._vendor import pkg_resources +from pip._vendor.distlib.scripts import ScriptMaker +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.six import StringIO + +from pip._internal import pep425tags +from pip._internal.build_env import BuildEnvironment +from pip._internal.download import path_to_url, unpack_url +from pip._internal.exceptions import ( + InstallationError, InvalidWheelFilename, UnsupportedWheel, +) +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, distutils_scheme, +) +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + call_subprocess, captured_stdout, ensure_dir, read_chunks, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import open_spinner + +if MYPY_CHECK_RUNNING: + from typing import Dict, List, Optional + +wheel_ext = '.whl' + +VERSION_COMPATIBLE = (1, 0) + + +logger = logging.getLogger(__name__) + + +def rehash(path, algo='sha256', blocksize=1 << 20): + """Return (hash, length) for path using hashlib.new(algo)""" + h = hashlib.new(algo) + length = 0 + with open(path, 'rb') as f: + for block in read_chunks(f, size=blocksize): + length += len(block) + h.update(block) + digest = 'sha256=' + urlsafe_b64encode( + h.digest() + ).decode('latin1').rstrip('=') + return (digest, length) + + +def open_for_csv(name, mode): + if sys.version_info[0] < 3: + nl = {} + bin = 'b' + else: + nl = {'newline': ''} + bin = '' + return open(name, mode + bin, **nl) + + +def fix_script(path): + """Replace #!python with #!/path/to/python + Return True if file was changed.""" + # XXX RECORD hashes will need to be updated + if os.path.isfile(path): + with open(path, 'rb') as script: + firstline = script.readline() + if not firstline.startswith(b'#!python'): + return False + exename = sys.executable.encode(sys.getfilesystemencoding()) + firstline = b'#!' + exename + os.linesep.encode("ascii") + rest = script.read() + with open(path, 'wb') as script: + script.write(firstline) + script.write(rest) + return True + + +dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) + \.dist-info$""", re.VERBOSE) + + +def root_is_purelib(name, wheeldir): + """ + Return True if the extracted wheel in wheeldir should go into purelib. + """ + name_folded = name.replace("-", "_") + for item in os.listdir(wheeldir): + match = dist_info_re.match(item) + if match and match.group('name') == name_folded: + with open(os.path.join(wheeldir, item, 'WHEEL')) as wheel: + for line in wheel: + line = line.lower().rstrip() + if line == "root-is-purelib: true": + return True + return False + + +def get_entrypoints(filename): + if not os.path.exists(filename): + return {}, {} + + # This is done because you can pass a string to entry_points wrappers which + # means that they may or may not be valid INI files. The attempt here is to + # strip leading and trailing whitespace in order to make them valid INI + # files. + with open(filename) as fp: + data = StringIO() + for line in fp: + data.write(line.strip()) + data.write("\n") + data.seek(0) + + # get the entry points and then the script names + entry_points = pkg_resources.EntryPoint.parse_map(data) + console = entry_points.get('console_scripts', {}) + gui = entry_points.get('gui_scripts', {}) + + def _split_ep(s): + """get the string representation of EntryPoint, remove space and split + on '='""" + return str(s).replace(" ", "").split("=") + + # convert the EntryPoint objects into strings with module:function + console = dict(_split_ep(v) for v in console.values()) + gui = dict(_split_ep(v) for v in gui.values()) + return console, gui + + +def message_about_scripts_not_on_PATH(scripts): + # type: (List[str]) -> Optional[str] + """Determine if any scripts are not on PATH and format a warning. + + Returns a warning message if one or more scripts are not on PATH, + otherwise None. + """ + if not scripts: + return None + + # Group scripts by the path they were installed in + grouped_by_dir = collections.defaultdict(set) # type: Dict[str, set] + for destfile in scripts: + parent_dir = os.path.dirname(destfile) + script_name = os.path.basename(destfile) + grouped_by_dir[parent_dir].add(script_name) + + # We don't want to warn for directories that are on PATH. + not_warn_dirs = [ + os.path.normcase(i) for i in os.environ["PATH"].split(os.pathsep) + ] + # If an executable sits with sys.executable, we don't warn for it. + # This covers the case of venv invocations without activating the venv. + not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) + warn_for = { + parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() + if os.path.normcase(parent_dir) not in not_warn_dirs + } + if not warn_for: + return None + + # Format a message + msg_lines = [] + for parent_dir, scripts in warn_for.items(): + scripts = sorted(scripts) + if len(scripts) == 1: + start_text = "script {} is".format(scripts[0]) + else: + start_text = "scripts {} are".format( + ", ".join(scripts[:-1]) + " and " + scripts[-1] + ) + + msg_lines.append( + "The {} installed in '{}' which is not on PATH." + .format(start_text, parent_dir) + ) + + last_line_fmt = ( + "Consider adding {} to PATH or, if you prefer " + "to suppress this warning, use --no-warn-script-location." + ) + if len(msg_lines) == 1: + msg_lines.append(last_line_fmt.format("this directory")) + else: + msg_lines.append(last_line_fmt.format("these directories")) + + # Returns the formatted multiline message + return "\n".join(msg_lines) + + +def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None, + pycompile=True, scheme=None, isolated=False, prefix=None, + warn_script_location=True): + """Install a wheel""" + + if not scheme: + scheme = distutils_scheme( + name, user=user, home=home, root=root, isolated=isolated, + prefix=prefix, + ) + + if root_is_purelib(name, wheeldir): + lib_dir = scheme['purelib'] + else: + lib_dir = scheme['platlib'] + + info_dir = [] + data_dirs = [] + source = wheeldir.rstrip(os.path.sep) + os.path.sep + + # Record details of the files moved + # installed = files copied from the wheel to the destination + # changed = files changed while installing (scripts #! line typically) + # generated = files newly generated during the install (script wrappers) + installed = {} + changed = set() + generated = [] + + # Compile all of the pyc files that we're going to be installing + if pycompile: + with captured_stdout() as stdout: + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + compileall.compile_dir(source, force=True, quiet=True) + logger.debug(stdout.getvalue()) + + def normpath(src, p): + return os.path.relpath(src, p).replace(os.path.sep, '/') + + def record_installed(srcfile, destfile, modified=False): + """Map archive RECORD paths to installation RECORD paths.""" + oldpath = normpath(srcfile, wheeldir) + newpath = normpath(destfile, lib_dir) + installed[oldpath] = newpath + if modified: + changed.add(destfile) + + def clobber(source, dest, is_base, fixer=None, filter=None): + ensure_dir(dest) # common for the 'include' path + + for dir, subdirs, files in os.walk(source): + basedir = dir[len(source):].lstrip(os.path.sep) + destdir = os.path.join(dest, basedir) + if is_base and basedir.split(os.path.sep, 1)[0].endswith('.data'): + continue + for s in subdirs: + destsubdir = os.path.join(dest, basedir, s) + if is_base and basedir == '' and destsubdir.endswith('.data'): + data_dirs.append(s) + continue + elif (is_base and + s.endswith('.dist-info') and + canonicalize_name(s).startswith( + canonicalize_name(req.name))): + assert not info_dir, ('Multiple .dist-info directories: ' + + destsubdir + ', ' + + ', '.join(info_dir)) + info_dir.append(destsubdir) + for f in files: + # Skip unwanted files + if filter and filter(f): + continue + srcfile = os.path.join(dir, f) + destfile = os.path.join(dest, basedir, f) + # directory creation is lazy and after the file filtering above + # to ensure we don't install empty dirs; empty dirs can't be + # uninstalled. + ensure_dir(destdir) + + # We use copyfile (not move, copy, or copy2) to be extra sure + # that we are not moving directories over (copyfile fails for + # directories) as well as to ensure that we are not copying + # over any metadata because we want more control over what + # metadata we actually copy over. + shutil.copyfile(srcfile, destfile) + + # Copy over the metadata for the file, currently this only + # includes the atime and mtime. + st = os.stat(srcfile) + if hasattr(os, "utime"): + os.utime(destfile, (st.st_atime, st.st_mtime)) + + # If our file is executable, then make our destination file + # executable. + if os.access(srcfile, os.X_OK): + st = os.stat(srcfile) + permissions = ( + st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH + ) + os.chmod(destfile, permissions) + + changed = False + if fixer: + changed = fixer(destfile) + record_installed(srcfile, destfile, changed) + + clobber(source, lib_dir, True) + + assert info_dir, "%s .dist-info directory not found" % req + + # Get the defined entry points + ep_file = os.path.join(info_dir[0], 'entry_points.txt') + console, gui = get_entrypoints(ep_file) + + def is_entrypoint_wrapper(name): + # EP, EP.exe and EP-script.py are scripts generated for + # entry point EP by setuptools + if name.lower().endswith('.exe'): + matchname = name[:-4] + elif name.lower().endswith('-script.py'): + matchname = name[:-10] + elif name.lower().endswith(".pya"): + matchname = name[:-4] + else: + matchname = name + # Ignore setuptools-generated scripts + return (matchname in console or matchname in gui) + + for datadir in data_dirs: + fixer = None + filter = None + for subdir in os.listdir(os.path.join(wheeldir, datadir)): + fixer = None + if subdir == 'scripts': + fixer = fix_script + filter = is_entrypoint_wrapper + source = os.path.join(wheeldir, datadir, subdir) + dest = scheme[subdir] + clobber(source, dest, False, fixer=fixer, filter=filter) + + maker = ScriptMaker(None, scheme['scripts']) + + # Ensure old scripts are overwritten. + # See https://github.com/pypa/pip/issues/1800 + maker.clobber = True + + # Ensure we don't generate any variants for scripts because this is almost + # never what somebody wants. + # See https://bitbucket.org/pypa/distlib/issue/35/ + maker.variants = {''} + + # This is required because otherwise distlib creates scripts that are not + # executable. + # See https://bitbucket.org/pypa/distlib/issue/32/ + maker.set_mode = True + + # Simplify the script and fix the fact that the default script swallows + # every single stack trace. + # See https://bitbucket.org/pypa/distlib/issue/34/ + # See https://bitbucket.org/pypa/distlib/issue/33/ + def _get_script_text(entry): + if entry.suffix is None: + raise InstallationError( + "Invalid script entry point: %s for req: %s - A callable " + "suffix is required. Cf https://packaging.python.org/en/" + "latest/distributing.html#console-scripts for more " + "information." % (entry, req) + ) + return maker.script_template % { + "module": entry.prefix, + "import_name": entry.suffix.split(".")[0], + "func": entry.suffix, + } + + maker._get_script_text = _get_script_text + maker.script_template = r"""# -*- coding: utf-8 -*- +import re +import sys + +from %(module)s import %(import_name)s + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(%(func)s()) +""" + + # Special case pip and setuptools to generate versioned wrappers + # + # The issue is that some projects (specifically, pip and setuptools) use + # code in setup.py to create "versioned" entry points - pip2.7 on Python + # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into + # the wheel metadata at build time, and so if the wheel is installed with + # a *different* version of Python the entry points will be wrong. The + # correct fix for this is to enhance the metadata to be able to describe + # such versioned entry points, but that won't happen till Metadata 2.0 is + # available. + # In the meantime, projects using versioned entry points will either have + # incorrect versioned entry points, or they will not be able to distribute + # "universal" wheels (i.e., they will need a wheel per Python version). + # + # Because setuptools and pip are bundled with _ensurepip and virtualenv, + # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we + # override the versioned entry points in the wheel and generate the + # correct ones. This code is purely a short-term measure until Metadata 2.0 + # is available. + # + # To add the level of hack in this section of code, in order to support + # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment + # variable which will control which version scripts get installed. + # + # ENSUREPIP_OPTIONS=altinstall + # - Only pipX.Y and easy_install-X.Y will be generated and installed + # ENSUREPIP_OPTIONS=install + # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note + # that this option is technically if ENSUREPIP_OPTIONS is set and is + # not altinstall + # DEFAULT + # - The default behavior is to install pip, pipX, pipX.Y, easy_install + # and easy_install-X.Y. + pip_script = console.pop('pip', None) + if pip_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'pip = ' + pip_script + generated.extend(maker.make(spec)) + + if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": + spec = 'pip%s = %s' % (sys.version[:1], pip_script) + generated.extend(maker.make(spec)) + + spec = 'pip%s = %s' % (sys.version[:3], pip_script) + generated.extend(maker.make(spec)) + # Delete any other versioned pip entry points + pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] + for k in pip_ep: + del console[k] + easy_install_script = console.pop('easy_install', None) + if easy_install_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'easy_install = ' + easy_install_script + generated.extend(maker.make(spec)) + + spec = 'easy_install-%s = %s' % (sys.version[:3], easy_install_script) + generated.extend(maker.make(spec)) + # Delete any other versioned easy_install entry points + easy_install_ep = [ + k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) + ] + for k in easy_install_ep: + del console[k] + + # Generate the console and GUI entry points specified in the wheel + if len(console) > 0: + generated_console_scripts = maker.make_multiple( + ['%s = %s' % kv for kv in console.items()] + ) + generated.extend(generated_console_scripts) + + if warn_script_location: + msg = message_about_scripts_not_on_PATH(generated_console_scripts) + if msg is not None: + logger.warn(msg) + + if len(gui) > 0: + generated.extend( + maker.make_multiple( + ['%s = %s' % kv for kv in gui.items()], + {'gui': True} + ) + ) + + # Record pip as the installer + installer = os.path.join(info_dir[0], 'INSTALLER') + temp_installer = os.path.join(info_dir[0], 'INSTALLER.pip') + with open(temp_installer, 'wb') as installer_file: + installer_file.write(b'pip\n') + shutil.move(temp_installer, installer) + generated.append(installer) + + # Record details of all files installed + record = os.path.join(info_dir[0], 'RECORD') + temp_record = os.path.join(info_dir[0], 'RECORD.pip') + with open_for_csv(record, 'r') as record_in: + with open_for_csv(temp_record, 'w+') as record_out: + reader = csv.reader(record_in) + writer = csv.writer(record_out) + for row in reader: + row[0] = installed.pop(row[0], row[0]) + if row[0] in changed: + row[1], row[2] = rehash(row[0]) + writer.writerow(row) + for f in generated: + h, l = rehash(f) + writer.writerow((normpath(f, lib_dir), h, l)) + for f in installed: + writer.writerow((installed[f], '', '')) + shutil.move(temp_record, record) + + +def wheel_version(source_dir): + """ + Return the Wheel-Version of an extracted wheel, if possible. + + Otherwise, return False if we couldn't parse / extract it. + """ + try: + dist = [d for d in pkg_resources.find_on_path(None, source_dir)][0] + + wheel_data = dist.get_metadata('WHEEL') + wheel_data = Parser().parsestr(wheel_data) + + version = wheel_data['Wheel-Version'].strip() + version = tuple(map(int, version.split('.'))) + return version + except: + return False + + +def check_compatibility(version, name): + """ + Raises errors or warns if called with an incompatible Wheel-Version. + + Pip should refuse to install a Wheel-Version that's a major series + ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when + installing a version only minor version ahead (e.g 1.2 > 1.1). + + version: a 2-tuple representing a Wheel-Version (Major, Minor) + name: name of wheel or package to raise exception about + + :raises UnsupportedWheel: when an incompatible Wheel-Version is given + """ + if not version: + raise UnsupportedWheel( + "%s is in an unsupported or invalid wheel" % name + ) + if version[0] > VERSION_COMPATIBLE[0]: + raise UnsupportedWheel( + "%s's Wheel-Version (%s) is not compatible with this version " + "of pip" % (name, '.'.join(map(str, version))) + ) + elif version > VERSION_COMPATIBLE: + logger.warning( + 'Installing from a newer Wheel-Version (%s)', + '.'.join(map(str, version)), + ) + + +class Wheel(object): + """A wheel file""" + + # TODO: maybe move the install code into this class + + wheel_file_re = re.compile( + r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?)) + ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?) + \.whl|\.dist-info)$""", + re.VERBOSE + ) + + def __init__(self, filename): + """ + :raises InvalidWheelFilename: when the filename is invalid for a wheel + """ + wheel_info = self.wheel_file_re.match(filename) + if not wheel_info: + raise InvalidWheelFilename( + "%s is not a valid wheel filename." % filename + ) + self.filename = filename + self.name = wheel_info.group('name').replace('_', '-') + # we'll assume "_" means "-" due to wheel naming scheme + # (https://github.com/pypa/pip/issues/1150) + self.version = wheel_info.group('ver').replace('_', '-') + self.build_tag = wheel_info.group('build') + self.pyversions = wheel_info.group('pyver').split('.') + self.abis = wheel_info.group('abi').split('.') + self.plats = wheel_info.group('plat').split('.') + + # All the tag combinations from this file + self.file_tags = { + (x, y, z) for x in self.pyversions + for y in self.abis for z in self.plats + } + + def support_index_min(self, tags=None): + """ + Return the lowest index that one of the wheel's file_tag combinations + achieves in the supported_tags list e.g. if there are 8 supported tags, + and one of the file tags is first in the list, then return 0. Returns + None is the wheel is not supported. + """ + if tags is None: # for mock + tags = pep425tags.get_supported() + indexes = [tags.index(c) for c in self.file_tags if c in tags] + return min(indexes) if indexes else None + + def supported(self, tags=None): + """Is this wheel supported on this system?""" + if tags is None: # for mock + tags = pep425tags.get_supported() + return bool(set(tags).intersection(self.file_tags)) + + +class WheelBuilder(object): + """Build wheels from a RequirementSet.""" + + def __init__(self, finder, preparer, wheel_cache, + build_options=None, global_options=None, no_clean=False): + self.finder = finder + self.preparer = preparer + self.wheel_cache = wheel_cache + + self._wheel_dir = preparer.wheel_download_dir + + self.build_options = build_options or [] + self.global_options = global_options or [] + self.no_clean = no_clean + + def _build_one(self, req, output_dir, python_tag=None): + """Build one wheel. + + :return: The filename of the built wheel, or None if the build failed. + """ + # Install build deps into temporary directory (PEP 518) + with req.build_env: + return self._build_one_inside_env(req, output_dir, + python_tag=python_tag) + + def _build_one_inside_env(self, req, output_dir, python_tag=None): + with TempDirectory(kind="wheel") as temp_dir: + if self.__build_one(req, temp_dir.path, python_tag=python_tag): + try: + wheel_name = os.listdir(temp_dir.path)[0] + wheel_path = os.path.join(output_dir, wheel_name) + shutil.move( + os.path.join(temp_dir.path, wheel_name), wheel_path + ) + logger.info('Stored in directory: %s', output_dir) + return wheel_path + except: + pass + # Ignore return, we can't do anything else useful. + self._clean_one(req) + return None + + def _base_setup_args(self, req): + # NOTE: Eventually, we'd want to also -S to the flags here, when we're + # isolating. Currently, it breaks Python in virtualenvs, because it + # relies on site.py to find parts of the standard library outside the + # virtualenv. + return [ + sys.executable, '-u', '-c', + SETUPTOOLS_SHIM % req.setup_py + ] + list(self.global_options) + + def __build_one(self, req, tempd, python_tag=None): + base_args = self._base_setup_args(req) + + spin_message = 'Running setup.py bdist_wheel for %s' % (req.name,) + with open_spinner(spin_message) as spinner: + logger.debug('Destination directory: %s', tempd) + wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ + + self.build_options + + if python_tag is not None: + wheel_args += ["--python-tag", python_tag] + + try: + call_subprocess(wheel_args, cwd=req.setup_py_dir, + show_stdout=False, spinner=spinner) + return True + except: + spinner.finish("error") + logger.error('Failed building wheel for %s', req.name) + return False + + def _clean_one(self, req): + base_args = self._base_setup_args(req) + + logger.info('Running setup.py clean for %s', req.name) + clean_args = base_args + ['clean', '--all'] + try: + call_subprocess(clean_args, cwd=req.source_dir, show_stdout=False) + return True + except: + logger.error('Failed cleaning build dir for %s', req.name) + return False + + def build(self, requirements, session, autobuilding=False): + """Build wheels. + + :param unpack: If True, replace the sdist we built from with the + newly built wheel, in preparation for installation. + :return: True if all the wheels built correctly. + """ + from pip._internal import index + + building_is_possible = self._wheel_dir or ( + autobuilding and self.wheel_cache.cache_dir + ) + assert building_is_possible + + buildset = [] + for req in requirements: + if req.constraint: + continue + if req.is_wheel: + if not autobuilding: + logger.info( + 'Skipping %s, due to already being wheel.', req.name, + ) + elif autobuilding and req.editable: + pass + elif autobuilding and not req.source_dir: + pass + elif autobuilding and req.link and not req.link.is_artifact: + # VCS checkout. Build wheel just for this run. + buildset.append((req, True)) + else: + ephem_cache = False + if autobuilding: + link = req.link + base, ext = link.splitext() + if index.egg_info_matches(base, None, link) is None: + # E.g. local directory. Build wheel just for this run. + ephem_cache = True + if "binary" not in index.fmt_ctl_formats( + self.finder.format_control, + canonicalize_name(req.name)): + logger.info( + "Skipping bdist_wheel for %s, due to binaries " + "being disabled for it.", req.name, + ) + continue + buildset.append((req, ephem_cache)) + + if not buildset: + return True + + # Build the wheels. + logger.info( + 'Building wheels for collected packages: %s', + ', '.join([req.name for (req, _) in buildset]), + ) + _cache = self.wheel_cache # shorter name + with indent_log(): + build_success, build_failure = [], [] + for req, ephem in buildset: + python_tag = None + if autobuilding: + python_tag = pep425tags.implementation_tag + if ephem: + output_dir = _cache.get_ephem_path_for_link(req.link) + else: + output_dir = _cache.get_path_for_link(req.link) + try: + ensure_dir(output_dir) + except OSError as e: + logger.warning("Building wheel for %s failed: %s", + req.name, e) + build_failure.append(req) + continue + else: + output_dir = self._wheel_dir + wheel_file = self._build_one( + req, output_dir, + python_tag=python_tag, + ) + if wheel_file: + build_success.append(req) + if autobuilding: + # XXX: This is mildly duplicative with prepare_files, + # but not close enough to pull out to a single common + # method. + # The code below assumes temporary source dirs - + # prevent it doing bad things. + if req.source_dir and not os.path.exists(os.path.join( + req.source_dir, PIP_DELETE_MARKER_FILENAME)): + raise AssertionError( + "bad source dir - missing marker") + # Delete the source we built the wheel from + req.remove_temporary_source() + # set the build directory again - name is known from + # the work prepare_files did. + req.source_dir = req.build_location( + self.preparer.build_dir + ) + # Update the link for this. + req.link = index.Link(path_to_url(wheel_file)) + assert req.link.is_wheel + # extract the wheel into the dir + unpack_url( + req.link, req.source_dir, None, False, + session=session, + ) + else: + build_failure.append(req) + + # notify success/failure + if build_success: + logger.info( + 'Successfully built %s', + ' '.join([req.name for req in build_success]), + ) + if build_failure: + logger.info( + 'Failed to build %s', + ' '.join([req.name for req in build_failure]), + ) + # Return True if all builds were successful + return len(build_failure) == 0 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__init__.py new file mode 100644 index 0000000..1387dba --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__init__.py @@ -0,0 +1,109 @@ +""" +pip._vendor is for vendoring dependencies of pip to prevent needing pip to +depend on something external. + +Files inside of pip._vendor should be considered immutable and should only be +updated to versions from upstream. +""" +from __future__ import absolute_import + +import glob +import os.path +import sys + +# Downstream redistributors which have debundled our dependencies should also +# patch this value to be true. This will trigger the additional patching +# to cause things like "six" to be available as pip. +DEBUNDLED = False + +# By default, look in this directory for a bunch of .whl files which we will +# add to the beginning of sys.path before attempting to import anything. This +# is done to support downstream re-distributors like Debian and Fedora who +# wish to create their own Wheels for our dependencies to aid in debundling. +WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) + + +# Define a small helper function to alias our vendored modules to the real ones +# if the vendored ones do not exist. This idea of this was taken from +# https://github.com/kennethreitz/requests/pull/2567. +def vendored(modulename): + vendored_name = "{0}.{1}".format(__name__, modulename) + + try: + __import__(vendored_name, globals(), locals(), level=0) + except ImportError: + try: + __import__(modulename, globals(), locals(), level=0) + except ImportError: + # We can just silently allow import failures to pass here. If we + # got to this point it means that ``import pip._vendor.whatever`` + # failed and so did ``import whatever``. Since we're importing this + # upfront in an attempt to alias imports, not erroring here will + # just mean we get a regular import error whenever pip *actually* + # tries to import one of these modules to use it, which actually + # gives us a better error message than we would have otherwise + # gotten. + pass + else: + sys.modules[vendored_name] = sys.modules[modulename] + base, head = vendored_name.rsplit(".", 1) + setattr(sys.modules[base], head, sys.modules[modulename]) + + +# If we're operating in a debundled setup, then we want to go ahead and trigger +# the aliasing of our vendored libraries as well as looking for wheels to add +# to our sys.path. This will cause all of this code to be a no-op typically +# however downstream redistributors can enable it in a consistent way across +# all platforms. +if DEBUNDLED: + # Actually look inside of WHEEL_DIR to find .whl files and add them to the + # front of our sys.path. + sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path + + # Actually alias all of our vendored dependencies. + vendored("cachecontrol") + vendored("colorama") + vendored("distlib") + vendored("distro") + vendored("html5lib") + vendored("lockfile") + vendored("six") + vendored("six.moves") + vendored("six.moves.urllib") + vendored("six.moves.urllib.parse") + vendored("packaging") + vendored("packaging.version") + vendored("packaging.specifiers") + vendored("pkg_resources") + vendored("progress") + vendored("pytoml") + vendored("retrying") + vendored("requests") + vendored("requests.packages") + vendored("requests.packages.urllib3") + vendored("requests.packages.urllib3._collections") + vendored("requests.packages.urllib3.connection") + vendored("requests.packages.urllib3.connectionpool") + vendored("requests.packages.urllib3.contrib") + vendored("requests.packages.urllib3.contrib.ntlmpool") + vendored("requests.packages.urllib3.contrib.pyopenssl") + vendored("requests.packages.urllib3.exceptions") + vendored("requests.packages.urllib3.fields") + vendored("requests.packages.urllib3.filepost") + vendored("requests.packages.urllib3.packages") + vendored("requests.packages.urllib3.packages.ordered_dict") + vendored("requests.packages.urllib3.packages.six") + vendored("requests.packages.urllib3.packages.ssl_match_hostname") + vendored("requests.packages.urllib3.packages.ssl_match_hostname." + "_implementation") + vendored("requests.packages.urllib3.poolmanager") + vendored("requests.packages.urllib3.request") + vendored("requests.packages.urllib3.response") + vendored("requests.packages.urllib3.util") + vendored("requests.packages.urllib3.util.connection") + vendored("requests.packages.urllib3.util.request") + vendored("requests.packages.urllib3.util.response") + vendored("requests.packages.urllib3.util.retry") + vendored("requests.packages.urllib3.util.ssl_") + vendored("requests.packages.urllib3.util.timeout") + vendored("requests.packages.urllib3.util.url") diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..dd4e46a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/appdirs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000..f5a4fa8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/appdirs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc new file mode 100644 index 0000000..702270c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/retrying.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/retrying.cpython-37.pyc new file mode 100644 index 0000000..e99e4ee Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/retrying.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/six.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000..06280dc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/__pycache__/six.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py new file mode 100644 index 0000000..2bd3911 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/appdirs.py @@ -0,0 +1,604 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy Petrișor + +"""Utilities for determining application-specific dirs. + +See <http://github.com/ActiveState/appdirs> for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html +# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + +__version_info__ = (1, 4, 3) +__version__ = '.'.join(map(str, __version_info__)) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user data directories are: + Mac OS X: ~/Library/Application Support/<AppName> + Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> + Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> + Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> + Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/<AppName>". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/<AppName>', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/<AppName> + Unix: /usr/local/share/<AppName> or /usr/share/<AppName> + Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS + # only first, if multipath is False + path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/<AppName> + Unix: ~/.cache/<AppName> (XDG default) + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go in + the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming + app data dir (the default returned by `user_data_dir` above). Apps typically + put cache data somewhere *under* the given dir here. Some examples: + ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache + ...\Acme\SuperApp\Cache\1.0 + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/<AppName> + Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + if PY3: + import winreg as _winreg + else: + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__init__.py new file mode 100644 index 0000000..f386d49 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__init__.py @@ -0,0 +1,11 @@ +"""CacheControl import Interface. + +Make it easy to import from cachecontrol without long namespaces. +""" +__author__ = 'Eric Larson' +__email__ = 'eric@ionrock.org' +__version__ = '0.12.4' + +from .wrapper import CacheControl +from .adapter import CacheControlAdapter +from .controller import CacheController diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..51c42c7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc new file mode 100644 index 0000000..151f552 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc new file mode 100644 index 0000000..152eb6b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000..97c48ee Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc new file mode 100644 index 0000000..64c11f8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc new file mode 100644 index 0000000..9a8e6f9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc new file mode 100644 index 0000000..891ecfb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc new file mode 100644 index 0000000..c89398a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py new file mode 100644 index 0000000..afdcc88 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/_cmd.py @@ -0,0 +1,60 @@ +import logging + +from pip._vendor import requests + +from pip._vendor.cachecontrol.adapter import CacheControlAdapter +from pip._vendor.cachecontrol.cache import DictCache +from pip._vendor.cachecontrol.controller import logger + +from argparse import ArgumentParser + + +def setup_logging(): + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler() + logger.addHandler(handler) + + +def get_session(): + adapter = CacheControlAdapter( + DictCache(), + cache_etags=True, + serializer=None, + heuristic=None, + ) + sess = requests.Session() + sess.mount('http://', adapter) + sess.mount('https://', adapter) + + sess.cache_controller = adapter.controller + return sess + + +def get_args(): + parser = ArgumentParser() + parser.add_argument('url', help='The URL to try and cache') + return parser.parse_args() + + +def main(args=None): + args = get_args() + sess = get_session() + + # Make a request to get a response + resp = sess.get(args.url) + + # Turn on logging + setup_logging() + + # try setting the cache + sess.cache_controller.cache_response(resp.request, resp.raw) + + # Now try to get it + if sess.cache_controller.cached_request(resp.request): + print('Cached!') + else: + print('Not cached :(') + + +if __name__ == '__main__': + main() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py new file mode 100644 index 0000000..ecb34a6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/adapter.py @@ -0,0 +1,134 @@ +import types +import functools +import zlib + +from pip._vendor.requests.adapters import HTTPAdapter + +from .controller import CacheController +from .cache import DictCache +from .filewrapper import CallbackFileWrapper + + +class CacheControlAdapter(HTTPAdapter): + invalidating_methods = set(['PUT', 'DELETE']) + + def __init__(self, cache=None, + cache_etags=True, + controller_class=None, + serializer=None, + heuristic=None, + cacheable_methods=None, + *args, **kw): + super(CacheControlAdapter, self).__init__(*args, **kw) + self.cache = cache or DictCache() + self.heuristic = heuristic + self.cacheable_methods = cacheable_methods or ('GET',) + + controller_factory = controller_class or CacheController + self.controller = controller_factory( + self.cache, + cache_etags=cache_etags, + serializer=serializer, + ) + + def send(self, request, cacheable_methods=None, **kw): + """ + Send a request. Use the request information to see if it + exists in the cache and cache the response if we need to and can. + """ + cacheable = cacheable_methods or self.cacheable_methods + if request.method in cacheable: + try: + cached_response = self.controller.cached_request(request) + except zlib.error: + cached_response = None + if cached_response: + return self.build_response(request, cached_response, + from_cache=True) + + # check for etags and add headers if appropriate + request.headers.update( + self.controller.conditional_headers(request) + ) + + resp = super(CacheControlAdapter, self).send(request, **kw) + + return resp + + def build_response(self, request, response, from_cache=False, + cacheable_methods=None): + """ + Build a response by making a request or using the cache. + + This will end up calling send and returning a potentially + cached response + """ + cacheable = cacheable_methods or self.cacheable_methods + if not from_cache and request.method in cacheable: + # Check for any heuristics that might update headers + # before trying to cache. + if self.heuristic: + response = self.heuristic.apply(response) + + # apply any expiration heuristics + if response.status == 304: + # We must have sent an ETag request. This could mean + # that we've been expired already or that we simply + # have an etag. In either case, we want to try and + # update the cache if that is the case. + cached_response = self.controller.update_cached_response( + request, response + ) + + if cached_response is not response: + from_cache = True + + # We are done with the server response, read a + # possible response body (compliant servers will + # not return one, but we cannot be 100% sure) and + # release the connection back to the pool. + response.read(decode_content=False) + response.release_conn() + + response = cached_response + + # We always cache the 301 responses + elif response.status == 301: + self.controller.cache_response(request, response) + else: + # Wrap the response file with a wrapper that will cache the + # response when the stream has been consumed. + response._fp = CallbackFileWrapper( + response._fp, + functools.partial( + self.controller.cache_response, + request, + response, + ) + ) + if response.chunked: + super_update_chunk_length = response._update_chunk_length + + def _update_chunk_length(self): + super_update_chunk_length() + if self.chunk_left == 0: + self._fp._close() + response._update_chunk_length = types.MethodType(_update_chunk_length, response) + + resp = super(CacheControlAdapter, self).build_response( + request, response + ) + + # See if we should invalidate the cache. + if request.method in self.invalidating_methods and resp.ok: + cache_url = self.controller.cache_url(request.url) + self.cache.delete(cache_url) + + # Give the request a from_cache attr to let people use it + resp.from_cache = from_cache + + return resp + + def close(self): + self.cache.close() + super(CacheControlAdapter, self).close() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/cache.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/cache.py new file mode 100644 index 0000000..7389a73 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/cache.py @@ -0,0 +1,39 @@ +""" +The cache object API for implementing caches. The default is a thread +safe in-memory dictionary. +""" +from threading import Lock + + +class BaseCache(object): + + def get(self, key): + raise NotImplemented() + + def set(self, key, value): + raise NotImplemented() + + def delete(self, key): + raise NotImplemented() + + def close(self): + pass + + +class DictCache(BaseCache): + + def __init__(self, init_dict=None): + self.lock = Lock() + self.data = init_dict or {} + + def get(self, key): + return self.data.get(key, None) + + def set(self, key, value): + with self.lock: + self.data.update({key: value}) + + def delete(self, key): + with self.lock: + if key in self.data: + self.data.pop(key) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py new file mode 100644 index 0000000..0e1658f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__init__.py @@ -0,0 +1,2 @@ +from .file_cache import FileCache # noqa +from .redis_cache import RedisCache # noqa diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..02efdda Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc new file mode 100644 index 0000000..6b26257 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc new file mode 100644 index 0000000..88495a8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py new file mode 100644 index 0000000..885c8a6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/file_cache.py @@ -0,0 +1,133 @@ +import hashlib +import os +from textwrap import dedent + +from ..cache import BaseCache +from ..controller import CacheController + +try: + FileNotFoundError +except NameError: + # py2.X + FileNotFoundError = OSError + + +def _secure_open_write(filename, fmode): + # We only want to write to this file, so open it in write only mode + flags = os.O_WRONLY + + # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only + # will open *new* files. + # We specify this because we want to ensure that the mode we pass is the + # mode of the file. + flags |= os.O_CREAT | os.O_EXCL + + # Do not follow symlinks to prevent someone from making a symlink that + # we follow and insecurely open a cache file. + if hasattr(os, "O_NOFOLLOW"): + flags |= os.O_NOFOLLOW + + # On Windows we'll mark this file as binary + if hasattr(os, "O_BINARY"): + flags |= os.O_BINARY + + # Before we open our file, we want to delete any existing file that is + # there + try: + os.remove(filename) + except (IOError, OSError): + # The file must not exist already, so we can just skip ahead to opening + pass + + # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a + # race condition happens between the os.remove and this line, that an + # error will be raised. Because we utilize a lockfile this should only + # happen if someone is attempting to attack us. + fd = os.open(filename, flags, fmode) + try: + return os.fdopen(fd, "wb") + except: + # An error occurred wrapping our FD in a file object + os.close(fd) + raise + + +class FileCache(BaseCache): + def __init__(self, directory, forever=False, filemode=0o0600, + dirmode=0o0700, use_dir_lock=None, lock_class=None): + + if use_dir_lock is not None and lock_class is not None: + raise ValueError("Cannot use use_dir_lock and lock_class together") + + try: + from pip._vendor.lockfile import LockFile + from pip._vendor.lockfile.mkdirlockfile import MkdirLockFile + except ImportError: + notice = dedent(""" + NOTE: In order to use the FileCache you must have + lockfile installed. You can install it via pip: + pip install lockfile + """) + raise ImportError(notice) + else: + if use_dir_lock: + lock_class = MkdirLockFile + + elif lock_class is None: + lock_class = LockFile + + self.directory = directory + self.forever = forever + self.filemode = filemode + self.dirmode = dirmode + self.lock_class = lock_class + + @staticmethod + def encode(x): + return hashlib.sha224(x.encode()).hexdigest() + + def _fn(self, name): + # NOTE: This method should not change as some may depend on it. + # See: https://github.com/ionrock/cachecontrol/issues/63 + hashed = self.encode(name) + parts = list(hashed[:5]) + [hashed] + return os.path.join(self.directory, *parts) + + def get(self, key): + name = self._fn(key) + if not os.path.exists(name): + return None + + with open(name, 'rb') as fh: + return fh.read() + + def set(self, key, value): + name = self._fn(key) + + # Make sure the directory exists + try: + os.makedirs(os.path.dirname(name), self.dirmode) + except (IOError, OSError): + pass + + with self.lock_class(name) as lock: + # Write our actual file + with _secure_open_write(lock.path, self.filemode) as fh: + fh.write(value) + + def delete(self, key): + name = self._fn(key) + if not self.forever: + try: + os.remove(name) + except FileNotFoundError: + pass + + +def url_to_file_path(url, filecache): + """Return the file cache path based on the URL. + + This does not ensure the file exists! + """ + key = CacheController.cache_url(url) + return filecache._fn(key) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py new file mode 100644 index 0000000..b6285e9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/caches/redis_cache.py @@ -0,0 +1,43 @@ +from __future__ import division + +from datetime import datetime +from pip._vendor.cachecontrol.cache import BaseCache + + +def total_seconds(td): + """Python 2.6 compatability""" + if hasattr(td, 'total_seconds'): + return int(td.total_seconds()) + + ms = td.microseconds + secs = (td.seconds + td.days * 24 * 3600) + return int((ms + secs * 10**6) / 10**6) + + +class RedisCache(BaseCache): + + def __init__(self, conn): + self.conn = conn + + def get(self, key): + return self.conn.get(key) + + def set(self, key, value, expires=None): + if not expires: + self.conn.set(key, value) + else: + expires = expires - datetime.utcnow() + self.conn.setex(key, total_seconds(expires), value) + + def delete(self, key): + self.conn.delete(key) + + def clear(self): + """Helper for clearing all the keys in a database. Use with + caution!""" + for key in self.conn.keys(): + self.conn.delete(key) + + def close(self): + """Redis uses connection pooling, no need to close the connection.""" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/compat.py new file mode 100644 index 0000000..33b5aed --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/compat.py @@ -0,0 +1,29 @@ +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +try: + import cPickle as pickle +except ImportError: + import pickle + + +# Handle the case where the requests module has been patched to not have +# urllib3 bundled as part of its source. +try: + from pip._vendor.requests.packages.urllib3.response import HTTPResponse +except ImportError: + from pip._vendor.urllib3.response import HTTPResponse + +try: + from pip._vendor.requests.packages.urllib3.util import is_fp_closed +except ImportError: + from pip._vendor.urllib3.util import is_fp_closed + +# Replicate some six behaviour +try: + text_type = unicode +except NameError: + text_type = str diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/controller.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/controller.py new file mode 100644 index 0000000..0e2eb3c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/controller.py @@ -0,0 +1,373 @@ +""" +The httplib2 algorithms ported for use with requests. +""" +import logging +import re +import calendar +import time +from email.utils import parsedate_tz + +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .cache import DictCache +from .serialize import Serializer + + +logger = logging.getLogger(__name__) + +URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") + + +def parse_uri(uri): + """Parses a URI using the regex given in Appendix B of RFC 3986. + + (scheme, authority, path, query, fragment) = parse_uri(uri) + """ + groups = URI.match(uri).groups() + return (groups[1], groups[3], groups[4], groups[6], groups[8]) + + +class CacheController(object): + """An interface to see if request should cached or not. + """ + def __init__(self, cache=None, cache_etags=True, serializer=None, + status_codes=None): + self.cache = cache or DictCache() + self.cache_etags = cache_etags + self.serializer = serializer or Serializer() + self.cacheable_status_codes = status_codes or (200, 203, 300, 301) + + @classmethod + def _urlnorm(cls, uri): + """Normalize the URL to create a safe key for the cache""" + (scheme, authority, path, query, fragment) = parse_uri(uri) + if not scheme or not authority: + raise Exception("Only absolute URIs are allowed. uri = %s" % uri) + + scheme = scheme.lower() + authority = authority.lower() + + if not path: + path = "/" + + # Could do syntax based normalization of the URI before + # computing the digest. See Section 6.2.2 of Std 66. + request_uri = query and "?".join([path, query]) or path + defrag_uri = scheme + "://" + authority + request_uri + + return defrag_uri + + @classmethod + def cache_url(cls, uri): + return cls._urlnorm(uri) + + def parse_cache_control(self, headers): + known_directives = { + # https://tools.ietf.org/html/rfc7234#section-5.2 + 'max-age': (int, True,), + 'max-stale': (int, False,), + 'min-fresh': (int, True,), + 'no-cache': (None, False,), + 'no-store': (None, False,), + 'no-transform': (None, False,), + 'only-if-cached' : (None, False,), + 'must-revalidate': (None, False,), + 'public': (None, False,), + 'private': (None, False,), + 'proxy-revalidate': (None, False,), + 's-maxage': (int, True,) + } + + cc_headers = headers.get('cache-control', + headers.get('Cache-Control', '')) + + retval = {} + + for cc_directive in cc_headers.split(','): + parts = cc_directive.split('=', 1) + directive = parts[0].strip() + + try: + typ, required = known_directives[directive] + except KeyError: + logger.debug('Ignoring unknown cache-control directive: %s', + directive) + continue + + if not typ or not required: + retval[directive] = None + if typ: + try: + retval[directive] = typ(parts[1].strip()) + except IndexError: + if required: + logger.debug('Missing value for cache-control ' + 'directive: %s', directive) + except ValueError: + logger.debug('Invalid value for cache-control directive ' + '%s, must be %s', directive, typ.__name__) + + return retval + + def cached_request(self, request): + """ + Return a cached response if it exists in the cache, otherwise + return False. + """ + cache_url = self.cache_url(request.url) + logger.debug('Looking up "%s" in the cache', cache_url) + cc = self.parse_cache_control(request.headers) + + # Bail out if the request insists on fresh data + if 'no-cache' in cc: + logger.debug('Request header has "no-cache", cache bypassed') + return False + + if 'max-age' in cc and cc['max-age'] == 0: + logger.debug('Request header has "max_age" as 0, cache bypassed') + return False + + # Request allows serving from the cache, let's see if we find something + cache_data = self.cache.get(cache_url) + if cache_data is None: + logger.debug('No cache entry available') + return False + + # Check whether it can be deserialized + resp = self.serializer.loads(request, cache_data) + if not resp: + logger.warning('Cache entry deserialization failed, entry ignored') + return False + + # If we have a cached 301, return it immediately. We don't + # need to test our response for other headers b/c it is + # intrinsically "cacheable" as it is Permanent. + # See: + # https://tools.ietf.org/html/rfc7231#section-6.4.2 + # + # Client can try to refresh the value by repeating the request + # with cache busting headers as usual (ie no-cache). + if resp.status == 301: + msg = ('Returning cached "301 Moved Permanently" response ' + '(ignoring date and etag information)') + logger.debug(msg) + return resp + + headers = CaseInsensitiveDict(resp.headers) + if not headers or 'date' not in headers: + if 'etag' not in headers: + # Without date or etag, the cached response can never be used + # and should be deleted. + logger.debug('Purging cached response: no date or etag') + self.cache.delete(cache_url) + logger.debug('Ignoring cached response: no date') + return False + + now = time.time() + date = calendar.timegm( + parsedate_tz(headers['date']) + ) + current_age = max(0, now - date) + logger.debug('Current age based on date: %i', current_age) + + # TODO: There is an assumption that the result will be a + # urllib3 response object. This may not be best since we + # could probably avoid instantiating or constructing the + # response until we know we need it. + resp_cc = self.parse_cache_control(headers) + + # determine freshness + freshness_lifetime = 0 + + # Check the max-age pragma in the cache control header + if 'max-age' in resp_cc: + freshness_lifetime = resp_cc['max-age'] + logger.debug('Freshness lifetime from max-age: %i', + freshness_lifetime) + + # If there isn't a max-age, check for an expires header + elif 'expires' in headers: + expires = parsedate_tz(headers['expires']) + if expires is not None: + expire_time = calendar.timegm(expires) - date + freshness_lifetime = max(0, expire_time) + logger.debug("Freshness lifetime from expires: %i", + freshness_lifetime) + + # Determine if we are setting freshness limit in the + # request. Note, this overrides what was in the response. + if 'max-age' in cc: + freshness_lifetime = cc['max-age'] + logger.debug('Freshness lifetime from request max-age: %i', + freshness_lifetime) + + if 'min-fresh' in cc: + min_fresh = cc['min-fresh'] + # adjust our current age by our min fresh + current_age += min_fresh + logger.debug('Adjusted current age from min-fresh: %i', + current_age) + + # Return entry if it is fresh enough + if freshness_lifetime > current_age: + logger.debug('The response is "fresh", returning cached response') + logger.debug('%i > %i', freshness_lifetime, current_age) + return resp + + # we're not fresh. If we don't have an Etag, clear it out + if 'etag' not in headers: + logger.debug( + 'The cached response is "stale" with no etag, purging' + ) + self.cache.delete(cache_url) + + # return the original handler + return False + + def conditional_headers(self, request): + cache_url = self.cache_url(request.url) + resp = self.serializer.loads(request, self.cache.get(cache_url)) + new_headers = {} + + if resp: + headers = CaseInsensitiveDict(resp.headers) + + if 'etag' in headers: + new_headers['If-None-Match'] = headers['ETag'] + + if 'last-modified' in headers: + new_headers['If-Modified-Since'] = headers['Last-Modified'] + + return new_headers + + def cache_response(self, request, response, body=None, + status_codes=None): + """ + Algorithm for caching requests. + + This assumes a requests Response object. + """ + # From httplib2: Don't cache 206's since we aren't going to + # handle byte range requests + cacheable_status_codes = status_codes or self.cacheable_status_codes + if response.status not in cacheable_status_codes: + logger.debug( + 'Status code %s not in %s', + response.status, + cacheable_status_codes + ) + return + + response_headers = CaseInsensitiveDict(response.headers) + + # If we've been given a body, our response has a Content-Length, that + # Content-Length is valid then we can check to see if the body we've + # been given matches the expected size, and if it doesn't we'll just + # skip trying to cache it. + if (body is not None and + "content-length" in response_headers and + response_headers["content-length"].isdigit() and + int(response_headers["content-length"]) != len(body)): + return + + cc_req = self.parse_cache_control(request.headers) + cc = self.parse_cache_control(response_headers) + + cache_url = self.cache_url(request.url) + logger.debug('Updating cache with response from "%s"', cache_url) + + # Delete it from the cache if we happen to have it stored there + no_store = False + if 'no-store' in cc: + no_store = True + logger.debug('Response header has "no-store"') + if 'no-store' in cc_req: + no_store = True + logger.debug('Request header has "no-store"') + if no_store and self.cache.get(cache_url): + logger.debug('Purging existing cache entry to honor "no-store"') + self.cache.delete(cache_url) + + # If we've been given an etag, then keep the response + if self.cache_etags and 'etag' in response_headers: + logger.debug('Caching due to etag') + self.cache.set( + cache_url, + self.serializer.dumps(request, response, body=body), + ) + + # Add to the cache any 301s. We do this before looking that + # the Date headers. + elif response.status == 301: + logger.debug('Caching permanant redirect') + self.cache.set( + cache_url, + self.serializer.dumps(request, response) + ) + + # Add to the cache if the response headers demand it. If there + # is no date header then we can't do anything about expiring + # the cache. + elif 'date' in response_headers: + # cache when there is a max-age > 0 + if 'max-age' in cc and cc['max-age'] > 0: + logger.debug('Caching b/c date exists and max-age > 0') + self.cache.set( + cache_url, + self.serializer.dumps(request, response, body=body), + ) + + # If the request can expire, it means we should cache it + # in the meantime. + elif 'expires' in response_headers: + if response_headers['expires']: + logger.debug('Caching b/c of expires header') + self.cache.set( + cache_url, + self.serializer.dumps(request, response, body=body), + ) + + def update_cached_response(self, request, response): + """On a 304 we will get a new set of headers that we want to + update our cached value with, assuming we have one. + + This should only ever be called when we've sent an ETag and + gotten a 304 as the response. + """ + cache_url = self.cache_url(request.url) + + cached_response = self.serializer.loads( + request, + self.cache.get(cache_url) + ) + + if not cached_response: + # we didn't have a cached response + return response + + # Lets update our headers with the headers from the new request: + # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1 + # + # The server isn't supposed to send headers that would make + # the cached body invalid. But... just in case, we'll be sure + # to strip out ones we know that might be problmatic due to + # typical assumptions. + excluded_headers = [ + "content-length", + ] + + cached_response.headers.update( + dict((k, v) for k, v in response.headers.items() + if k.lower() not in excluded_headers) + ) + + # we want a 200 b/c we have content via the cache + cached_response.status = 200 + + # update our cache + self.cache.set( + cache_url, + self.serializer.dumps(request, cached_response), + ) + + return cached_response diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py new file mode 100644 index 0000000..f1e1ce0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/filewrapper.py @@ -0,0 +1,78 @@ +from io import BytesIO + + +class CallbackFileWrapper(object): + """ + Small wrapper around a fp object which will tee everything read into a + buffer, and when that file is closed it will execute a callback with the + contents of that buffer. + + All attributes are proxied to the underlying file object. + + This class uses members with a double underscore (__) leading prefix so as + not to accidentally shadow an attribute. + """ + + def __init__(self, fp, callback): + self.__buf = BytesIO() + self.__fp = fp + self.__callback = callback + + def __getattr__(self, name): + # The vaguaries of garbage collection means that self.__fp is + # not always set. By using __getattribute__ and the private + # name[0] allows looking up the attribute value and raising an + # AttributeError when it doesn't exist. This stop thigns from + # infinitely recursing calls to getattr in the case where + # self.__fp hasn't been set. + # + # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers + fp = self.__getattribute__('_CallbackFileWrapper__fp') + return getattr(fp, name) + + def __is_fp_closed(self): + try: + return self.__fp.fp is None + except AttributeError: + pass + + try: + return self.__fp.closed + except AttributeError: + pass + + # We just don't cache it then. + # TODO: Add some logging here... + return False + + def _close(self): + if self.__callback: + self.__callback(self.__buf.getvalue()) + + # We assign this to None here, because otherwise we can get into + # really tricky problems where the CPython interpreter dead locks + # because the callback is holding a reference to something which + # has a __del__ method. Setting this to None breaks the cycle + # and allows the garbage collector to do it's thing normally. + self.__callback = None + + def read(self, amt=None): + data = self.__fp.read(amt) + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data + + def _safe_read(self, amt): + data = self.__fp._safe_read(amt) + if amt == 2 and data == b'\r\n': + # urllib executes this read to toss the CRLF at the end + # of the chunk. + return data + + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py new file mode 100644 index 0000000..f182ff0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/heuristics.py @@ -0,0 +1,138 @@ +import calendar +import time + +from email.utils import formatdate, parsedate, parsedate_tz + +from datetime import datetime, timedelta + +TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" + + +def expire_after(delta, date=None): + date = date or datetime.utcnow() + return date + delta + + +def datetime_to_header(dt): + return formatdate(calendar.timegm(dt.timetuple())) + + +class BaseHeuristic(object): + + def warning(self, response): + """ + Return a valid 1xx warning header value describing the cache + adjustments. + + The response is provided too allow warnings like 113 + http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need + to explicitly say response is over 24 hours old. + """ + return '110 - "Response is Stale"' + + def update_headers(self, response): + """Update the response headers with any new headers. + + NOTE: This SHOULD always include some Warning header to + signify that the response was cached by the client, not + by way of the provided headers. + """ + return {} + + def apply(self, response): + updated_headers = self.update_headers(response) + + if updated_headers: + response.headers.update(updated_headers) + warning_header_value = self.warning(response) + if warning_header_value is not None: + response.headers.update({'Warning': warning_header_value}) + + return response + + +class OneDayCache(BaseHeuristic): + """ + Cache the response by providing an expires 1 day in the + future. + """ + def update_headers(self, response): + headers = {} + + if 'expires' not in response.headers: + date = parsedate(response.headers['date']) + expires = expire_after(timedelta(days=1), + date=datetime(*date[:6])) + headers['expires'] = datetime_to_header(expires) + headers['cache-control'] = 'public' + return headers + + +class ExpiresAfter(BaseHeuristic): + """ + Cache **all** requests for a defined time period. + """ + + def __init__(self, **kw): + self.delta = timedelta(**kw) + + def update_headers(self, response): + expires = expire_after(self.delta) + return { + 'expires': datetime_to_header(expires), + 'cache-control': 'public', + } + + def warning(self, response): + tmpl = '110 - Automatically cached for %s. Response might be stale' + return tmpl % self.delta + + +class LastModified(BaseHeuristic): + """ + If there is no Expires header already, fall back on Last-Modified + using the heuristic from + http://tools.ietf.org/html/rfc7234#section-4.2.2 + to calculate a reasonable value. + + Firefox also does something like this per + https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ + http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397 + Unlike mozilla we limit this to 24-hr. + """ + cacheable_by_default_statuses = set([ + 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501 + ]) + + def update_headers(self, resp): + headers = resp.headers + + if 'expires' in headers: + return {} + + if 'cache-control' in headers and headers['cache-control'] != 'public': + return {} + + if resp.status not in self.cacheable_by_default_statuses: + return {} + + if 'date' not in headers or 'last-modified' not in headers: + return {} + + date = calendar.timegm(parsedate_tz(headers['date'])) + last_modified = parsedate(headers['last-modified']) + if date is None or last_modified is None: + return {} + + now = time.time() + current_age = max(0, now - date) + delta = date - calendar.timegm(last_modified) + freshness_lifetime = max(0, min(delta / 10, 24 * 3600)) + if freshness_lifetime <= current_age: + return {} + + expires = date + freshness_lifetime + return {'expires': time.strftime(TIME_FMT, time.gmtime(expires))} + + def warning(self, resp): + return None diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/serialize.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/serialize.py new file mode 100644 index 0000000..05b6e24 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/serialize.py @@ -0,0 +1,194 @@ +import base64 +import io +import json +import zlib + +from pip._vendor import msgpack +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .compat import HTTPResponse, pickle, text_type + + +def _b64_decode_bytes(b): + return base64.b64decode(b.encode("ascii")) + + +def _b64_decode_str(s): + return _b64_decode_bytes(s).decode("utf8") + + +class Serializer(object): + + def dumps(self, request, response, body=None): + response_headers = CaseInsensitiveDict(response.headers) + + if body is None: + body = response.read(decode_content=False) + + # NOTE: 99% sure this is dead code. I'm only leaving it + # here b/c I don't have a test yet to prove + # it. Basically, before using + # `cachecontrol.filewrapper.CallbackFileWrapper`, + # this made an effort to reset the file handle. The + # `CallbackFileWrapper` short circuits this code by + # setting the body as the content is consumed, the + # result being a `body` argument is *always* passed + # into cache_response, and in turn, + # `Serializer.dump`. + response._fp = io.BytesIO(body) + + # NOTE: This is all a bit weird, but it's really important that on + # Python 2.x these objects are unicode and not str, even when + # they contain only ascii. The problem here is that msgpack + # understands the difference between unicode and bytes and we + # have it set to differentiate between them, however Python 2 + # doesn't know the difference. Forcing these to unicode will be + # enough to have msgpack know the difference. + data = { + u"response": { + u"body": body, + u"headers": dict( + (text_type(k), text_type(v)) + for k, v in response.headers.items() + ), + u"status": response.status, + u"version": response.version, + u"reason": text_type(response.reason), + u"strict": response.strict, + u"decode_content": response.decode_content, + }, + } + + # Construct our vary headers + data[u"vary"] = {} + if u"vary" in response_headers: + varied_headers = response_headers[u'vary'].split(',') + for header in varied_headers: + header = header.strip() + header_value = request.headers.get(header, None) + if header_value is not None: + header_value = text_type(header_value) + data[u"vary"][header] = header_value + + return b",".join([b"cc=4", msgpack.dumps(data, use_bin_type=True)]) + + def loads(self, request, data): + # Short circuit if we've been given an empty set of data + if not data: + return + + # Determine what version of the serializer the data was serialized + # with + try: + ver, data = data.split(b",", 1) + except ValueError: + ver = b"cc=0" + + # Make sure that our "ver" is actually a version and isn't a false + # positive from a , being in the data stream. + if ver[:3] != b"cc=": + data = ver + data + ver = b"cc=0" + + # Get the version number out of the cc=N + ver = ver.split(b"=", 1)[-1].decode("ascii") + + # Dispatch to the actual load method for the given version + try: + return getattr(self, "_loads_v{0}".format(ver))(request, data) + except AttributeError: + # This is a version we don't have a loads function for, so we'll + # just treat it as a miss and return None + return + + def prepare_response(self, request, cached): + """Verify our vary headers match and construct a real urllib3 + HTTPResponse object. + """ + # Special case the '*' Vary value as it means we cannot actually + # determine if the cached response is suitable for this request. + if "*" in cached.get("vary", {}): + return + + # Ensure that the Vary headers for the cached response match our + # request + for header, value in cached.get("vary", {}).items(): + if request.headers.get(header, None) != value: + return + + body_raw = cached["response"].pop("body") + + headers = CaseInsensitiveDict(data=cached['response']['headers']) + if headers.get('transfer-encoding', '') == 'chunked': + headers.pop('transfer-encoding') + + cached['response']['headers'] = headers + + try: + body = io.BytesIO(body_raw) + except TypeError: + # This can happen if cachecontrol serialized to v1 format (pickle) + # using Python 2. A Python 2 str(byte string) will be unpickled as + # a Python 3 str (unicode string), which will cause the above to + # fail with: + # + # TypeError: 'str' does not support the buffer interface + body = io.BytesIO(body_raw.encode('utf8')) + + return HTTPResponse( + body=body, + preload_content=False, + **cached["response"] + ) + + def _loads_v0(self, request, data): + # The original legacy cache data. This doesn't contain enough + # information to construct everything we need, so we'll treat this as + # a miss. + return + + def _loads_v1(self, request, data): + try: + cached = pickle.loads(data) + except ValueError: + return + + return self.prepare_response(request, cached) + + def _loads_v2(self, request, data): + try: + cached = json.loads(zlib.decompress(data).decode("utf8")) + except (ValueError, zlib.error): + return + + # We need to decode the items that we've base64 encoded + cached["response"]["body"] = _b64_decode_bytes( + cached["response"]["body"] + ) + cached["response"]["headers"] = dict( + (_b64_decode_str(k), _b64_decode_str(v)) + for k, v in cached["response"]["headers"].items() + ) + cached["response"]["reason"] = _b64_decode_str( + cached["response"]["reason"], + ) + cached["vary"] = dict( + (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + for k, v in cached["vary"].items() + ) + + return self.prepare_response(request, cached) + + def _loads_v3(self, request, data): + # Due to Python 2 encoding issues, it's impossible to know for sure + # exactly how to load v3 entries, thus we'll treat these as a miss so + # that they get rewritten out as v4 entries. + return + + def _loads_v4(self, request, data): + try: + cached = msgpack.loads(data, encoding='utf-8') + except ValueError: + return + + return self.prepare_response(request, cached) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py new file mode 100644 index 0000000..b50a6e2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/cachecontrol/wrapper.py @@ -0,0 +1,27 @@ +from .adapter import CacheControlAdapter +from .cache import DictCache + + +def CacheControl(sess, + cache=None, + cache_etags=True, + serializer=None, + heuristic=None, + controller_class=None, + adapter_class=None, + cacheable_methods=None): + + cache = cache or DictCache() + adapter_class = adapter_class or CacheControlAdapter + adapter = adapter_class( + cache, + cache_etags=cache_etags, + serializer=serializer, + heuristic=heuristic, + controller_class=controller_class, + cacheable_methods=cacheable_methods + ) + sess.mount('http://', adapter) + sess.mount('https://', adapter) + + return sess diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__init__.py new file mode 100644 index 0000000..556193c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__init__.py @@ -0,0 +1,3 @@ +from .core import where, old_where + +__version__ = "2018.01.18" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__main__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__main__.py new file mode 100644 index 0000000..5f1da0d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__main__.py @@ -0,0 +1,2 @@ +from certifi import where +print(where()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..b92ab12 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000..e998bb5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/cacert.pem b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/cacert.pem new file mode 100644 index 0000000..101ac98 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/cacert.pem @@ -0,0 +1,4433 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Label: "GlobalSign Root CA - R2" +# Serial: 4835703278459682885658125 +# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 +# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe +# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Label: "Verisign Class 3 Public Primary Certification Authority - G3" +# Serial: 206684696279472310254277870180966723415 +# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 +# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 +# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Label: "AddTrust External Root" +# Serial: 1 +# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f +# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 +# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. +# Label: "GeoTrust Global CA" +# Serial: 144470 +# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 +# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 +# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Label: "GeoTrust Universal CA" +# Serial: 1 +# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 +# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 +# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Label: "GeoTrust Universal CA 2" +# Serial: 1 +# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 +# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 +# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Label: "Visa eCommerce Root" +# Serial: 25952180776285836048024890241505565794 +# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02 +# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62 +# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22 +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Label: "QuoVadis Root CA" +# Serial: 985026699 +# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 +# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 +# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=Sonera Class2 CA O=Sonera +# Subject: CN=Sonera Class2 CA O=Sonera +# Label: "Sonera Class 2 Root CA" +# Serial: 29 +# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb +# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 +# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: O=Government Root Certification Authority +# Subject: O=Government Root Certification Authority +# Label: "Taiwan GRCA" +# Serial: 42023070807708724159991140556527066870 +# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e +# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 +# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=Class 2 Primary CA O=Certplus +# Subject: CN=Class 2 Primary CA O=Certplus +# Label: "Certplus Class 2 Primary CA" +# Serial: 177770208045934040241468760488327595043 +# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b +# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb +# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Label: "DST Root CA X3" +# Serial: 91299735575339953335919266965803778155 +# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 +# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 +# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Label: "GeoTrust Primary Certification Authority" +# Serial: 32798226551256963324313806436981982369 +# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf +# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 +# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA" +# Serial: 69529181992039203566298953787712940909 +# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 +# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 +# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" +# Serial: 33037644167568058970164719475676101450 +# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c +# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 +# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Label: "Network Solutions Certificate Authority" +# Serial: 116697915152937497490437556386812487904 +# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e +# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce +# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GA CA" +# Serial: 86718877871133159090080555911823548314 +# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 +# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 +# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Label: "Deutsche Telekom Root CA 2" +# Serial: 38 +# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 +# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf +# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc +# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc +# Label: "Cybertrust Global Root" +# Serial: 4835703278459682877484360 +# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 +# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 +# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G3" +# Serial: 28809105769928564313984085209975885599 +# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 +# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd +# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G2" +# Serial: 71758320672825410020661621085256472406 +# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f +# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 +# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G3" +# Serial: 127614157056681299805556476275995414779 +# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 +# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 +# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G2" +# Serial: 80682863203381065782177908751794619243 +# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a +# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 +# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Universal Root Certification Authority" +# Serial: 85209574734084581917763752644031726877 +# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 +# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 +# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" +# Serial: 63143484348153506665311985501458640051 +# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 +# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a +# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G2" +# Serial: 10000012 +# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a +# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 +# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX +DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 +qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp +uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU +Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE +pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp +5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M +UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN +GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy +5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv +6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK +eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 +B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ +BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov +L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG +SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS +CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen +5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 +IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK +gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL ++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL +vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm +bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk +N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC +Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z +ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Label: "Hongkong Post Root CA 1" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Label: "Chambers of Commerce Root - 2008" +# Serial: 11806822484801597146 +# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 +# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c +# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Label: "Global Chambersign Root - 2008" +# Serial: 14541511773111788494 +# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 +# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c +# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2011" +# Serial: 0 +# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 +# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d +# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: O=Trustis Limited OU=Trustis FPS Root CA +# Subject: O=Trustis Limited OU=Trustis FPS Root CA +# Label: "Trustis FPS Root CA" +# Serial: 36053640375399034304724988975563710553 +# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d +# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 +# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Label: "EE Certification Centre Root CA" +# Serial: 112324828676200291871926431888494945866 +# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f +# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 +# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Label: "E-Tugra Certification Authority" +# Serial: 7667447206703254355 +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 14367148294922964480859022125800977897474 +# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e +# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb +# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=T\xdcRKTRUST Elektronik Sertifika Hizmet Sa\u011flay\u0131c\u0131s\u0131 H5 O=T\xdcRKTRUST Bilgi \u0130leti\u015fim ve Bili\u015fim G\xfcvenli\u011fi Hizmetleri A.\u015e. +# Subject: CN=T\xdcRKTRUST Elektronik Sertifika Hizmet Sa\u011flay\u0131c\u0131s\u0131 H5 O=T\xdcRKTRUST Bilgi \u0130leti\u015fim ve Bili\u015fim G\xfcvenli\u011fi Hizmetleri A.\u015e. +# Label: "T\xdcRKTRUST Elektronik Sertifika Hizmet Sa\u011flay\u0131c\u0131s\u0131 H5" +# Serial: 156233699172481 +# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e +# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb +# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78 +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE +BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn +aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg +QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg +SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0 +MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD +VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom +/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR +Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3 +4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z +5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0 +hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID +AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX +SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l +VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf +peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF +Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW ++qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Root CA" +# Serial: 1 +# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f +# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 +# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G1 O=Certplus +# Subject: CN=Certplus Root CA G1 O=Certplus +# Label: "Certplus Root CA G1" +# Serial: 1491911565779898356709731176965615564637713 +# MD5 Fingerprint: 7f:09:9c:f7:d9:b9:5c:69:69:56:d5:37:3e:14:0d:42 +# SHA1 Fingerprint: 22:fd:d0:b7:fd:a2:4e:0d:ac:49:2c:a0:ac:a6:7b:6a:1f:e3:f7:66 +# SHA256 Fingerprint: 15:2a:40:2b:fc:df:2c:d5:48:05:4d:22:75:b3:9c:7f:ca:3e:c0:97:80:78:b0:f0:ea:76:e5:61:a6:c7:43:3e +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a +iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt +6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP +0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f +6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE +EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN +1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc +h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT +mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV +4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO +WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud +DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd +Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq +hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7 +/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS +S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j +2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R +Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr +RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy +6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV +V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5 +g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl +++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G2 O=Certplus +# Subject: CN=Certplus Root CA G2 O=Certplus +# Label: "Certplus Root CA G2" +# Serial: 1492087096131536844209563509228951875861589 +# MD5 Fingerprint: a7:ee:c4:78:2d:1b:ee:2d:b9:29:ce:d6:a7:96:32:31 +# SHA1 Fingerprint: 4f:65:8e:1f:e9:06:d8:28:02:e9:54:47:41:c9:54:25:5d:69:cc:1a +# SHA256 Fingerprint: 6c:c0:50:41:e6:44:5e:74:69:6c:4c:fb:c9:f8:0f:54:3b:7e:ab:bb:44:b4:ce:6f:78:7c:6a:99:71:c4:2f:17 +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat +93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x +Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj +FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG +SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch +p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal +U5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G1 O=OpenTrust +# Subject: CN=OpenTrust Root CA G1 O=OpenTrust +# Label: "OpenTrust Root CA G1" +# Serial: 1492036577811947013770400127034825178844775 +# MD5 Fingerprint: 76:00:cc:81:29:cd:55:5e:88:6a:7a:2e:f7:4d:39:da +# SHA1 Fingerprint: 79:91:e8:34:f7:e2:ee:dd:08:95:01:52:e9:55:2d:14:e9:58:d5:7e +# SHA256 Fingerprint: 56:c7:71:28:d9:8c:18:d9:1b:4c:fd:ff:bc:25:ee:91:03:d4:75:8e:a2:ab:ad:82:6a:90:f3:45:7d:46:0e:b4 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b +wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX +/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0 +77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP +uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx +p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx +Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2 +TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W +G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw +vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY +EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1 +2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw +DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf +gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS +FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0 +V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P +XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I +i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t +TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91 +09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky +Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ +AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj +1oxx +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G2 O=OpenTrust +# Subject: CN=OpenTrust Root CA G2 O=OpenTrust +# Label: "OpenTrust Root CA G2" +# Serial: 1492012448042702096986875987676935573415441 +# MD5 Fingerprint: 57:24:b6:59:24:6b:ae:c8:fe:1c:0c:20:f2:c0:4e:eb +# SHA1 Fingerprint: 79:5f:88:60:c5:ab:7c:3d:92:e6:cb:f4:8d:e1:45:cd:11:ef:60:0b +# SHA256 Fingerprint: 27:99:58:29:fe:6a:75:15:c1:bf:e8:48:f9:c4:76:1d:b1:6c:22:59:29:25:7b:f4:0d:08:94:f2:9e:a8:ba:f2 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh +/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e +CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6 +1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE +FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS +gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X +G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy +YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH +vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4 +t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/ +gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3 +5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w +DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0 +nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT +RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT +wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2 +t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa +TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2 +o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU +3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA +iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f +WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM +S1IK +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G3 O=OpenTrust +# Subject: CN=OpenTrust Root CA G3 O=OpenTrust +# Label: "OpenTrust Root CA G3" +# Serial: 1492104908271485653071219941864171170455615 +# MD5 Fingerprint: 21:37:b4:17:16:92:7b:67:46:70:a9:96:d7:a8:13:24 +# SHA1 Fingerprint: 6e:26:64:f3:56:bf:34:55:bf:d1:93:3f:7c:01:de:d8:13:da:8a:a6 +# SHA256 Fingerprint: b7:c3:62:31:70:6e:81:07:8c:36:7c:b8:96:19:8f:1e:32:08:dd:92:69:49:dd:8f:57:09:a4:10:f7:5b:62:92 +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx +CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U +cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow +QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl +blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm +3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d +oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5 +DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK +BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q +j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx +4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Label: "LuxTrust Global Root 2" +# Serial: 59914338225734147123941058376788110305822489521 +# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c +# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f +# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 +-----BEGIN CERTIFICATE----- +MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQEL +BQAwRjELMAkGA1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNV +BAMMFkx1eFRydXN0IEdsb2JhbCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUw +MzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEWMBQGA1UECgwNTHV4VHJ1c3QgUy5B +LjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wmKb3F +ibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTem +hfY7RBi2xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1 +EMShduxq3sVs35a0VkBCwGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsn +Xpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4 +zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkmFRseTJIpgp7VkoGSQXAZ +96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niFwpN6cj5m +j5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4g +DEa/a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+ +8kPREd8vZS9kzl8UubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2j +X5t/Lax5Gw5CMZdjpPuKadUiDTSQMC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmH +hFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB/zBCBgNVHSAEOzA5MDcGByuB +KwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5Lmx1eHRydXN0 +Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT ++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQEL +BQADggIBAGoZFO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9 +BzZAcg4atmpZ1gDlaCDdLnINH2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTO +jFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW7MM3LGVYvlcAGvI1+ut7MV3CwRI9 +loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIuZY+kt9J/Z93I055c +qqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWAVWe+ +2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/ +JEAdemrRTxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKre +zrnK+T+Tb/mjuuqlPpmt/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQf +LSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+ +x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31IiyBMz2TWuJdGsE7RKlY6 +oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-1" +# Serial: 15752444095811006489 +# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 +# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a +# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-2" +# Serial: 2711694510199101698 +# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 +# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 +# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor ECA-1" +# Serial: 9548242946988625984 +# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c +# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd +# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/core.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/core.py new file mode 100644 index 0000000..eab9d1d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/certifi/core.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem. +""" +import os +import warnings + + +class DeprecatedBundleWarning(DeprecationWarning): + """ + The weak security bundle is being deprecated. Please bother your service + provider to get them to stop using cross-signed roots. + """ + + +def where(): + f = os.path.dirname(__file__) + + return os.path.join(f, 'cacert.pem') + + +def old_where(): + warnings.warn( + "The weak security bundle has been removed. certifi.old_where() is now an alias " + "of certifi.where(). Please update your code to use certifi.where() instead. " + "certifi.old_where() will be removed in 2018.", + DeprecatedBundleWarning + ) + return where() + +if __name__ == '__main__': + print(where()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__init__.py new file mode 100644 index 0000000..0f9f820 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__init__.py @@ -0,0 +1,39 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .compat import PY2, PY3 +from .universaldetector import UniversalDetector +from .version import __version__, VERSION + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{0}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..2affebb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc new file mode 100644 index 0000000..2634a61 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc new file mode 100644 index 0000000..a66d18a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc new file mode 100644 index 0000000..ae55e5f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc new file mode 100644 index 0000000..7f46917 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc new file mode 100644 index 0000000..50fda7a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc new file mode 100644 index 0000000..78dd4b4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000..fae42e6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc new file mode 100644 index 0000000..f4b28be Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc new file mode 100644 index 0000000..50936d7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc new file mode 100644 index 0000000..8b8e490 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc new file mode 100644 index 0000000..65669ab Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc new file mode 100644 index 0000000..d104dc4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc new file mode 100644 index 0000000..cfb0d41 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc new file mode 100644 index 0000000..8b8bb87 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc new file mode 100644 index 0000000..3e442bc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc new file mode 100644 index 0000000..69343be Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc new file mode 100644 index 0000000..dd682ef Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc new file mode 100644 index 0000000..c64f86a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc new file mode 100644 index 0000000..f500482 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc new file mode 100644 index 0000000..f18821d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc new file mode 100644 index 0000000..6f1df47 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc new file mode 100644 index 0000000..44c06f4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc new file mode 100644 index 0000000..c16b9aa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc new file mode 100644 index 0000000..3aab42c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc new file mode 100644 index 0000000..91233e1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc new file mode 100644 index 0000000..87c1ea9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc new file mode 100644 index 0000000..9574314 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc new file mode 100644 index 0000000..893017d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc new file mode 100644 index 0000000..180393d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc new file mode 100644 index 0000000..10704ab Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc new file mode 100644 index 0000000..4e1486c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc new file mode 100644 index 0000000..7240682 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc new file mode 100644 index 0000000..1a6f2b3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc new file mode 100644 index 0000000..7b97b33 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc new file mode 100644 index 0000000..d2678e2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc new file mode 100644 index 0000000..58b2817 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000..c68e84d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5freq.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5freq.py new file mode 100644 index 0000000..38f3251 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# <http://www.edu.tw:81/mandr/> +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5prober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5prober.py new file mode 100644 index 0000000..98f9970 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/chardistribution.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/chardistribution.py new file mode 100644 index 0000000..c0395f4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py new file mode 100644 index 0000000..8b3738e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetgroupprober.py @@ -0,0 +1,106 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetprober.py new file mode 100644 index 0000000..eac4e59 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py new file mode 100644 index 0000000..c61136b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cli/chardetect.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from pip._vendor.chardet import __version__ +from pip._vendor.chardet.compat import PY2 +from pip._vendor.chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{0}: {1} with confidence {2}'.format(name, result['encoding'], + result['confidence']) + else: + return '{0}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {0}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py new file mode 100644 index 0000000..68fba44 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/compat.py new file mode 100644 index 0000000..ddd7468 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/compat.py @@ -0,0 +1,34 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + base_str = (str, unicode) + text_type = unicode +else: + PY2 = False + PY3 = True + base_str = (bytes, str) + text_type = str diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cp949prober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cp949prober.py new file mode 100644 index 0000000..efd793a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/enums.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/enums.py new file mode 100644 index 0000000..0451207 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escprober.py new file mode 100644 index 0000000..c70493f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escsm.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escsm.py new file mode 100644 index 0000000..0069523 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/eucjpprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/eucjpprober.py new file mode 100644 index 0000000..20ce8f7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrfreq.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrfreq.py new file mode 100644 index 0000000..b68078c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrprober.py new file mode 100644 index 0000000..345a060 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwfreq.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwfreq.py new file mode 100644 index 0000000..ed7a995 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# <http:#www.edu.tw:81/mandr/> + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwprober.py new file mode 100644 index 0000000..35669cc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312freq.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312freq.py new file mode 100644 index 0000000..697837b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312prober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312prober.py new file mode 100644 index 0000000..8446d2d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/hebrewprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/hebrewprober.py new file mode 100644 index 0000000..b0e1bf4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jisfreq.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jisfreq.py new file mode 100644 index 0000000..83fc082 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jpcntx.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jpcntx.py new file mode 100644 index 0000000..20044e4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py new file mode 100644 index 0000000..2aa4fb2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langbulgarianmodel.py @@ -0,0 +1,228 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +# this table is modified base on win1251BulgarianCharToOrderMap, so +# only number <64 is sure valid + +Latin5_BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, # 80 +210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, # 90 + 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, # a0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # b0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, # c0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # d0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, # e0 + 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, # f0 +) + +win1251BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, # 80 +221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, # 90 + 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, # a0 + 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, # b0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # c0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, # d0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # e0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 96.9392% +# first 1024 sequences:3.0618% +# rest sequences: 0.2992% +# negative sequences: 0.0020% +BulgarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, +3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, +0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, +0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, +0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, +0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, +0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, +2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, +3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, +1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, +3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, +1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, +2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, +2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, +3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, +1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, +2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, +2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, +1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, +2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, +2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, +2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, +1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, +2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, +1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, +3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, +1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, +3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, +1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, +2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, +1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, +2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, +1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, +2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, +1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, +2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, +1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, +0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, +1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, +1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, +1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, +0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, +1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, +1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +) + +Latin5BulgarianModel = { + 'char_to_order_map': Latin5_BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Bulgairan', +} + +Win1251BulgarianModel = { + 'char_to_order_map': win1251BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Bulgarian', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py new file mode 100644 index 0000000..e5f9a1f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langcyrillicmodel.py @@ -0,0 +1,333 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# KOI8-R language model +# Character Mapping Table: +KOI8R_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, # 80 +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, # 90 +223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, # a0 +238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, # b0 + 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, # c0 + 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, # d0 + 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, # e0 + 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, # f0 +) + +win1251_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +) + +latin5_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +macCyrillic_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, +) + +IBM855_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, +206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, + 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, +220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, +230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, + 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, + 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, +250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, +) + +IBM866_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 97.6601% +# first 1024 sequences: 2.3389% +# rest sequences: 0.1237% +# negative sequences: 0.0009% +RussianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, +1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, +1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, +2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, +1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, +3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, +1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, +2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, +1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, +1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, +1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, +1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, +3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, +1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, +2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, +1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, +2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, +1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, +1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, +1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, +3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, +3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, +1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, +1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, +0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, +1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, +1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, +0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, +1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, +2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, +1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, +1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, +2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, +1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, +1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, +1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, +0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, +0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, +0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, +2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, +0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +) + +Koi8rModel = { + 'char_to_order_map': KOI8R_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "KOI8-R", + 'language': 'Russian', +} + +Win1251CyrillicModel = { + 'char_to_order_map': win1251_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Russian', +} + +Latin5CyrillicModel = { + 'char_to_order_map': latin5_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Russian', +} + +MacCyrillicModel = { + 'char_to_order_map': macCyrillic_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "MacCyrillic", + 'language': 'Russian', +} + +Ibm866Model = { + 'char_to_order_map': IBM866_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM866", + 'language': 'Russian', +} + +Ibm855Model = { + 'char_to_order_map': IBM855_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM855", + 'language': 'Russian', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py new file mode 100644 index 0000000..5332221 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langgreekmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin7_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +win1253_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.2851% +# first 1024 sequences:1.7001% +# rest sequences: 0.0359% +# negative sequences: 0.0148% +GreekLangModel = ( +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, +2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, +2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, +2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, +0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, +3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, +2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, +0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, +0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, +0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, +0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, +0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, +0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, +0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, +0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, +0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, +0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, +0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, +0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, +0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, +0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, +0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, +0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, +0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, +0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin7GreekModel = { + 'char_to_order_map': Latin7_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-7", + 'language': 'Greek', +} + +Win1253GreekModel = { + 'char_to_order_map': win1253_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "windows-1253", + 'language': 'Greek', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py new file mode 100644 index 0000000..58f4c87 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhebrewmodel.py @@ -0,0 +1,200 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Simon Montagu +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Shoshannah Forbes - original C code (?) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Windows-1255 language model +# Character Mapping Table: +WIN1255_CHAR_TO_ORDER_MAP = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, # 40 + 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, # 50 +253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, # 60 + 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, # 70 +124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, +215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, + 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, +106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, + 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, +238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, + 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, + 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.4004% +# first 1024 sequences: 1.5981% +# rest sequences: 0.087% +# negative sequences: 0.0015% +HEBREW_LANG_MODEL = ( +0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, +3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, +1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, +1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, +1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, +1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, +0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, +0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, +0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, +0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, +0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, +0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, +0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, +0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, +0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, +0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, +0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, +0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, +0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, +1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, +1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, +2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, +0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, +0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, +) + +Win1255HebrewModel = { + 'char_to_order_map': WIN1255_CHAR_TO_ORDER_MAP, + 'precedence_matrix': HEBREW_LANG_MODEL, + 'typical_positive_ratio': 0.984004, + 'keep_english_letter': False, + 'charset_name': "windows-1255", + 'language': 'Hebrew', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py new file mode 100644 index 0000000..bb7c095 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langhungarianmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin2_HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, +175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, + 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, + 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, +245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +win1250HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, + 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, + 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, +245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 94.7368% +# first 1024 sequences:5.2623% +# rest sequences: 0.8894% +# negative sequences: 0.0009% +HungarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, +3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, +0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, +1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, +1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, +3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, +2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, +2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, +2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, +2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, +1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, +1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, +3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, +1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, +1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, +2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, +2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, +2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, +3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, +1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, +1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, +1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, +2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, +1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, +2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, +2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, +1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, +1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, +0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, +2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, +2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, +1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, +1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, +2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, +2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, +2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, +1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, +0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +) + +Latin2HungarianModel = { + 'char_to_order_map': Latin2_HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-2", + 'language': 'Hungarian', +} + +Win1250HungarianModel = { + 'char_to_order_map': win1250HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "windows-1250", + 'language': 'Hungarian', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langthaimodel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langthaimodel.py new file mode 100644 index 0000000..15f94c2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langthaimodel.py @@ -0,0 +1,199 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# The following result for thai was collected from a limited sample (1M). + +# Character Mapping Table: +TIS620CharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, # 40 +188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, # 50 +253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, # 60 + 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, # 70 +209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, +223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, +236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, + 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, + 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, + 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, + 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, + 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 92.6386% +# first 1024 sequences:7.3177% +# rest sequences: 1.0230% +# negative sequences: 0.0436% +ThaiLangModel = ( +0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, +0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, +3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, +0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, +3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, +3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, +3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, +3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, +2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, +3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, +1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, +3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, +1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, +0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, +0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, +2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, +0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, +3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, +2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, +2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, +3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, +3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, +3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, +3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, +1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, +0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, +0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, +3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, +3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, +1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, +3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, +3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, +0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, +0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, +1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, +1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, +3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, +0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, +3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, +0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, +0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, +0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, +0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, +0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, +0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, +0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, +0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, +3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, +2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, +0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, +3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, +1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, +1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +TIS620ThaiModel = { + 'char_to_order_map': TIS620CharToOrderMap, + 'precedence_matrix': ThaiLangModel, + 'typical_positive_ratio': 0.926386, + 'keep_english_letter': False, + 'charset_name': "TIS-620", + 'language': 'Thai', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py new file mode 100644 index 0000000..a427a45 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/langturkishmodel.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Özgür Baskın - Turkish Language Model +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin5_TurkishCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255, 23, 37, 47, 39, 29, 52, 36, 45, 53, 60, 16, 49, 20, 46, 42, + 48, 69, 44, 35, 31, 51, 38, 62, 65, 43, 56,255,255,255,255,255, +255, 1, 21, 28, 12, 2, 18, 27, 25, 3, 24, 10, 5, 13, 4, 15, + 26, 64, 7, 8, 9, 14, 32, 57, 58, 11, 22,255,255,255,255,255, +180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165, +164,163,162,161,160,159,101,158,157,156,155,154,153,152,151,106, +150,149,148,147,146,145,144,100,143,142,141,140,139,138,137,136, + 94, 80, 93,135,105,134,133, 63,132,131,130,129,128,127,126,125, +124,104, 73, 99, 79, 85,123, 54,122, 98, 92,121,120, 91,103,119, + 68,118,117, 97,116,115, 50, 90,114,113,112,111, 55, 41, 40, 86, + 89, 70, 59, 78, 71, 82, 88, 33, 77, 66, 84, 83,110, 75, 61, 96, + 30, 67,109, 74, 87,102, 34, 95, 81,108, 76, 72, 17, 6, 19,107, +) + +TurkishLangModel = ( +3,2,3,3,3,1,3,3,3,3,3,3,3,3,2,1,1,3,3,1,3,3,0,3,3,3,3,3,0,3,1,3, +3,2,1,0,0,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,3,1,0,3,3,1,3,3,0,3,3,3,3,3,0,3,0,3, +3,1,1,0,1,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,0,1,0,1, +3,3,2,3,3,0,3,3,3,3,3,3,3,2,3,1,1,3,3,0,3,3,1,2,3,3,3,3,0,3,0,3, +3,1,1,0,0,0,1,0,0,0,0,1,1,0,1,2,1,0,0,0,1,0,0,0,0,2,0,0,0,0,0,1, +3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,1,3,3,2,0,3,2,1,2,2,1,3,3,0,0,0,2, +2,2,0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1, +3,3,3,2,3,3,1,2,3,3,3,3,3,3,3,1,3,2,1,0,3,2,0,1,2,3,3,2,1,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0, +1,0,1,3,3,1,3,3,3,3,3,3,3,1,2,0,0,2,3,0,2,3,0,0,2,2,2,3,0,3,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,0,3,2,0,2,3,2,3,3,1,0,0,2, +3,2,0,0,1,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,1, +3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,0,3,3,0,0,2,1,0,0,2,3,2,2,0,0,0,2, +2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,0,2,0,0,1, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,0,1,3,2,1,1,3,2,3,2,1,0,0,2, +2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,2,0,2,3,0,0,2,2,2,2,0,0,0,2, +3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,0,3,3,1,1,2,2,0,0,2,2,3,2,0,0,1,3, +0,3,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1, +3,3,3,2,3,3,3,2,1,2,2,3,2,3,3,0,3,2,0,0,1,1,0,1,1,2,1,2,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0, +3,3,3,2,3,3,2,3,2,2,2,3,3,3,3,1,3,1,1,0,3,2,1,1,3,3,2,3,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,2,1,0,3,3,1,3,3,0,1,3,3,2,3,0,3,0,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +2,2,2,3,3,0,3,3,3,3,3,3,3,3,3,0,0,3,2,0,3,3,0,3,2,3,3,3,0,3,1,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,1,2,0,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,3,3,1,2,3,3,1,0,0,1,0,0,3,3,2,3,0,0,2,0,0,2,0,2,0,0,0,2,0,2,0, +0,3,1,0,1,0,0,0,2,2,1,0,1,1,2,1,2,2,2,0,2,1,1,0,0,0,2,0,0,0,0,0, +1,2,1,3,3,0,3,3,3,3,3,2,3,0,0,0,0,2,3,0,2,3,1,0,2,3,1,3,0,3,0,2, +3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,3,2,2,3,2,2,0,1,2,3,0,1,2,1,0,1,0,0,0,1,0,2,2,0,0,0,1, +1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0, +3,3,3,1,3,3,1,1,3,3,1,1,3,3,1,0,2,1,2,0,2,1,0,0,1,1,2,1,0,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,0,2,1,3,0,0,2,0,0,3,3,0,3,0,0,1,0,1,2,0,0,1,1,2,2,0,1,0, +0,1,2,1,1,0,1,0,1,1,1,1,1,0,1,1,1,2,2,1,2,0,1,0,0,0,0,0,0,1,0,0, +3,3,3,2,3,2,3,3,0,2,2,2,3,3,3,0,3,0,0,0,2,2,0,1,2,1,1,1,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +3,3,3,3,3,3,2,1,2,2,3,3,3,3,2,0,2,0,0,0,2,2,0,0,2,1,3,3,0,0,1,1, +1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0, +1,1,2,3,3,0,3,3,3,3,3,3,2,2,0,2,0,2,3,2,3,2,2,2,2,2,2,2,1,3,2,3, +2,0,2,1,2,2,2,2,1,1,2,2,1,2,2,1,2,0,0,2,1,1,0,2,1,0,0,1,0,0,0,1, +2,3,3,1,1,1,0,1,1,1,2,3,2,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,2,2,1,3,3,3,0,2,1,2,0,2,1,0,0,1,1,1,1,1,0,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,2,3,3,3,3,3,2,3,1,2,3,3,1,2,0,0,0,0,0,0,0,3,2,1,1,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +3,3,3,2,2,3,3,2,1,1,1,1,1,3,3,0,3,1,0,0,1,1,0,0,3,1,2,1,0,0,0,0, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, +3,3,3,2,2,3,2,2,2,3,2,1,1,3,3,0,3,0,0,0,0,1,0,0,3,1,1,2,0,0,0,1, +1,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,3,3,0,3,3,3,3,3,2,2,2,1,2,0,2,1,2,2,1,1,0,1,2,2,2,2,2,2,2, +0,0,2,1,2,1,2,1,0,1,1,3,1,2,1,1,2,0,0,2,0,1,0,1,0,1,0,0,0,1,0,1, +3,3,3,1,3,3,3,0,1,1,0,2,2,3,1,0,3,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,2,2,1,0,0,1,0,0,3,3,1,3,0,0,1,1,0,2,0,3,0,0,0,2,0,1,1, +0,1,2,0,1,2,2,0,2,2,2,2,1,0,2,1,1,0,2,0,2,1,2,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,2,3,2,0,2,2,2,1,3,2,0,2,1,2,0,1,2,0,0,1,0,2,2,0,0,0,2, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0, +3,3,3,0,3,3,1,1,2,3,1,0,3,2,3,0,3,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0, +1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,3,3,2,3,3,2,2,0,0,0,0,1,2,0,1,3,0,0,0,3,1,1,0,3,0,2, +2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,2,2,1,0,3,1,1,1,1,3,3,2,3,0,0,1,0,1,2,0,2,2,0,2,2,0,2,1, +0,2,2,1,1,1,1,0,2,1,1,0,1,1,1,1,2,1,2,1,2,0,1,0,1,0,0,0,0,0,0,0, +3,3,3,0,1,1,3,0,0,1,1,0,0,2,2,0,3,0,0,1,1,0,1,0,0,0,0,0,2,0,0,0, +0,3,1,0,1,0,1,0,2,0,0,1,0,1,0,1,1,1,2,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,0,2,0,1,1,1,0,0,3,3,0,2,0,0,1,0,0,2,1,1,0,1,0,1,0,1,0, +0,2,0,1,2,0,2,0,2,1,1,0,1,0,2,1,1,0,2,1,1,0,1,0,0,0,1,1,0,0,0,0, +3,2,3,0,1,0,0,0,0,0,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,0,2,0,0,0, +0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,2,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,0,2,3,0,0,1,0,1,0,2,3,2,3,0,0,1,3,0,2,1,0,0,0,0,2,0,1,0, +0,2,1,0,0,1,1,0,2,1,0,0,1,0,0,1,1,0,1,1,2,0,1,0,0,0,0,1,0,0,0,0, +3,2,2,0,0,1,1,0,0,0,0,0,0,3,1,1,1,0,0,0,0,0,1,0,0,0,0,0,2,0,1,0, +0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,2,3,2,2,1,2,2,1,1,2,0,1,3,2,2,2,0,0,2,2,0,0,0,1,2,1, +3,0,2,1,1,0,1,1,1,0,1,2,2,2,1,1,2,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0, +0,1,1,2,3,0,3,3,3,2,2,2,2,1,0,1,0,1,0,1,2,2,0,0,2,2,1,3,1,1,2,1, +0,0,1,1,2,0,1,1,0,0,1,2,0,2,1,1,2,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0, +3,3,2,0,0,3,1,0,0,0,0,0,0,3,2,1,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,2,1,1,0,0,1,0,1,2,0,0,1,1,0,0,2,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,1,0,0,0,0,1,0,0,3,3,2,2,0,0,1,0,0,2,0,1,0,0,0,2,0,1,0, +0,0,1,1,0,0,2,0,2,1,0,0,1,1,2,1,2,0,2,1,2,1,1,1,0,0,1,1,0,0,0,0, +3,3,2,0,0,2,2,0,0,0,1,1,0,2,2,1,3,1,0,1,0,1,2,0,0,0,0,0,1,0,1,0, +0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,0,0,0,1,0,0,1,0,0,2,3,1,2,0,0,1,0,0,2,0,0,0,1,0,2,0,2,0, +0,1,1,2,2,1,2,0,2,1,1,0,0,1,1,0,1,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,1,0,0,1,1,0,3,3,1,2,0,0,1,0,0,2,0,2,0,1,1,2,0,0,0, +0,0,1,1,1,1,2,0,1,1,0,1,1,1,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +3,3,3,0,2,2,3,2,0,0,1,0,0,2,3,1,0,0,0,0,0,0,2,0,2,0,0,0,2,0,0,0, +0,1,1,0,0,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,0,0,0,0,0,0,1,0,0,2,2,2,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,0,2,1,1,0,1,0,2,1,1,0,0,1,1,2,1,0,2,0,2,0,1,0,0,0,2,0,0,0,0,0, +0,0,0,2,2,0,2,1,1,1,1,2,2,0,0,1,0,1,0,0,1,3,0,0,0,0,1,0,0,2,1,0, +0,0,1,0,1,0,0,0,0,0,2,1,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +2,0,0,2,3,0,2,3,1,2,2,0,2,0,0,2,0,2,1,1,1,2,1,0,0,1,2,1,1,2,1,0, +1,0,2,0,1,0,1,1,0,0,2,2,1,2,1,1,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,0,0,0,1,0,0,3,2,0,1,0,0,1,0,0,2,0,0,0,1,2,1,0,1,0, +0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,2,2,0,2,2,1,1,0,1,1,1,1,1,0,0,1,2,1,1,1,0,1,0,0,0,1,1,1,1, +0,0,2,1,0,1,1,1,0,1,1,2,1,2,1,1,2,0,1,1,2,1,0,2,0,0,0,0,0,0,0,0, +3,2,2,0,0,2,0,0,0,0,0,0,0,2,2,0,2,0,0,1,0,0,2,0,0,0,0,0,2,0,0,0, +0,2,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,0,2,2,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0, +2,0,1,0,1,0,1,1,0,0,1,2,0,1,0,1,1,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0, +2,2,2,0,1,1,0,0,0,1,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,1,2,0,1,0, +0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,1,1,1,0,0,0,0,1,2,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +1,1,2,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1, +0,0,1,2,2,0,2,1,2,1,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,2,2,0,0,0,1,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin5TurkishModel = { + 'char_to_order_map': Latin5_TurkishCharToOrderMap, + 'precedence_matrix': TurkishLangModel, + 'typical_positive_ratio': 0.970290, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-9", + 'language': 'Turkish', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/latin1prober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/latin1prober.py new file mode 100644 index 0000000..7d1e8c2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py new file mode 100644 index 0000000..6256ecf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py new file mode 100644 index 0000000..530abe7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcssm.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcssm.py new file mode 100644 index 0000000..8360d0f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py new file mode 100644 index 0000000..0adb51d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcharsetprober.py @@ -0,0 +1,132 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import CharacterCategory, ProbingState, SequenceLikelihood + + +class SingleByteCharSetProber(CharSetProber): + SAMPLE_SIZE = 64 + SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 + POSITIVE_SHORTCUT_THRESHOLD = 0.95 + NEGATIVE_SHORTCUT_THRESHOLD = 0.05 + + def __init__(self, model, reversed=False, name_prober=None): + super(SingleByteCharSetProber, self).__init__() + self._model = model + # TRUE if we need to reverse every pair in the model lookup + self._reversed = reversed + # Optional auxiliary prober for name decision + self._name_prober = name_prober + self._last_order = None + self._seq_counters = None + self._total_seqs = None + self._total_char = None + self._freq_char = None + self.reset() + + def reset(self): + super(SingleByteCharSetProber, self).reset() + # char order of last character + self._last_order = 255 + self._seq_counters = [0] * SequenceLikelihood.get_num_categories() + self._total_seqs = 0 + self._total_char = 0 + # characters that fall in our sampling range + self._freq_char = 0 + + @property + def charset_name(self): + if self._name_prober: + return self._name_prober.charset_name + else: + return self._model['charset_name'] + + @property + def language(self): + if self._name_prober: + return self._name_prober.language + else: + return self._model.get('language') + + def feed(self, byte_str): + if not self._model['keep_english_letter']: + byte_str = self.filter_international_words(byte_str) + if not byte_str: + return self.state + char_to_order_map = self._model['char_to_order_map'] + for i, c in enumerate(byte_str): + # XXX: Order is in range 1-64, so one would think we want 0-63 here, + # but that leads to 27 more test failures than before. + order = char_to_order_map[c] + # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but + # CharacterCategory.SYMBOL is actually 253, so we use CONTROL + # to make it closer to the original intent. The only difference + # is whether or not we count digits and control characters for + # _total_char purposes. + if order < CharacterCategory.CONTROL: + self._total_char += 1 + if order < self.SAMPLE_SIZE: + self._freq_char += 1 + if self._last_order < self.SAMPLE_SIZE: + self._total_seqs += 1 + if not self._reversed: + i = (self._last_order * self.SAMPLE_SIZE) + order + model = self._model['precedence_matrix'][i] + else: # reverse the order of the letters in the lookup + i = (order * self.SAMPLE_SIZE) + self._last_order + model = self._model['precedence_matrix'][i] + self._seq_counters[model] += 1 + self._last_order = order + + charset_name = self._model['charset_name'] + if self.state == ProbingState.DETECTING: + if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model['typical_positive_ratio']) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py new file mode 100644 index 0000000..98e95dc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sbcsgroupprober.py @@ -0,0 +1,73 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .sbcharsetprober import SingleByteCharSetProber +from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel, + Latin5CyrillicModel, MacCyrillicModel, + Ibm866Model, Ibm855Model) +from .langgreekmodel import Latin7GreekModel, Win1253GreekModel +from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel +# from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel +from .langthaimodel import TIS620ThaiModel +from .langhebrewmodel import Win1255HebrewModel +from .hebrewprober import HebrewProber +from .langturkishmodel import Latin5TurkishModel + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + self.probers = [ + SingleByteCharSetProber(Win1251CyrillicModel), + SingleByteCharSetProber(Koi8rModel), + SingleByteCharSetProber(Latin5CyrillicModel), + SingleByteCharSetProber(MacCyrillicModel), + SingleByteCharSetProber(Ibm866Model), + SingleByteCharSetProber(Ibm855Model), + SingleByteCharSetProber(Latin7GreekModel), + SingleByteCharSetProber(Win1253GreekModel), + SingleByteCharSetProber(Latin5BulgarianModel), + SingleByteCharSetProber(Win1251BulgarianModel), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(Latin2HungarianModel), + # SingleByteCharSetProber(Win1250HungarianModel), + SingleByteCharSetProber(TIS620ThaiModel), + SingleByteCharSetProber(Latin5TurkishModel), + ] + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, + False, hebrew_prober) + visual_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, True, + hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, visual_hebrew_prober) + self.probers.extend([hebrew_prober, logical_hebrew_prober, + visual_hebrew_prober]) + + self.reset() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sjisprober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sjisprober.py new file mode 100644 index 0000000..9e29623 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/universaldetector.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/universaldetector.py new file mode 100644 index 0000000..7b4e92d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() == logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + return self.result diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/utf8prober.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/utf8prober.py new file mode 100644 index 0000000..6c3196c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/version.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/version.py new file mode 100644 index 0000000..bb2a34a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "3.0.4" +VERSION = __version__.split('.') diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__init__.py new file mode 100644 index 0000000..f4d9ce2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__init__.py @@ -0,0 +1,7 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.3.9' + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..456a1ae Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc new file mode 100644 index 0000000..a0be8f4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc new file mode 100644 index 0000000..3031586 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc new file mode 100644 index 0000000..49b4cac Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc new file mode 100644 index 0000000..f6b22b3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc new file mode 100644 index 0000000..8466328 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansi.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansi.py new file mode 100644 index 0000000..7877658 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansitowin32.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansitowin32.py new file mode 100644 index 0000000..1d6e605 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/ansitowin32.py @@ -0,0 +1,236 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +def is_stream_closed(stream): + return not hasattr(stream, 'closed') or stream.closed + + +def is_a_tty(stream): + return hasattr(stream, 'isatty') and stream.isatty() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + self.__convertor.write(text) + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not is_stream_closed(self.wrapped): + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/initialise.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/initialise.py new file mode 100644 index 0000000..834962a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/initialise.py @@ -0,0 +1,82 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream + + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/win32.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/win32.py new file mode 100644 index 0000000..8262e35 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/win32.py @@ -0,0 +1,156 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + handles = { + STDOUT: _GetStdHandle(STDOUT), + STDERR: _GetStdHandle(STDERR), + } + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in handles.values()) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = handles[stream_id] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = handles[stream_id] + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = handles[stream_id] + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = handles[stream_id] + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = handles[stream_id] + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/winterm.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/winterm.py new file mode 100644 index 0000000..60309d3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/colorama/winterm.py @@ -0,0 +1,162 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + if mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + if mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__init__.py new file mode 100644 index 0000000..d4aab45 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import logging + +__version__ = '0.2.7' + +class DistlibException(Exception): + pass + +try: + from logging import NullHandler +except ImportError: # pragma: no cover + class NullHandler(logging.Handler): + def handle(self, record): pass + def emit(self, record): pass + def createLock(self): self.lock = None + +logger = logging.getLogger(__name__) +logger.addHandler(NullHandler()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..d362970 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000..456d2d3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc new file mode 100644 index 0000000..814fdae Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc new file mode 100644 index 0000000..223e551 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000..4c9c0be Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py new file mode 100644 index 0000000..f7dbf4c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/__init__.py @@ -0,0 +1,6 @@ +"""Modules copied from Python 3 standard libraries, for internal use only. + +Individual classes and functions are found in d2._backport.misc. Intended +usage is to always import things missing from 3.1 from that module: the +built-in/stdlib objects will be used if found. +""" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/misc.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/misc.py new file mode 100644 index 0000000..cfb318d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/misc.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Backports for individual classes and functions.""" + +import os +import sys + +__all__ = ['cache_from_source', 'callable', 'fsencode'] + + +try: + from imp import cache_from_source +except ImportError: + def cache_from_source(py_file, debug=__debug__): + ext = debug and 'c' or 'o' + return py_file + ext + + +try: + callable = callable +except NameError: + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode +except AttributeError: + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, str): + return filename.encode(sys.getfilesystemencoding()) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py new file mode 100644 index 0000000..159e49e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/shutil.py @@ -0,0 +1,761 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Utility functions for copying and archiving files and directory trees. + +XXX The functions here don't copy the resource fork or other metadata on Mac. + +""" + +import os +import sys +import stat +from os.path import abspath +import fnmatch +import collections +import errno +from . import tarfile + +try: + import bz2 + _BZ2_SUPPORTED = True +except ImportError: + _BZ2_SUPPORTED = False + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", + "copytree", "move", "rmtree", "Error", "SpecialFileError", + "ExecError", "make_archive", "get_archive_formats", + "register_archive_format", "unregister_archive_format", + "get_unpack_formats", "register_unpack_format", + "unregister_unpack_format", "unpack_archive", "ignore_patterns"] + +class Error(EnvironmentError): + pass + +class SpecialFileError(EnvironmentError): + """Raised when trying to do a kind of operation (e.g. copying) which is + not supported on a special file (e.g. a named pipe)""" + +class ExecError(EnvironmentError): + """Raised when a command could not be executed""" + +class ReadError(EnvironmentError): + """Raised when an archive cannot be read""" + +class RegistryError(Exception): + """Raised when a registry operation with the archiving + and unpacking registries fails""" + + +try: + WindowsError +except NameError: + WindowsError = None + +def copyfileobj(fsrc, fdst, length=16*1024): + """copy data from file-like object fsrc to file-like object fdst""" + while 1: + buf = fsrc.read(length) + if not buf: + break + fdst.write(buf) + +def _samefile(src, dst): + # Macintosh, Unix. + if hasattr(os.path, 'samefile'): + try: + return os.path.samefile(src, dst) + except OSError: + return False + + # All other platforms: check for same pathname. + return (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + +def copyfile(src, dst): + """Copy data from src to dst""" + if _samefile(src, dst): + raise Error("`%s` and `%s` are the same file" % (src, dst)) + + for fn in [src, dst]: + try: + st = os.stat(fn) + except OSError: + # File most likely does not exist + pass + else: + # XXX What about other special files? (sockets, devices...) + if stat.S_ISFIFO(st.st_mode): + raise SpecialFileError("`%s` is a named pipe" % fn) + + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + +def copymode(src, dst): + """Copy mode bits from src to dst""" + if hasattr(os, 'chmod'): + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + os.chmod(dst, mode) + +def copystat(src, dst): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + if hasattr(os, 'utime'): + os.utime(dst, (st.st_atime, st.st_mtime)) + if hasattr(os, 'chmod'): + os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + try: + os.chflags(dst, st.st_flags) + except OSError as why: + if (not hasattr(errno, 'EOPNOTSUPP') or + why.errno != errno.EOPNOTSUPP): + raise + +def copy(src, dst): + """Copy data and mode bits ("cp src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copymode(src, dst) + +def copy2(src, dst): + """Copy data and all stat info ("cp -p src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copystat(src, dst) + +def ignore_patterns(*patterns): + """Function that can be used as copytree() ignore parameter. + + Patterns is a sequence of glob-style patterns + that are used to exclude files""" + def _ignore_patterns(path, names): + ignored_names = [] + for pattern in patterns: + ignored_names.extend(fnmatch.filter(names, pattern)) + return set(ignored_names) + return _ignore_patterns + +def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks=False): + """Recursively copy a directory tree. + + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. If the file pointed by the symlink doesn't + exist, an exception will be added in the list of errors raised in + an Error exception at the end of the copy process. + + You can set the optional ignore_dangling_symlinks flag to true if you + want to silence this exception. Notice that this has no effect on + platforms that don't support os.symlink. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + The optional copy_function argument is a callable that will be used + to copy each file. It will be called with the source path and the + destination path as arguments. By default, copy2() is used, but any + function that supports the same signature (like copy()) can be used. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.islink(srcname): + linkto = os.readlink(srcname) + if symlinks: + os.symlink(linkto, dstname) + else: + # ignore dangling symlink if the flag is on + if not os.path.exists(linkto) and ignore_dangling_symlinks: + continue + # otherwise let the copy occurs. copy2 will raise an error + copy_function(srcname, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, copy_function) + else: + # Will raise a SpecialFileError for unsupported file types + copy_function(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error(errors) + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is os.listdir, os.remove, or os.rmdir; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return + names = [] + try: + names = os.listdir(path) + except os.error: + onerror(os.listdir, path, sys.exc_info()) + for name in names: + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except os.error: + mode = 0 + if stat.S_ISDIR(mode): + rmtree(fullname, ignore_errors, onerror) + else: + try: + os.remove(fullname) + except os.error: + onerror(os.remove, fullname, sys.exc_info()) + try: + os.rmdir(path) + except os.error: + onerror(os.rmdir, path, sys.exc_info()) + + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + return os.path.basename(path.rstrip(os.path.sep)) + +def move(src, dst): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error("Destination path '%s' already exists" % real_dst) + try: + os.rename(src, real_dst) + except OSError: + if os.path.isdir(src): + if _destinsrc(src, dst): + raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) + copytree(src, real_dst, symlinks=True) + rmtree(src) + else: + copy2(src, real_dst) + os.unlink(src) + +def _destinsrc(src, dst): + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", or ".bz2"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', None: ''} + compress_ext = {'gzip': '.gz'} + + if _BZ2_SUPPORTED: + tar_compression['bzip2'] = 'bz2' + compress_ext['bzip2'] = '.bz2' + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext: + raise ValueError("bad value for 'compress', or compression format not " + "supported : {0}".format(compress)) + + archive_name = base_name + '.tar' + compress_ext.get(compress, '') + archive_dir = os.path.dirname(archive_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # creating the tarball + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): + # XXX see if we want to keep an external call here + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + from distutils.errors import DistutilsExecError + from distutils.spawn import spawn + try: + spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise ExecError("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises ExecError. Returns the name of the output zip + file. + """ + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # If zipfile module is not available, try spawning an external 'zip' + # command. + try: + import zipfile + except ImportError: + zipfile = None + + if zipfile is None: + _call_external_zip(base_dir, zip_filename, verbose, dry_run) + else: + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + zip.close() + + return zip_filename + +_ARCHIVE_FORMATS = { + 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (_make_zipfile, [], "ZIP file"), + } + +if _BZ2_SUPPORTED: + _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], + "bzip2'ed tar-file") + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not isinstance(function, collections.Callable): + raise TypeError('The %s object is not callable' % function) + if not isinstance(extra_args, (tuple, list)): + raise TypeError('extra_args needs to be a sequence') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2: + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "bztar" + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError("unknown archive format '%s'" % format) + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + + +def get_unpack_formats(): + """Returns a list of supported formats for unpacking. + + Each element of the returned sequence is a tuple + (name, extensions, description) + """ + formats = [(name, info[0], info[3]) for name, info in + _UNPACK_FORMATS.items()] + formats.sort() + return formats + +def _check_unpack_options(extensions, function, extra_args): + """Checks what gets registered as an unpacker.""" + # first make sure no other unpacker is registered for this extension + existing_extensions = {} + for name, info in _UNPACK_FORMATS.items(): + for ext in info[0]: + existing_extensions[ext] = name + + for extension in extensions: + if extension in existing_extensions: + msg = '%s is already registered for "%s"' + raise RegistryError(msg % (extension, + existing_extensions[extension])) + + if not isinstance(function, collections.Callable): + raise TypeError('The registered function must be a callable') + + +def register_unpack_format(name, extensions, function, extra_args=None, + description=''): + """Registers an unpack format. + + `name` is the name of the format. `extensions` is a list of extensions + corresponding to the format. + + `function` is the callable that will be + used to unpack archives. The callable will receive archives to unpack. + If it's unable to handle an archive, it needs to raise a ReadError + exception. + + If provided, `extra_args` is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_unpack_formats() function. + """ + if extra_args is None: + extra_args = [] + _check_unpack_options(extensions, function, extra_args) + _UNPACK_FORMATS[name] = extensions, function, extra_args, description + +def unregister_unpack_format(name): + """Removes the pack format from the registry.""" + del _UNPACK_FORMATS[name] + +def _ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + +def _unpack_zipfile(filename, extract_dir): + """Unpack zip `filename` to `extract_dir` + """ + try: + import zipfile + except ImportError: + raise ReadError('zlib not supported, cannot unpack this archive.') + + if not zipfile.is_zipfile(filename): + raise ReadError("%s is not a zip file" % filename) + + zip = zipfile.ZipFile(filename) + try: + for info in zip.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name: + continue + + target = os.path.join(extract_dir, *name.split('/')) + if not target: + continue + + _ensure_directory(target) + if not name.endswith('/'): + # file + data = zip.read(info.filename) + f = open(target, 'wb') + try: + f.write(data) + finally: + f.close() + del data + finally: + zip.close() + +def _unpack_tarfile(filename, extract_dir): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise ReadError( + "%s is not a compressed or uncompressed tar file" % filename) + try: + tarobj.extractall(extract_dir) + finally: + tarobj.close() + +_UNPACK_FORMATS = { + 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), + 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") + } + +if _BZ2_SUPPORTED: + _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + "bzip2'ed tar-file") + +def _find_unpack_format(filename): + for name, info in _UNPACK_FORMATS.items(): + for extension in info[0]: + if filename.endswith(extension): + return name + return None + +def unpack_archive(filename, extract_dir=None, format=None): + """Unpack an archive. + + `filename` is the name of the archive. + + `extract_dir` is the name of the target directory, where the archive + is unpacked. If not provided, the current working directory is used. + + `format` is the archive format: one of "zip", "tar", or "gztar". Or any + other registered format. If not provided, unpack_archive will use the + filename extension and see if an unpacker was registered for that + extension. + + In case none is found, a ValueError is raised. + """ + if extract_dir is None: + extract_dir = os.getcwd() + + if format is not None: + try: + format_info = _UNPACK_FORMATS[format] + except KeyError: + raise ValueError("Unknown unpack format '{0}'".format(format)) + + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) + else: + # we need to look at the registered unpackers supported extensions + format = _find_unpack_format(filename) + if format is None: + raise ReadError("Unknown archive format '{0}'".format(filename)) + + func = _UNPACK_FORMATS[format][1] + kwargs = dict(_UNPACK_FORMATS[format][2]) + func(filename, extract_dir, **kwargs) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg new file mode 100644 index 0000000..1746bd0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.cfg @@ -0,0 +1,84 @@ +[posix_prefix] +# Configuration directories. Some of these come straight out of the +# configure script. They are for implementing the other variables, not to +# be used directly in [resource_locations]. +confdir = /etc +datadir = /usr/share +libdir = /usr/lib +statedir = /var +# User resource directory +local = ~/.local/{distribution.name} + +stdlib = {base}/lib/python{py_version_short} +platstdlib = {platbase}/lib/python{py_version_short} +purelib = {base}/lib/python{py_version_short}/site-packages +platlib = {platbase}/lib/python{py_version_short}/site-packages +include = {base}/include/python{py_version_short}{abiflags} +platinclude = {platbase}/include/python{py_version_short}{abiflags} +data = {base} + +[posix_home] +stdlib = {base}/lib/python +platstdlib = {base}/lib/python +purelib = {base}/lib/python +platlib = {base}/lib/python +include = {base}/include/python +platinclude = {base}/include/python +scripts = {base}/bin +data = {base} + +[nt] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2_home] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[nt_user] +stdlib = {userbase}/Python{py_version_nodot} +platstdlib = {userbase}/Python{py_version_nodot} +purelib = {userbase}/Python{py_version_nodot}/site-packages +platlib = {userbase}/Python{py_version_nodot}/site-packages +include = {userbase}/Python{py_version_nodot}/Include +scripts = {userbase}/Scripts +data = {userbase} + +[posix_user] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[osx_framework_user] +stdlib = {userbase}/lib/python +platstdlib = {userbase}/lib/python +purelib = {userbase}/lib/python/site-packages +platlib = {userbase}/lib/python/site-packages +include = {userbase}/include +scripts = {userbase}/bin +data = {userbase} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py new file mode 100644 index 0000000..1df3aba --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/sysconfig.py @@ -0,0 +1,788 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Access to Python's configuration information.""" + +import codecs +import os +import re +import sys +from os.path import pardir, realpath +try: + import configparser +except ImportError: + import ConfigParser as configparser + + +__all__ = [ + 'get_config_h_filename', + 'get_config_var', + 'get_config_vars', + 'get_makefile_filename', + 'get_path', + 'get_path_names', + 'get_paths', + 'get_platform', + 'get_python_version', + 'get_scheme_names', + 'parse_config_h', +] + + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) + + +def is_python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +_cfg_read = False + +def _ensure_cfg_read(): + global _cfg_read + if not _cfg_read: + from ..resources import finder + backport_package = __name__.rsplit('.', 1)[0] + _finder = finder(backport_package) + _cfgfile = _finder.find('sysconfig.cfg') + assert _cfgfile, 'sysconfig.cfg exists' + with _cfgfile.as_stream() as s: + _SCHEMES.readfp(s) + if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + _SCHEMES.set(scheme, 'include', '{srcdir}/Include') + _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') + + _cfg_read = True + + +_SCHEMES = configparser.RawConfigParser() +_VAR_REPL = re.compile(r'\{([^{]*?)\}') + +def _expand_globals(config): + _ensure_cfg_read() + if config.has_section('globals'): + globals = config.items('globals') + else: + globals = tuple() + + sections = config.sections() + for section in sections: + if section == 'globals': + continue + for option, value in globals: + if config.has_option(section, option): + continue + config.set(section, option, value) + config.remove_section('globals') + + # now expanding local variables defined in the cfg file + # + for section in config.sections(): + variables = dict(config.items(section)) + + def _replacer(matchobj): + name = matchobj.group(1) + if name in variables: + return variables[name] + return matchobj.group(0) + + for option, value in config.items(section): + config.set(section, option, _VAR_REPL.sub(_replacer, value)) + +#_expand_globals(_SCHEMES) + + # FIXME don't rely on sys.version here, its format is an implementation detail + # of CPython, use sys.version_info or sys.hexversion +_PY_VERSION = sys.version.split()[0] +_PY_VERSION_SHORT = sys.version[:3] +_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None + + +def _subst_vars(path, local_vars): + """In the string `path`, replace tokens like {some.thing} with the + corresponding value from the map `local_vars`. + + If there is no corresponding value, leave the token unchanged. + """ + def _replacer(matchobj): + name = matchobj.group(1) + if name in local_vars: + return local_vars[name] + elif name in os.environ: + return os.environ[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, path) + + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + + for key, value in _SCHEMES.items(scheme): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + + +def format_value(value, vars): + def _replacer(matchobj): + name = matchobj.group(1) + if name in vars: + return vars[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, value) + + +def _get_default_scheme(): + if os.name == 'posix': + # the default scheme for posix is posix_prefix + return 'posix_prefix' + return os.name + + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + return env_base + else: + return joinuser(base, "Python") + + if sys.platform == "darwin": + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + if env_base: + return env_base + else: + return joinuser("~", "Library", framework, "%d.%d" % + sys.version_info[:2]) + + if env_base: + return env_base + else: + return joinuser("~", ".local") + + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if (name.startswith('PY_') and + name[3:] in renamed_variables): + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if (name.startswith('PY_') and + name[3:] in renamed_variables): + + name = name[3:] + if name not in done: + done[name] = value + + else: + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def get_makefile_filename(): + """Return the path of the Makefile.""" + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + if hasattr(sys, 'abiflags'): + config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) + else: + config_dir_name = 'config' + return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') + + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + makefile = get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % makefile + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h) as f: + parse_config_h(f, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % config_h + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: + v = int(v) + except ValueError: + pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + + +def get_config_h_filename(): + """Return the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + + +def get_scheme_names(): + """Return a tuple containing the schemes names.""" + return tuple(sorted(_SCHEMES.sections())) + + +def get_path_names(): + """Return a tuple containing the paths names.""" + # xxx see if we want a static list + return _SCHEMES.options('posix_prefix') + + +def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): + """Return a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + _ensure_cfg_read() + if expand: + return _expand_vars(scheme, vars) + else: + return dict(_SCHEMES.items(scheme)) + + +def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): + """Return a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _CONFIG_VARS + if _CONFIG_VARS is None: + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # distutils2 module. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + if sys.version >= '2.6': + _CONFIG_VARS['userbase'] = _getuserbase() + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = _PROJECT_BASE + try: + cwd = os.getcwd() + except OSError: + cwd = None + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != cwd): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _CONFIG_VARS[key] = flags + else: + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search(r'-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile(r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if True: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + try: + m = re.search(r'<key>ProductUserVisibleVersion</key>\s*' + r'<string>(.*?)</string>', f.read()) + finally: + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if ((macrelease + '.') >= '10.4.' and + '-arch' in get_config_vars().get('CFLAGS', '').strip()): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall(r'-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r" % (archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + else: + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT + + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('%s: ' % (title)) + print('\t%s = "%s"' % (key, value)) + + +def _main(): + """Display all information sysconfig detains.""" + print('Platform: "%s"' % get_platform()) + print('Python version: "%s"' % get_python_version()) + print('Current installation scheme: "%s"' % _get_default_scheme()) + print() + _print_dict('Paths', get_paths()) + print() + _print_dict('Variables', get_config_vars()) + + +if __name__ == '__main__': + _main() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py new file mode 100644 index 0000000..d66d856 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/_backport/tarfile.py @@ -0,0 +1,2607 @@ +#------------------------------------------------------------------- +# tarfile.py +#------------------------------------------------------------------- +# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de> +# All rights reserved. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +from __future__ import print_function + +"""Read from and write to tar format archives. +""" + +__version__ = "$Revision$" + +version = "0.9.0" +__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" +__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" +__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" +__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." + +#--------- +# Imports +#--------- +import sys +import os +import stat +import errno +import time +import struct +import copy +import re + +try: + import grp, pwd +except ImportError: + grp = pwd = None + +# os.symlink on Windows prior to 6.0 raises NotImplementedError +symlink_exception = (AttributeError, NotImplementedError) +try: + # WindowsError (1314) will be raised if the caller does not hold the + # SeCreateSymbolicLinkPrivilege privilege + symlink_exception += (WindowsError,) +except NameError: + pass + +# from tarfile import * +__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] + +if sys.version_info[0] < 3: + import __builtin__ as builtins +else: + import builtins + +_open = builtins.open # Since 'open' is TarFile.open + +#--------------------------------------------------------- +# tar constants +#--------------------------------------------------------- +NUL = b"\0" # the null character +BLOCKSIZE = 512 # length of processing blocks +RECORDSIZE = BLOCKSIZE * 20 # length of records +GNU_MAGIC = b"ustar \0" # magic gnu tar string +POSIX_MAGIC = b"ustar\x0000" # magic posix tar string + +LENGTH_NAME = 100 # maximum length of a filename +LENGTH_LINK = 100 # maximum length of a linkname +LENGTH_PREFIX = 155 # maximum length of the prefix field + +REGTYPE = b"0" # regular file +AREGTYPE = b"\0" # regular file +LNKTYPE = b"1" # link (inside tarfile) +SYMTYPE = b"2" # symbolic link +CHRTYPE = b"3" # character special device +BLKTYPE = b"4" # block special device +DIRTYPE = b"5" # directory +FIFOTYPE = b"6" # fifo special device +CONTTYPE = b"7" # contiguous file + +GNUTYPE_LONGNAME = b"L" # GNU tar longname +GNUTYPE_LONGLINK = b"K" # GNU tar longlink +GNUTYPE_SPARSE = b"S" # GNU tar sparse file + +XHDTYPE = b"x" # POSIX.1-2001 extended header +XGLTYPE = b"g" # POSIX.1-2001 global header +SOLARIS_XHDTYPE = b"X" # Solaris extended header + +USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format +GNU_FORMAT = 1 # GNU tar format +PAX_FORMAT = 2 # POSIX.1-2001 (pax) format +DEFAULT_FORMAT = GNU_FORMAT + +#--------------------------------------------------------- +# tarfile constants +#--------------------------------------------------------- +# File types that tarfile supports: +SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, + SYMTYPE, DIRTYPE, FIFOTYPE, + CONTTYPE, CHRTYPE, BLKTYPE, + GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# File types that will be treated as a regular file. +REGULAR_TYPES = (REGTYPE, AREGTYPE, + CONTTYPE, GNUTYPE_SPARSE) + +# File types that are part of the GNU tar format. +GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# Fields from a pax header that override a TarInfo attribute. +PAX_FIELDS = ("path", "linkpath", "size", "mtime", + "uid", "gid", "uname", "gname") + +# Fields from a pax header that are affected by hdrcharset. +PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) + +# Fields in a pax header that are numbers, all other fields +# are treated as strings. +PAX_NUMBER_FIELDS = { + "atime": float, + "ctime": float, + "mtime": float, + "uid": int, + "gid": int, + "size": int +} + +#--------------------------------------------------------- +# Bits used in the mode field, values in octal. +#--------------------------------------------------------- +S_IFLNK = 0o120000 # symbolic link +S_IFREG = 0o100000 # regular file +S_IFBLK = 0o060000 # block device +S_IFDIR = 0o040000 # directory +S_IFCHR = 0o020000 # character device +S_IFIFO = 0o010000 # fifo + +TSUID = 0o4000 # set UID on execution +TSGID = 0o2000 # set GID on execution +TSVTX = 0o1000 # reserved + +TUREAD = 0o400 # read by owner +TUWRITE = 0o200 # write by owner +TUEXEC = 0o100 # execute/search by owner +TGREAD = 0o040 # read by group +TGWRITE = 0o020 # write by group +TGEXEC = 0o010 # execute/search by group +TOREAD = 0o004 # read by other +TOWRITE = 0o002 # write by other +TOEXEC = 0o001 # execute/search by other + +#--------------------------------------------------------- +# initialization +#--------------------------------------------------------- +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() + +#--------------------------------------------------------- +# Some useful functions +#--------------------------------------------------------- + +def stn(s, length, encoding, errors): + """Convert a string to a null-terminated bytes object. + """ + s = s.encode(encoding, errors) + return s[:length] + (length - len(s)) * NUL + +def nts(s, encoding, errors): + """Convert a null-terminated bytes object to a string. + """ + p = s.find(b"\0") + if p != -1: + s = s[:p] + return s.decode(encoding, errors) + +def nti(s): + """Convert a number field to a python number. + """ + # There are two possible encodings for a number field, see + # itn() below. + if s[0] != chr(0o200): + try: + n = int(nts(s, "ascii", "strict") or "0", 8) + except ValueError: + raise InvalidHeaderError("invalid header") + else: + n = 0 + for i in range(len(s) - 1): + n <<= 8 + n += ord(s[i + 1]) + return n + +def itn(n, digits=8, format=DEFAULT_FORMAT): + """Convert a python number to a number field. + """ + # POSIX 1003.1-1988 requires numbers to be encoded as a string of + # octal digits followed by a null-byte, this allows values up to + # (8**(digits-1))-1. GNU tar allows storing numbers greater than + # that if necessary. A leading 0o200 byte indicates this particular + # encoding, the following digits-1 bytes are a big-endian + # representation. This allows values up to (256**(digits-1))-1. + if 0 <= n < 8 ** (digits - 1): + s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL + else: + if format != GNU_FORMAT or n >= 256 ** (digits - 1): + raise ValueError("overflow in number field") + + if n < 0: + # XXX We mimic GNU tar's behaviour with negative numbers, + # this could raise OverflowError. + n = struct.unpack("L", struct.pack("l", n))[0] + + s = bytearray() + for i in range(digits - 1): + s.insert(0, n & 0o377) + n >>= 8 + s.insert(0, 0o200) + return s + +def calc_chksums(buf): + """Calculate the checksum for a member's header by summing up all + characters except for the chksum field which is treated as if + it was filled with spaces. According to the GNU tar sources, + some tars (Sun and NeXT) calculate chksum with signed char, + which will be different if there are chars in the buffer with + the high bit set. So we calculate two checksums, unsigned and + signed. + """ + unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) + signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) + return unsigned_chksum, signed_chksum + +def copyfileobj(src, dst, length=None): + """Copy length bytes from fileobj src to fileobj dst. + If length is None, copy the entire content. + """ + if length == 0: + return + if length is None: + while True: + buf = src.read(16*1024) + if not buf: + break + dst.write(buf) + return + + BUFSIZE = 16 * 1024 + blocks, remainder = divmod(length, BUFSIZE) + for b in range(blocks): + buf = src.read(BUFSIZE) + if len(buf) < BUFSIZE: + raise IOError("end of file reached") + dst.write(buf) + + if remainder != 0: + buf = src.read(remainder) + if len(buf) < remainder: + raise IOError("end of file reached") + dst.write(buf) + return + +filemode_table = ( + ((S_IFLNK, "l"), + (S_IFREG, "-"), + (S_IFBLK, "b"), + (S_IFDIR, "d"), + (S_IFCHR, "c"), + (S_IFIFO, "p")), + + ((TUREAD, "r"),), + ((TUWRITE, "w"),), + ((TUEXEC|TSUID, "s"), + (TSUID, "S"), + (TUEXEC, "x")), + + ((TGREAD, "r"),), + ((TGWRITE, "w"),), + ((TGEXEC|TSGID, "s"), + (TSGID, "S"), + (TGEXEC, "x")), + + ((TOREAD, "r"),), + ((TOWRITE, "w"),), + ((TOEXEC|TSVTX, "t"), + (TSVTX, "T"), + (TOEXEC, "x")) +) + +def filemode(mode): + """Convert a file's mode to a string of the form + -rwxrwxrwx. + Used by TarFile.list() + """ + perm = [] + for table in filemode_table: + for bit, char in table: + if mode & bit == bit: + perm.append(char) + break + else: + perm.append("-") + return "".join(perm) + +class TarError(Exception): + """Base exception.""" + pass +class ExtractError(TarError): + """General exception for extract errors.""" + pass +class ReadError(TarError): + """Exception for unreadable tar archives.""" + pass +class CompressionError(TarError): + """Exception for unavailable compression methods.""" + pass +class StreamError(TarError): + """Exception for unsupported operations on stream-like TarFiles.""" + pass +class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): + """Exception for invalid headers.""" + pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass + +#--------------------------- +# internal stream interface +#--------------------------- +class _LowLevelFile(object): + """Low-level file object. Supports reading and writing. + It is used instead of a regular file object for streaming + access. + """ + + def __init__(self, name, mode): + mode = { + "r": os.O_RDONLY, + "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + }[mode] + if hasattr(os, "O_BINARY"): + mode |= os.O_BINARY + self.fd = os.open(name, mode, 0o666) + + def close(self): + os.close(self.fd) + + def read(self, size): + return os.read(self.fd, size) + + def write(self, s): + os.write(self.fd, s) + +class _Stream(object): + """Class that serves as an adapter between TarFile and + a stream-like object. The stream-like object only + needs to have a read() or write() method and is accessed + blockwise. Use of gzip or bzip2 compression is possible. + A stream-like object could be for example: sys.stdin, + sys.stdout, a socket, a tape device etc. + + _Stream is intended to be used only internally. + """ + + def __init__(self, name, mode, comptype, fileobj, bufsize): + """Construct a _Stream object. + """ + self._extfileobj = True + if fileobj is None: + fileobj = _LowLevelFile(name, mode) + self._extfileobj = False + + if comptype == '*': + # Enable transparent compression detection for the + # stream interface + fileobj = _StreamProxy(fileobj) + comptype = fileobj.getcomptype() + + self.name = name or "" + self.mode = mode + self.comptype = comptype + self.fileobj = fileobj + self.bufsize = bufsize + self.buf = b"" + self.pos = 0 + self.closed = False + + try: + if comptype == "gz": + try: + import zlib + except ImportError: + raise CompressionError("zlib module is not available") + self.zlib = zlib + self.crc = zlib.crc32(b"") + if mode == "r": + self._init_read_gz() + else: + self._init_write_gz() + + if comptype == "bz2": + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + if mode == "r": + self.dbuf = b"" + self.cmp = bz2.BZ2Decompressor() + else: + self.cmp = bz2.BZ2Compressor() + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + def __del__(self): + if hasattr(self, "closed") and not self.closed: + self.close() + + def _init_write_gz(self): + """Initialize for writing with gzip compression. + """ + self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) + timestamp = struct.pack("<L", int(time.time())) + self.__write(b"\037\213\010\010" + timestamp + b"\002\377") + if self.name.endswith(".gz"): + self.name = self.name[:-3] + # RFC1952 says we must use ISO-8859-1 for the FNAME field. + self.__write(self.name.encode("iso-8859-1", "replace") + NUL) + + def write(self, s): + """Write string s to the stream. + """ + if self.comptype == "gz": + self.crc = self.zlib.crc32(s, self.crc) + self.pos += len(s) + if self.comptype != "tar": + s = self.cmp.compress(s) + self.__write(s) + + def __write(self, s): + """Write string s to the stream if a whole new block + is ready to be written. + """ + self.buf += s + while len(self.buf) > self.bufsize: + self.fileobj.write(self.buf[:self.bufsize]) + self.buf = self.buf[self.bufsize:] + + def close(self): + """Close the _Stream object. No operation should be + done on it afterwards. + """ + if self.closed: + return + + if self.mode == "w" and self.comptype != "tar": + self.buf += self.cmp.flush() + + if self.mode == "w" and self.buf: + self.fileobj.write(self.buf) + self.buf = b"" + if self.comptype == "gz": + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff)) + self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF)) + + if not self._extfileobj: + self.fileobj.close() + + self.closed = True + + def _init_read_gz(self): + """Initialize for reading a gzip compressed fileobj. + """ + self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS) + self.dbuf = b"" + + # taken from gzip.GzipFile with some alterations + if self.__read(2) != b"\037\213": + raise ReadError("not a gzip file") + if self.__read(1) != b"\010": + raise CompressionError("unsupported compression method") + + flag = ord(self.__read(1)) + self.__read(6) + + if flag & 4: + xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) + self.read(xlen) + if flag & 8: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 16: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 2: + self.__read(2) + + def tell(self): + """Return the stream's file pointer position. + """ + return self.pos + + def seek(self, pos=0): + """Set the stream's file pointer to pos. Negative seeking + is forbidden. + """ + if pos - self.pos >= 0: + blocks, remainder = divmod(pos - self.pos, self.bufsize) + for i in range(blocks): + self.read(self.bufsize) + self.read(remainder) + else: + raise StreamError("seeking backwards is not allowed") + return self.pos + + def read(self, size=None): + """Return the next size number of bytes from the stream. + If size is not defined, return all bytes of the stream + up to EOF. + """ + if size is None: + t = [] + while True: + buf = self._read(self.bufsize) + if not buf: + break + t.append(buf) + buf = "".join(t) + else: + buf = self._read(size) + self.pos += len(buf) + return buf + + def _read(self, size): + """Return size bytes from the stream. + """ + if self.comptype == "tar": + return self.__read(size) + + c = len(self.dbuf) + while c < size: + buf = self.__read(self.bufsize) + if not buf: + break + try: + buf = self.cmp.decompress(buf) + except IOError: + raise ReadError("invalid compressed data") + self.dbuf += buf + c += len(buf) + buf = self.dbuf[:size] + self.dbuf = self.dbuf[size:] + return buf + + def __read(self, size): + """Return size bytes from stream. If internal buffer is empty, + read another block from the stream. + """ + c = len(self.buf) + while c < size: + buf = self.fileobj.read(self.bufsize) + if not buf: + break + self.buf += buf + c += len(buf) + buf = self.buf[:size] + self.buf = self.buf[size:] + return buf +# class _Stream + +class _StreamProxy(object): + """Small proxy class that enables transparent compression + detection for the Stream interface (mode 'r|*'). + """ + + def __init__(self, fileobj): + self.fileobj = fileobj + self.buf = self.fileobj.read(BLOCKSIZE) + + def read(self, size): + self.read = self.fileobj.read + return self.buf + + def getcomptype(self): + if self.buf.startswith(b"\037\213\010"): + return "gz" + if self.buf.startswith(b"BZh91"): + return "bz2" + return "tar" + + def close(self): + self.fileobj.close() +# class StreamProxy + +class _BZ2Proxy(object): + """Small proxy class that enables external file object + support for "r:bz2" and "w:bz2" modes. This is actually + a workaround for a limitation in bz2 module's BZ2File + class which (unlike gzip.GzipFile) has no support for + a file object argument. + """ + + blocksize = 16 * 1024 + + def __init__(self, fileobj, mode): + self.fileobj = fileobj + self.mode = mode + self.name = getattr(self.fileobj, "name", None) + self.init() + + def init(self): + import bz2 + self.pos = 0 + if self.mode == "r": + self.bz2obj = bz2.BZ2Decompressor() + self.fileobj.seek(0) + self.buf = b"" + else: + self.bz2obj = bz2.BZ2Compressor() + + def read(self, size): + x = len(self.buf) + while x < size: + raw = self.fileobj.read(self.blocksize) + if not raw: + break + data = self.bz2obj.decompress(raw) + self.buf += data + x += len(data) + + buf = self.buf[:size] + self.buf = self.buf[size:] + self.pos += len(buf) + return buf + + def seek(self, pos): + if pos < self.pos: + self.init() + self.read(pos - self.pos) + + def tell(self): + return self.pos + + def write(self, data): + self.pos += len(data) + raw = self.bz2obj.compress(data) + self.fileobj.write(raw) + + def close(self): + if self.mode == "w": + raw = self.bz2obj.flush() + self.fileobj.write(raw) +# class _BZ2Proxy + +#------------------------ +# Extraction file object +#------------------------ +class _FileInFile(object): + """A thin wrapper around an existing file object that + provides a part of its data as an individual file + object. + """ + + def __init__(self, fileobj, offset, size, blockinfo=None): + self.fileobj = fileobj + self.offset = offset + self.size = size + self.position = 0 + + if blockinfo is None: + blockinfo = [(0, size)] + + # Construct a map with data and zero blocks. + self.map_index = 0 + self.map = [] + lastpos = 0 + realpos = self.offset + for offset, size in blockinfo: + if offset > lastpos: + self.map.append((False, lastpos, offset, None)) + self.map.append((True, offset, offset + size, realpos)) + realpos += size + lastpos = offset + size + if lastpos < self.size: + self.map.append((False, lastpos, self.size, None)) + + def seekable(self): + if not hasattr(self.fileobj, "seekable"): + # XXX gzip.GzipFile and bz2.BZ2File + return True + return self.fileobj.seekable() + + def tell(self): + """Return the current file position. + """ + return self.position + + def seek(self, position): + """Seek to a position in the file. + """ + self.position = position + + def read(self, size=None): + """Read data from the file. + """ + if size is None: + size = self.size - self.position + else: + size = min(size, self.size - self.position) + + buf = b"" + while size > 0: + while True: + data, start, stop, offset = self.map[self.map_index] + if start <= self.position < stop: + break + else: + self.map_index += 1 + if self.map_index == len(self.map): + self.map_index = 0 + length = min(size, stop - self.position) + if data: + self.fileobj.seek(offset + (self.position - start)) + buf += self.fileobj.read(length) + else: + buf += NUL * length + size -= length + self.position += length + return buf +#class _FileInFile + + +class ExFileObject(object): + """File-like object for reading an archive member. + Is returned by TarFile.extractfile(). + """ + blocksize = 1024 + + def __init__(self, tarfile, tarinfo): + self.fileobj = _FileInFile(tarfile.fileobj, + tarinfo.offset_data, + tarinfo.size, + tarinfo.sparse) + self.name = tarinfo.name + self.mode = "r" + self.closed = False + self.size = tarinfo.size + + self.position = 0 + self.buffer = b"" + + def readable(self): + return True + + def writable(self): + return False + + def seekable(self): + return self.fileobj.seekable() + + def read(self, size=None): + """Read at most size bytes from the file. If size is not + present or None, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + buf = b"" + if self.buffer: + if size is None: + buf = self.buffer + self.buffer = b"" + else: + buf = self.buffer[:size] + self.buffer = self.buffer[size:] + + if size is None: + buf += self.fileobj.read() + else: + buf += self.fileobj.read(size - len(buf)) + + self.position += len(buf) + return buf + + # XXX TextIOWrapper uses the read1() method. + read1 = read + + def readline(self, size=-1): + """Read one entire line from the file. If size is present + and non-negative, return a string with at most that + size, which may be an incomplete line. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + while True: + buf = self.fileobj.read(self.blocksize) + self.buffer += buf + if not buf or b"\n" in buf: + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + pos = len(self.buffer) + break + + if size != -1: + pos = min(size, pos) + + buf = self.buffer[:pos] + self.buffer = self.buffer[pos:] + self.position += len(buf) + return buf + + def readlines(self): + """Return a list with all remaining lines. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def tell(self): + """Return the current file position. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + return self.position + + def seek(self, pos, whence=os.SEEK_SET): + """Seek to a position in the file. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if whence == os.SEEK_SET: + self.position = min(max(pos, 0), self.size) + elif whence == os.SEEK_CUR: + if pos < 0: + self.position = max(self.position + pos, 0) + else: + self.position = min(self.position + pos, self.size) + elif whence == os.SEEK_END: + self.position = max(min(self.size + pos, self.size), 0) + else: + raise ValueError("Invalid argument") + + self.buffer = b"" + self.fileobj.seek(self.position) + + def close(self): + """Close the file object. + """ + self.closed = True + + def __iter__(self): + """Get an iterator over the file's lines. + """ + while True: + line = self.readline() + if not line: + break + yield line +#class ExFileObject + +#------------------ +# Exported Classes +#------------------ +class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. + TarInfo objects are returned by TarFile.getmember(), + TarFile.getmembers() and TarFile.gettarinfo() and are + usually created internally. + """ + + __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", + "chksum", "type", "linkname", "uname", "gname", + "devmajor", "devminor", + "offset", "offset_data", "pax_headers", "sparse", + "tarfile", "_sparse_structs", "_link_target") + + def __init__(self, name=""): + """Construct a TarInfo object. name is the optional name + of the member. + """ + self.name = name # member name + self.mode = 0o644 # file permissions + self.uid = 0 # user id + self.gid = 0 # group id + self.size = 0 # file size + self.mtime = 0 # modification time + self.chksum = 0 # header checksum + self.type = REGTYPE # member type + self.linkname = "" # link name + self.uname = "" # user name + self.gname = "" # group name + self.devmajor = 0 # device major number + self.devminor = 0 # device minor number + + self.offset = 0 # the tar header starts here + self.offset_data = 0 # the file's data starts here + + self.sparse = None # sparse member information + self.pax_headers = {} # pax header information + + # In pax headers the "name" and "linkname" field are called + # "path" and "linkpath". + def _getpath(self): + return self.name + def _setpath(self, name): + self.name = name + path = property(_getpath, _setpath) + + def _getlinkpath(self): + return self.linkname + def _setlinkpath(self, linkname): + self.linkname = linkname + linkpath = property(_getlinkpath, _setlinkpath) + + def __repr__(self): + return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + + def get_info(self): + """Return the TarInfo's attributes as a dictionary. + """ + info = { + "name": self.name, + "mode": self.mode & 0o7777, + "uid": self.uid, + "gid": self.gid, + "size": self.size, + "mtime": self.mtime, + "chksum": self.chksum, + "type": self.type, + "linkname": self.linkname, + "uname": self.uname, + "gname": self.gname, + "devmajor": self.devmajor, + "devminor": self.devminor + } + + if info["type"] == DIRTYPE and not info["name"].endswith("/"): + info["name"] += "/" + + return info + + def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): + """Return a tar header as a string of 512 byte blocks. + """ + info = self.get_info() + + if format == USTAR_FORMAT: + return self.create_ustar_header(info, encoding, errors) + elif format == GNU_FORMAT: + return self.create_gnu_header(info, encoding, errors) + elif format == PAX_FORMAT: + return self.create_pax_header(info, encoding) + else: + raise ValueError("invalid format") + + def create_ustar_header(self, info, encoding, errors): + """Return the object as a ustar header block. + """ + info["magic"] = POSIX_MAGIC + + if len(info["linkname"]) > LENGTH_LINK: + raise ValueError("linkname is too long") + + if len(info["name"]) > LENGTH_NAME: + info["prefix"], info["name"] = self._posix_split_name(info["name"]) + + return self._create_header(info, USTAR_FORMAT, encoding, errors) + + def create_gnu_header(self, info, encoding, errors): + """Return the object as a GNU header block sequence. + """ + info["magic"] = GNU_MAGIC + + buf = b"" + if len(info["linkname"]) > LENGTH_LINK: + buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) + + if len(info["name"]) > LENGTH_NAME: + buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) + + return buf + self._create_header(info, GNU_FORMAT, encoding, errors) + + def create_pax_header(self, info, encoding): + """Return the object as a ustar header block. If it cannot be + represented this way, prepend a pax extended header sequence + with supplement information. + """ + info["magic"] = POSIX_MAGIC + pax_headers = self.pax_headers.copy() + + # Test string fields for values that exceed the field length or cannot + # be represented in ASCII encoding. + for name, hname, length in ( + ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), + ("uname", "uname", 32), ("gname", "gname", 32)): + + if hname in pax_headers: + # The pax header has priority. + continue + + # Try to encode the string as ASCII. + try: + info[name].encode("ascii", "strict") + except UnicodeEncodeError: + pax_headers[hname] = info[name] + continue + + if len(info[name]) > length: + pax_headers[hname] = info[name] + + # Test number fields for values that exceed the field limit or values + # that like to be stored as float. + for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): + if name in pax_headers: + # The pax header has priority. Avoid overflow. + info[name] = 0 + continue + + val = info[name] + if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): + pax_headers[name] = str(val) + info[name] = 0 + + # Create a pax extended header if necessary. + if pax_headers: + buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) + else: + buf = b"" + + return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") + + @classmethod + def create_pax_global_header(cls, pax_headers): + """Return the object as a pax global header block sequence. + """ + return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") + + def _posix_split_name(self, name): + """Split a name longer than 100 chars into a prefix + and a name part. + """ + prefix = name[:LENGTH_PREFIX + 1] + while prefix and prefix[-1] != "/": + prefix = prefix[:-1] + + name = name[len(prefix):] + prefix = prefix[:-1] + + if not prefix or len(name) > LENGTH_NAME: + raise ValueError("name is too long") + return prefix, name + + @staticmethod + def _create_header(info, format, encoding, errors): + """Return a header block. info is a dictionary with file + information, format must be one of the *_FORMAT constants. + """ + parts = [ + stn(info.get("name", ""), 100, encoding, errors), + itn(info.get("mode", 0) & 0o7777, 8, format), + itn(info.get("uid", 0), 8, format), + itn(info.get("gid", 0), 8, format), + itn(info.get("size", 0), 12, format), + itn(info.get("mtime", 0), 12, format), + b" ", # checksum field + info.get("type", REGTYPE), + stn(info.get("linkname", ""), 100, encoding, errors), + info.get("magic", POSIX_MAGIC), + stn(info.get("uname", ""), 32, encoding, errors), + stn(info.get("gname", ""), 32, encoding, errors), + itn(info.get("devmajor", 0), 8, format), + itn(info.get("devminor", 0), 8, format), + stn(info.get("prefix", ""), 155, encoding, errors) + ] + + buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) + chksum = calc_chksums(buf[-BLOCKSIZE:])[0] + buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] + return buf + + @staticmethod + def _create_payload(payload): + """Return the string payload filled with zero bytes + up to the next 512 byte border. + """ + blocks, remainder = divmod(len(payload), BLOCKSIZE) + if remainder > 0: + payload += (BLOCKSIZE - remainder) * NUL + return payload + + @classmethod + def _create_gnu_long_header(cls, name, type, encoding, errors): + """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence + for name. + """ + name = name.encode(encoding, errors) + NUL + + info = {} + info["name"] = "././@LongLink" + info["type"] = type + info["size"] = len(name) + info["magic"] = GNU_MAGIC + + # create extended header + name blocks. + return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ + cls._create_payload(name) + + @classmethod + def _create_pax_generic_header(cls, pax_headers, type, encoding): + """Return a POSIX.1-2008 extended or global header sequence + that contains a list of keyword, value pairs. The values + must be strings. + """ + # Check if one of the fields contains surrogate characters and thereby + # forces hdrcharset=BINARY, see _proc_pax() for more information. + binary = False + for keyword, value in pax_headers.items(): + try: + value.encode("utf8", "strict") + except UnicodeEncodeError: + binary = True + break + + records = b"" + if binary: + # Put the hdrcharset field at the beginning of the header. + records += b"21 hdrcharset=BINARY\n" + + for keyword, value in pax_headers.items(): + keyword = keyword.encode("utf8") + if binary: + # Try to restore the original byte representation of `value'. + # Needless to say, that the encoding must match the string. + value = value.encode(encoding, "surrogateescape") + else: + value = value.encode("utf8") + + l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' + n = p = 0 + while True: + n = l + len(str(p)) + if n == p: + break + p = n + records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" + + # We use a hardcoded "././@PaxHeader" name like star does + # instead of the one that POSIX recommends. + info = {} + info["name"] = "././@PaxHeader" + info["type"] = type + info["size"] = len(records) + info["magic"] = POSIX_MAGIC + + # Create pax header + record blocks. + return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ + cls._create_payload(records) + + @classmethod + def frombuf(cls, buf, encoding, errors): + """Construct a TarInfo object from a 512 byte bytes object. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") + if len(buf) != BLOCKSIZE: + raise TruncatedHeaderError("truncated header") + if buf.count(NUL) == BLOCKSIZE: + raise EOFHeaderError("end of file header") + + chksum = nti(buf[148:156]) + if chksum not in calc_chksums(buf): + raise InvalidHeaderError("bad checksum") + + obj = cls() + obj.name = nts(buf[0:100], encoding, errors) + obj.mode = nti(buf[100:108]) + obj.uid = nti(buf[108:116]) + obj.gid = nti(buf[116:124]) + obj.size = nti(buf[124:136]) + obj.mtime = nti(buf[136:148]) + obj.chksum = chksum + obj.type = buf[156:157] + obj.linkname = nts(buf[157:257], encoding, errors) + obj.uname = nts(buf[265:297], encoding, errors) + obj.gname = nts(buf[297:329], encoding, errors) + obj.devmajor = nti(buf[329:337]) + obj.devminor = nti(buf[337:345]) + prefix = nts(buf[345:500], encoding, errors) + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. + if obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # The old GNU sparse format occupies some of the unused + # space in the buffer for up to 4 sparse structures. + # Save the them for later processing in _proc_sparse(). + if obj.type == GNUTYPE_SPARSE: + pos = 386 + structs = [] + for i in range(4): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[482]) + origsize = nti(buf[483:495]) + obj._sparse_structs = (structs, isextended, origsize) + + # Remove redundant slashes from directories. + if obj.isdir(): + obj.name = obj.name.rstrip("/") + + # Reconstruct a ustar longname. + if prefix and obj.type not in GNU_TYPES: + obj.name = prefix + "/" + obj.name + return obj + + @classmethod + def fromtarfile(cls, tarfile): + """Return the next TarInfo object from TarFile object + tarfile. + """ + buf = tarfile.fileobj.read(BLOCKSIZE) + obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + + #-------------------------------------------------------------------------- + # The following are methods that are called depending on the type of a + # member. The entry point is _proc_member() which can be overridden in a + # subclass to add custom _proc_*() methods. A _proc_*() method MUST + # implement the following + # operations: + # 1. Set self.offset_data to the position where the data blocks begin, + # if there is data that follows. + # 2. Set tarfile.offset to the position where the next member's header will + # begin. + # 3. Return self or another valid TarInfo object. + def _proc_member(self, tarfile): + """Choose the right processing method depending on + the type and call it. + """ + if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): + return self._proc_gnulong(tarfile) + elif self.type == GNUTYPE_SPARSE: + return self._proc_sparse(tarfile) + elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): + return self._proc_pax(tarfile) + else: + return self._proc_builtin(tarfile) + + def _proc_builtin(self, tarfile): + """Process a builtin type or an unknown type which + will be treated as a regular file. + """ + self.offset_data = tarfile.fileobj.tell() + offset = self.offset_data + if self.isreg() or self.type not in SUPPORTED_TYPES: + # Skip the following data blocks. + offset += self._block(self.size) + tarfile.offset = offset + + # Patch the TarInfo object with saved global + # header information. + self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) + + return self + + def _proc_gnulong(self, tarfile): + """Process the blocks that hold a GNU longname + or longlink member. + """ + buf = tarfile.fileobj.read(self._block(self.size)) + + # Fetch the next header and process it. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Patch the TarInfo object from the next header with + # the longname information. + next.offset = self.offset + if self.type == GNUTYPE_LONGNAME: + next.name = nts(buf, tarfile.encoding, tarfile.errors) + elif self.type == GNUTYPE_LONGLINK: + next.linkname = nts(buf, tarfile.encoding, tarfile.errors) + + return next + + def _proc_sparse(self, tarfile): + """Process a GNU sparse header plus extra headers. + """ + # We already collected some sparse structures in frombuf(). + structs, isextended, origsize = self._sparse_structs + del self._sparse_structs + + # Collect sparse structures from extended header blocks. + while isextended: + buf = tarfile.fileobj.read(BLOCKSIZE) + pos = 0 + for i in range(21): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset and numbytes: + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[504]) + self.sparse = structs + + self.offset_data = tarfile.fileobj.tell() + tarfile.offset = self.offset_data + self._block(self.size) + self.size = origsize + return self + + def _proc_pax(self, tarfile): + """Process an extended or global header as described in + POSIX.1-2008. + """ + # Read the header information. + buf = tarfile.fileobj.read(self._block(self.size)) + + # A pax header stores supplemental information for either + # the following file (extended) or all following files + # (global). + if self.type == XGLTYPE: + pax_headers = tarfile.pax_headers + else: + pax_headers = tarfile.pax_headers.copy() + + # Check if the pax header contains a hdrcharset field. This tells us + # the encoding of the path, linkpath, uname and gname fields. Normally, + # these fields are UTF-8 encoded but since POSIX.1-2008 tar + # implementations are allowed to store them as raw binary strings if + # the translation to UTF-8 fails. + match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) + if match is not None: + pax_headers["hdrcharset"] = match.group(1).decode("utf8") + + # For the time being, we don't care about anything other than "BINARY". + # The only other value that is currently allowed by the standard is + # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. + hdrcharset = pax_headers.get("hdrcharset") + if hdrcharset == "BINARY": + encoding = tarfile.encoding + else: + encoding = "utf8" + + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and + # the newline. keyword and value are both UTF-8 encoded strings. + regex = re.compile(br"(\d+) ([^=]+)=") + pos = 0 + while True: + match = regex.match(buf, pos) + if not match: + break + + length, keyword = match.groups() + length = int(length) + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + # Normally, we could just use "utf8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot + # translate to UTF-8 as raw strings (unfortunately without a + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. + keyword = self._decode_pax_field(keyword, "utf8", "utf8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: + value = self._decode_pax_field(value, encoding, tarfile.encoding, + tarfile.errors) + else: + value = self._decode_pax_field(value, "utf8", "utf8", + tarfile.errors) + + pax_headers[keyword] = value + pos += length + + # Fetch the next header. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Process GNU sparse information. + if "GNU.sparse.map" in pax_headers: + # GNU extended sparse format version 0.1. + self._proc_gnusparse_01(next, pax_headers) + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. + self._proc_gnusparse_00(next, pax_headers, buf) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. + self._proc_gnusparse_10(next, pax_headers, tarfile) + + if self.type in (XHDTYPE, SOLARIS_XHDTYPE): + # Patch the TarInfo object with the extended header info. + next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) + next.offset = self.offset + + if "size" in pax_headers: + # If the extended header replaces the size field, + # we need to recalculate the offset where the next + # header starts. + offset = next.offset_data + if next.isreg() or next.type not in SUPPORTED_TYPES: + offset += next._block(next.size) + tarfile.offset = offset + + return next + + def _proc_gnusparse_00(self, next, pax_headers, buf): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] + for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): + offsets.append(int(match.group(1))) + numbytes = [] + for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): + numbytes.append(int(match.group(1))) + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): + """Process a GNU tar extended sparse header, version 0.1. + """ + sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _proc_gnusparse_10(self, next, pax_headers, tarfile): + """Process a GNU tar extended sparse header, version 1.0. + """ + fields = None + sparse = [] + buf = tarfile.fileobj.read(BLOCKSIZE) + fields, buf = buf.split(b"\n", 1) + fields = int(fields) + while len(sparse) < fields * 2: + if b"\n" not in buf: + buf += tarfile.fileobj.read(BLOCKSIZE) + number, buf = buf.split(b"\n", 1) + sparse.append(int(number)) + next.offset_data = tarfile.fileobj.tell() + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _apply_pax_info(self, pax_headers, encoding, errors): + """Replace fields with supplemental information from a previous + pax extended or global header. + """ + for keyword, value in pax_headers.items(): + if keyword == "GNU.sparse.name": + setattr(self, "path", value) + elif keyword == "GNU.sparse.size": + setattr(self, "size", int(value)) + elif keyword == "GNU.sparse.realsize": + setattr(self, "size", int(value)) + elif keyword in PAX_FIELDS: + if keyword in PAX_NUMBER_FIELDS: + try: + value = PAX_NUMBER_FIELDS[keyword](value) + except ValueError: + value = 0 + if keyword == "path": + value = value.rstrip("/") + setattr(self, keyword, value) + + self.pax_headers = pax_headers.copy() + + def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): + """Decode a single field from a pax record. + """ + try: + return value.decode(encoding, "strict") + except UnicodeDecodeError: + return value.decode(fallback_encoding, fallback_errors) + + def _block(self, count): + """Round up a byte count by BLOCKSIZE and return it, + e.g. _block(834) => 1024. + """ + blocks, remainder = divmod(count, BLOCKSIZE) + if remainder: + blocks += 1 + return blocks * BLOCKSIZE + + def isreg(self): + return self.type in REGULAR_TYPES + def isfile(self): + return self.isreg() + def isdir(self): + return self.type == DIRTYPE + def issym(self): + return self.type == SYMTYPE + def islnk(self): + return self.type == LNKTYPE + def ischr(self): + return self.type == CHRTYPE + def isblk(self): + return self.type == BLKTYPE + def isfifo(self): + return self.type == FIFOTYPE + def issparse(self): + return self.sparse is not None + def isdev(self): + return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) +# class TarInfo + +class TarFile(object): + """The TarFile Class provides an interface to tar archives. + """ + + debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) + + dereference = False # If true, add content of linked file to the + # tar file, else the link. + + ignore_zeros = False # If true, skips empty or invalid blocks and + # continues processing. + + errorlevel = 1 # If 0, fatal errors only appear in debug + # messages (if debug >= 0). If > 0, errors + # are passed to the caller as exceptions. + + format = DEFAULT_FORMAT # The format to use when creating an archive. + + encoding = ENCODING # Encoding for 8-bit character strings. + + errors = None # Error handler for unicode conversion. + + tarinfo = TarInfo # The default TarInfo class to use. + + fileobject = ExFileObject # The default ExFileObject class to use. + + def __init__(self, name=None, mode="r", fileobj=None, format=None, + tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, + errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): + """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to + read from an existing archive, 'a' to append data to an existing + file or 'w' to create a new file overwriting an existing one. `mode' + defaults to 'r'. + If `fileobj' is given, it is used for reading or writing data. If it + can be determined, `mode' is overridden by `fileobj's mode. + `fileobj' is not closed, when TarFile is closed. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + self.mode = mode + self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + + if not fileobj: + if self.mode == "a" and not os.path.exists(name): + # Create nonexistent files in append mode. + self.mode = "w" + self._mode = "wb" + fileobj = bltn_open(name, self._mode) + self._extfileobj = False + else: + if name is None and hasattr(fileobj, "name"): + name = fileobj.name + if hasattr(fileobj, "mode"): + self._mode = fileobj.mode + self._extfileobj = True + self.name = os.path.abspath(name) if name else None + self.fileobj = fileobj + + # Init attributes. + if format is not None: + self.format = format + if tarinfo is not None: + self.tarinfo = tarinfo + if dereference is not None: + self.dereference = dereference + if ignore_zeros is not None: + self.ignore_zeros = ignore_zeros + if encoding is not None: + self.encoding = encoding + self.errors = errors + + if pax_headers is not None and self.format == PAX_FORMAT: + self.pax_headers = pax_headers + else: + self.pax_headers = {} + + if debug is not None: + self.debug = debug + if errorlevel is not None: + self.errorlevel = errorlevel + + # Init datastructures. + self.closed = False + self.members = [] # list of members as TarInfo objects + self._loaded = False # flag if all members have been read + self.offset = self.fileobj.tell() + # current position in the archive file + self.inodes = {} # dictionary caching the inodes of + # archive members already added + + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + while True: + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) + break + except HeaderError as e: + raise ReadError(str(e)) + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + #-------------------------------------------------------------------------- + # Below are the classmethods which act as alternate constructors to the + # TarFile class. The open() method is the only one that is needed for + # public use; it is the "super"-constructor and is able to select an + # adequate "sub"-constructor for a particular compression using the mapping + # from OPEN_METH. + # + # This concept allows one to subclass TarFile without losing the comfort of + # the super-constructor. A sub-constructor is registered and made available + # by adding it to the mapping in OPEN_METH. + + @classmethod + def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): + """Open a tar archive for reading, writing or appending. Return + an appropriate TarFile class. + + mode: + 'r' or 'r:*' open for reading with transparent compression + 'r:' open for reading exclusively uncompressed + 'r:gz' open for reading with gzip compression + 'r:bz2' open for reading with bzip2 compression + 'a' or 'a:' open for appending, creating the file if necessary + 'w' or 'w:' open for writing without compression + 'w:gz' open for writing with gzip compression + 'w:bz2' open for writing with bzip2 compression + + 'r|*' open a stream of tar blocks with transparent compression + 'r|' open an uncompressed stream of tar blocks for reading + 'r|gz' open a gzip compressed stream of tar blocks + 'r|bz2' open a bzip2 compressed stream of tar blocks + 'w|' open an uncompressed stream for writing + 'w|gz' open a gzip compressed stream for writing + 'w|bz2' open a bzip2 compressed stream for writing + """ + + if not name and not fileobj: + raise ValueError("nothing to open") + + if mode in ("r", "r:*"): + # Find out which *open() is appropriate for opening the file. + for comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + if fileobj is not None: + saved_pos = fileobj.tell() + try: + return func(name, "r", fileobj, **kwargs) + except (ReadError, CompressionError) as e: + if fileobj is not None: + fileobj.seek(saved_pos) + continue + raise ReadError("file could not be opened successfully") + + elif ":" in mode: + filemode, comptype = mode.split(":", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + # Select the *open() function according to + # given compression. + if comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + else: + raise CompressionError("unknown compression type %r" % comptype) + return func(name, filemode, fileobj, **kwargs) + + elif "|" in mode: + filemode, comptype = mode.split("|", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + if filemode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + stream = _Stream(name, filemode, comptype, fileobj, bufsize) + try: + t = cls(name, filemode, stream, **kwargs) + except: + stream.close() + raise + t._extfileobj = False + return t + + elif mode in "aw": + return cls.taropen(name, mode, fileobj, **kwargs) + + raise ValueError("undiscernible mode") + + @classmethod + def taropen(cls, name, mode="r", fileobj=None, **kwargs): + """Open uncompressed tar archive name for reading or writing. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + return cls(name, mode, fileobj, **kwargs) + + @classmethod + def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open gzip compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + try: + import gzip + gzip.GzipFile + except (ImportError, AttributeError): + raise CompressionError("gzip module is not available") + + extfileobj = fileobj is not None + try: + fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + t = cls.taropen(name, mode, fileobj, **kwargs) + except IOError: + if not extfileobj and fileobj is not None: + fileobj.close() + if fileobj is None: + raise + raise ReadError("not a gzip file") + except: + if not extfileobj and fileobj is not None: + fileobj.close() + raise + t._extfileobj = extfileobj + return t + + @classmethod + def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open bzip2 compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'.") + + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + + if fileobj is not None: + fileobj = _BZ2Proxy(fileobj, mode) + else: + fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except (IOError, EOFError): + fileobj.close() + raise ReadError("not a bzip2 file") + t._extfileobj = False + return t + + # All *open() methods are registered here. + OPEN_METH = { + "tar": "taropen", # uncompressed tar + "gz": "gzopen", # gzip compressed tar + "bz2": "bz2open" # bzip2 compressed tar + } + + #-------------------------------------------------------------------------- + # The public methods which TarFile provides: + + def close(self): + """Close the TarFile. In write-mode, two finishing zero blocks are + appended to the archive. + """ + if self.closed: + return + + if self.mode in "aw": + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + + if not self._extfileobj: + self.fileobj.close() + self.closed = True + + def getmember(self, name): + """Return a TarInfo object for member `name'. If `name' can not be + found in the archive, KeyError is raised. If a member occurs more + than once in the archive, its last occurrence is assumed to be the + most up-to-date version. + """ + tarinfo = self._getmember(name) + if tarinfo is None: + raise KeyError("filename %r not found" % name) + return tarinfo + + def getmembers(self): + """Return the members of the archive as a list of TarInfo objects. The + list has the same order as the members in the archive. + """ + self._check() + if not self._loaded: # if we want to obtain a list of + self._load() # all members, we first have to + # scan the whole archive. + return self.members + + def getnames(self): + """Return the members of the archive as a list of their names. It has + the same order as the list returned by getmembers(). + """ + return [tarinfo.name for tarinfo in self.getmembers()] + + def gettarinfo(self, name=None, arcname=None, fileobj=None): + """Create a TarInfo object for either the file `name' or the file + object `fileobj' (using os.fstat on its file descriptor). You can + modify some of the TarInfo's attributes before you add it using + addfile(). If given, `arcname' specifies an alternative name for the + file in the archive. + """ + self._check("aw") + + # When fileobj is given, replace name by + # fileobj's real name. + if fileobj is not None: + name = fileobj.name + + # Building the name of the member in the archive. + # Backward slashes are converted to forward slashes, + # Absolute paths are turned to relative paths. + if arcname is None: + arcname = name + drv, arcname = os.path.splitdrive(arcname) + arcname = arcname.replace(os.sep, "/") + arcname = arcname.lstrip("/") + + # Now, fill the TarInfo object with + # information specific for the file. + tarinfo = self.tarinfo() + tarinfo.tarfile = self + + # Use os.stat or os.lstat, depending on platform + # and if symlinks shall be resolved. + if fileobj is None: + if hasattr(os, "lstat") and not self.dereference: + statres = os.lstat(name) + else: + statres = os.stat(name) + else: + statres = os.fstat(fileobj.fileno()) + linkname = "" + + stmd = statres.st_mode + if stat.S_ISREG(stmd): + inode = (statres.st_ino, statres.st_dev) + if not self.dereference and statres.st_nlink > 1 and \ + inode in self.inodes and arcname != self.inodes[inode]: + # Is it a hardlink to an already + # archived file? + type = LNKTYPE + linkname = self.inodes[inode] + else: + # The inode is added only if its valid. + # For win32 it is always 0. + type = REGTYPE + if inode[0]: + self.inodes[inode] = arcname + elif stat.S_ISDIR(stmd): + type = DIRTYPE + elif stat.S_ISFIFO(stmd): + type = FIFOTYPE + elif stat.S_ISLNK(stmd): + type = SYMTYPE + linkname = os.readlink(name) + elif stat.S_ISCHR(stmd): + type = CHRTYPE + elif stat.S_ISBLK(stmd): + type = BLKTYPE + else: + return None + + # Fill the TarInfo object with all + # information we can get. + tarinfo.name = arcname + tarinfo.mode = stmd + tarinfo.uid = statres.st_uid + tarinfo.gid = statres.st_gid + if type == REGTYPE: + tarinfo.size = statres.st_size + else: + tarinfo.size = 0 + tarinfo.mtime = statres.st_mtime + tarinfo.type = type + tarinfo.linkname = linkname + if pwd: + try: + tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] + except KeyError: + pass + if grp: + try: + tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] + except KeyError: + pass + + if type in (CHRTYPE, BLKTYPE): + if hasattr(os, "major") and hasattr(os, "minor"): + tarinfo.devmajor = os.major(statres.st_rdev) + tarinfo.devminor = os.minor(statres.st_rdev) + return tarinfo + + def list(self, verbose=True): + """Print a table of contents to sys.stdout. If `verbose' is False, only + the names of the members are printed. If it is True, an `ls -l'-like + output is produced. + """ + self._check() + + for tarinfo in self: + if verbose: + print(filemode(tarinfo.mode), end=' ') + print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid), end=' ') + if tarinfo.ischr() or tarinfo.isblk(): + print("%10s" % ("%d,%d" \ + % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + else: + print("%10d" % tarinfo.size, end=' ') + print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6], end=' ') + + print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + + if verbose: + if tarinfo.issym(): + print("->", tarinfo.linkname, end=' ') + if tarinfo.islnk(): + print("link to", tarinfo.linkname, end=' ') + print() + + def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): + """Add the file `name' to the archive. `name' may be any type of file + (directory, fifo, symbolic link, etc.). If given, `arcname' + specifies an alternative name for the file in the archive. + Directories are added recursively by default. This can be avoided by + setting `recursive' to False. `exclude' is a function that should + return True for each filename to be excluded. `filter' is a function + that expects a TarInfo object argument and returns the changed + TarInfo object, if it returns None the TarInfo object will be + excluded from the archive. + """ + self._check("aw") + + if arcname is None: + arcname = name + + # Exclude pathnames. + if exclude is not None: + import warnings + warnings.warn("use the filter argument instead", + DeprecationWarning, 2) + if exclude(name): + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Skip if somebody tries to archive the archive... + if self.name is not None and os.path.abspath(name) == self.name: + self._dbg(2, "tarfile: Skipped %r" % name) + return + + self._dbg(1, name) + + # Create a TarInfo object from the file. + tarinfo = self.gettarinfo(name, arcname) + + if tarinfo is None: + self._dbg(1, "tarfile: Unsupported type %r" % name) + return + + # Change or exclude the TarInfo object. + if filter is not None: + tarinfo = filter(tarinfo) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Append the tar header and data to the archive. + if tarinfo.isreg(): + f = bltn_open(name, "rb") + self.addfile(tarinfo, f) + f.close() + + elif tarinfo.isdir(): + self.addfile(tarinfo) + if recursive: + for f in os.listdir(name): + self.add(os.path.join(name, f), os.path.join(arcname, f), + recursive, exclude, filter=filter) + + else: + self.addfile(tarinfo) + + def addfile(self, tarinfo, fileobj=None): + """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is + given, tarinfo.size bytes are read from it and added to the archive. + You can create TarInfo objects using gettarinfo(). + On Windows platforms, `fileobj' should always be opened with mode + 'rb' to avoid irritation about the file size. + """ + self._check("aw") + + tarinfo = copy.copy(tarinfo) + + buf = tarinfo.tobuf(self.format, self.encoding, self.errors) + self.fileobj.write(buf) + self.offset += len(buf) + + # If there's data to follow, append it. + if fileobj is not None: + copyfileobj(fileobj, self.fileobj, tarinfo.size) + blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) + if remainder > 0: + self.fileobj.write(NUL * (BLOCKSIZE - remainder)) + blocks += 1 + self.offset += blocks * BLOCKSIZE + + self.members.append(tarinfo) + + def extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 0o700 + # Do not set_attrs directories, as we will do that further down + self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) + + # Reverse sort directories. + directories.sort(key=lambda a: a.name) + directories.reverse() + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extract(self, member, path="", set_attrs=True): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a TarInfo object. You can + specify a different directory using `path'. File attributes (owner, + mtime, mode) are set unless `set_attrs' is False. + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + # Prepare the link target for makelink(). + if tarinfo.islnk(): + tarinfo._link_target = os.path.join(path, tarinfo.linkname) + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name), + set_attrs=set_attrs) + except EnvironmentError as e: + if self.errorlevel > 0: + raise + else: + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) + else: + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extractfile(self, member): + """Extract a member from the archive as a file object. `member' may be + a filename or a TarInfo object. If `member' is a regular file, a + file-like object is returned. If `member' is a link, a file-like + object is constructed from the link's target. If `member' is none of + the above, None is returned. + The file-like object is read-only and provides the following + methods: read(), readline(), readlines(), seek() and tell() + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + if tarinfo.isreg(): + return self.fileobject(self, tarinfo) + + elif tarinfo.type not in SUPPORTED_TYPES: + # If a member's type is unknown, it is treated as a + # regular file. + return self.fileobject(self, tarinfo) + + elif tarinfo.islnk() or tarinfo.issym(): + if isinstance(self.fileobj, _Stream): + # A small but ugly workaround for the case that someone tries + # to extract a (sym)link as a file-object from a non-seekable + # stream of tar blocks. + raise StreamError("cannot extract (sym)link as file object") + else: + # A (sym)link's file object is its target's file object. + return self.extractfile(self._find_link_target(tarinfo)) + else: + # If there's no data associated with the member (directory, chrdev, + # blkdev, etc.), return None instead of a file object. + return None + + def _extract_member(self, tarinfo, targetpath, set_attrs=True): + """Extract the TarInfo object tarinfo to a physical + file called targetpath. + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing + # forward slashes to platform specific separators. + targetpath = targetpath.rstrip("/") + targetpath = targetpath.replace("/", os.sep) + + # Create all upper directories. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + # Create directories that are not part of the archive with + # default permissions. + os.makedirs(upperdirs) + + if tarinfo.islnk() or tarinfo.issym(): + self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) + else: + self._dbg(1, tarinfo.name) + + if tarinfo.isreg(): + self.makefile(tarinfo, targetpath) + elif tarinfo.isdir(): + self.makedir(tarinfo, targetpath) + elif tarinfo.isfifo(): + self.makefifo(tarinfo, targetpath) + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): + self.makelink(tarinfo, targetpath) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: + self.makefile(tarinfo, targetpath) + + if set_attrs: + self.chown(tarinfo, targetpath) + if not tarinfo.issym(): + self.chmod(tarinfo, targetpath) + self.utime(tarinfo, targetpath) + + #-------------------------------------------------------------------------- + # Below are the different file methods. They are called via + # _extract_member() when extract() is called. They can be replaced in a + # subclass to implement other functionality. + + def makedir(self, tarinfo, targetpath): + """Make a directory called targetpath. + """ + try: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0o700) + except EnvironmentError as e: + if e.errno != errno.EEXIST: + raise + + def makefile(self, tarinfo, targetpath): + """Make a file called targetpath. + """ + source = self.fileobj + source.seek(tarinfo.offset_data) + target = bltn_open(targetpath, "wb") + if tarinfo.sparse is not None: + for offset, size in tarinfo.sparse: + target.seek(offset) + copyfileobj(source, target, size) + else: + copyfileobj(source, target, tarinfo.size) + target.seek(tarinfo.size) + target.truncate() + target.close() + + def makeunknown(self, tarinfo, targetpath): + """Make a file from a TarInfo object with an unknown type + at targetpath. + """ + self.makefile(tarinfo, targetpath) + self._dbg(1, "tarfile: Unknown file type %r, " \ + "extracted as regular file." % tarinfo.type) + + def makefifo(self, tarinfo, targetpath): + """Make a fifo called targetpath. + """ + if hasattr(os, "mkfifo"): + os.mkfifo(targetpath) + else: + raise ExtractError("fifo not supported by system") + + def makedev(self, tarinfo, targetpath): + """Make a character or block device called targetpath. + """ + if not hasattr(os, "mknod") or not hasattr(os, "makedev"): + raise ExtractError("special devices not supported by system") + + mode = tarinfo.mode + if tarinfo.isblk(): + mode |= stat.S_IFBLK + else: + mode |= stat.S_IFCHR + + os.mknod(targetpath, mode, + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. + """ + try: + # For systems that support symbolic and hard links. + if tarinfo.issym(): + os.symlink(tarinfo.linkname, targetpath) + else: + # See extract(). + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except symlink_exception: + if tarinfo.issym(): + linkpath = os.path.join(os.path.dirname(tarinfo.name), + tarinfo.linkname) + else: + linkpath = tarinfo.linkname + else: + try: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") + + def chown(self, tarinfo, targetpath): + """Set owner of targetpath according to tarinfo. + """ + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError as e: + raise ExtractError("could not change owner") + + def chmod(self, tarinfo, targetpath): + """Set file permissions of targetpath according to tarinfo. + """ + if hasattr(os, 'chmod'): + try: + os.chmod(targetpath, tarinfo.mode) + except EnvironmentError as e: + raise ExtractError("could not change mode") + + def utime(self, tarinfo, targetpath): + """Set modification time of targetpath according to tarinfo. + """ + if not hasattr(os, 'utime'): + return + try: + os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + except EnvironmentError as e: + raise ExtractError("could not change modification time") + + #-------------------------------------------------------------------------- + def next(self): + """Return the next member of the archive as a TarInfo object, when + TarFile is opened for reading. Return None if there is no more + available. + """ + self._check("ra") + if self.firstmember is not None: + m = self.firstmember + self.firstmember = None + return m + + # Read the next block. + self.fileobj.seek(self.offset) + tarinfo = None + while True: + try: + tarinfo = self.tarinfo.fromtarfile(self) + except EOFHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + except InvalidHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError as e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError as e: + raise ReadError(str(e)) + break + + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + + return tarinfo + + #-------------------------------------------------------------------------- + # Little helper methods: + + def _getmember(self, name, tarinfo=None, normalize=False): + """Find an archive member by name from bottom to top. + If tarinfo is given, it is used as the starting point. + """ + # Ensure that all members have been loaded. + members = self.getmembers() + + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] + + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member + + def _load(self): + """Read through the entire archive file and look for readable + members. + """ + while True: + tarinfo = self.next() + if tarinfo is None: + break + self._loaded = True + + def _check(self, mode=None): + """Check if TarFile is still open, and if the operation's mode + corresponds to TarFile's mode. + """ + if self.closed: + raise IOError("%s is closed" % self.__class__.__name__) + if mode is not None and self.mode not in mode: + raise IOError("bad operation for mode %r" % self.mode) + + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + + def __iter__(self): + """Provide an iterator object. + """ + if self._loaded: + return iter(self.members) + else: + return TarIter(self) + + def _dbg(self, level, msg): + """Write debugging output to sys.stderr. + """ + if level <= self.debug: + print(msg, file=sys.stderr) + + def __enter__(self): + self._check() + return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + # An exception occurred. We must not call close() because + # it would try to write end-of-archive blocks and padding. + if not self._extfileobj: + self.fileobj.close() + self.closed = True +# class TarFile + +class TarIter(object): + """Iterator Class. + + for tarinfo in TarFile(...): + suite... + """ + + def __init__(self, tarfile): + """Construct a TarIter object. + """ + self.tarfile = tarfile + self.index = 0 + def __iter__(self): + """Return iterator object. + """ + return self + + def __next__(self): + """Return the next item using TarFile's next() method. + When all members have been read, set TarFile as _loaded. + """ + # Fix for SF #1100429: Under rare circumstances it can + # happen that getmembers() is called during iteration, + # which will cause TarIter to stop prematurely. + if not self.tarfile._loaded: + tarinfo = self.tarfile.next() + if not tarinfo: + self.tarfile._loaded = True + raise StopIteration + else: + try: + tarinfo = self.tarfile.members[self.index] + except IndexError: + raise StopIteration + self.index += 1 + return tarinfo + + next = __next__ # for Python 2.x + +#-------------------- +# exported functions +#-------------------- +def is_tarfile(name): + """Return True if name points to a tar archive that we + are able to handle, else return False. + """ + try: + t = open(name) + t.close() + return True + except TarError: + return False + +bltn_open = open +open = TarFile.open diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/compat.py new file mode 100644 index 0000000..ff328c8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/compat.py @@ -0,0 +1,1120 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import absolute_import + +import os +import re +import sys + +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +if sys.version_info[0] < 3: # pragma: no cover + from StringIO import StringIO + string_types = basestring, + text_type = unicode + from types import FileType as file_type + import __builtin__ as builtins + import ConfigParser as configparser + from ._backport import shutil + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit + from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, + pathname2url, ContentTooShortError, splittype) + + def quote(s): + if isinstance(s, unicode): + s = s.encode('utf-8') + return _quote(s) + + import urllib2 + from urllib2 import (Request, urlopen, URLError, HTTPError, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib2 import HTTPSHandler + import httplib + import xmlrpclib + import Queue as queue + from HTMLParser import HTMLParser + import htmlentitydefs + raw_input = raw_input + from itertools import ifilter as filter + from itertools import ifilterfalse as filterfalse + + _userprog = None + def splituser(host): + """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + global _userprog + if _userprog is None: + import re + _userprog = re.compile('^(.*)@(.*)$') + + match = _userprog.match(host) + if match: return match.group(1, 2) + return None, host + +else: # pragma: no cover + from io import StringIO + string_types = str, + text_type = str + from io import TextIOWrapper as file_type + import builtins + import configparser + import shutil + from urllib.parse import (urlparse, urlunparse, urljoin, splituser, quote, + unquote, urlsplit, urlunsplit, splittype) + from urllib.request import (urlopen, urlretrieve, Request, url2pathname, + pathname2url, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib.request import HTTPSHandler + from urllib.error import HTTPError, URLError, ContentTooShortError + import http.client as httplib + import urllib.request as urllib2 + import xmlrpc.client as xmlrpclib + import queue + from html.parser import HTMLParser + import html.entities as htmlentitydefs + raw_input = input + from itertools import filterfalse + filter = filter + +try: + from ssl import match_hostname, CertificateError +except ImportError: # pragma: no cover + class CertificateError(ValueError): + pass + + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + parts = dn.split('.') + leftmost, remainder = parts[0], parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +try: + from types import SimpleNamespace as Container +except ImportError: # pragma: no cover + class Container(object): + """ + A generic container for when multiple values need to be returned + """ + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +try: + from shutil import which +except ImportError: # pragma: no cover + # Implementation from Python 3.3 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None + + +# ZipFile is a context manager in 2.7, but not in 2.6 + +from zipfile import ZipFile as BaseZipFile + +if hasattr(BaseZipFile, '__enter__'): # pragma: no cover + ZipFile = BaseZipFile +else: # pragma: no cover + from zipfile import ZipExtFile as BaseZipExtFile + + class ZipExtFile(BaseZipExtFile): + def __init__(self, base): + self.__dict__.update(base.__dict__) + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + class ZipFile(BaseZipFile): + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + def open(self, *args, **kwargs): + base = BaseZipFile.open(self, *args, **kwargs) + return ZipExtFile(base) + +try: + from platform import python_implementation +except ImportError: # pragma: no cover + def python_implementation(): + """Return a string identifying the Python implementation.""" + if 'PyPy' in sys.version: + return 'PyPy' + if os.name == 'java': + return 'Jython' + if sys.version.startswith('IronPython'): + return 'IronPython' + return 'CPython' + +try: + import sysconfig +except ImportError: # pragma: no cover + from ._backport import sysconfig + +try: + callable = callable +except NameError: # pragma: no cover + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode + fsdecode = os.fsdecode +except AttributeError: # pragma: no cover + # Issue #99: on some systems (e.g. containerised), + # sys.getfilesystemencoding() returns None, and we need a real value, + # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and + # sys.getfilesystemencoding(): the return value is "the user’s preference + # according to the result of nl_langinfo(CODESET), or None if the + # nl_langinfo(CODESET) failed." + _fsencoding = sys.getfilesystemencoding() or 'utf-8' + if _fsencoding == 'mbcs': + _fserrors = 'strict' + else: + _fserrors = 'surrogateescape' + + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, text_type): + return filename.encode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + + def fsdecode(filename): + if isinstance(filename, text_type): + return filename + elif isinstance(filename, bytes): + return filename.decode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + +try: + from tokenize import detect_encoding +except ImportError: # pragma: no cover + from codecs import BOM_UTF8, lookup + import re + + cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") + + def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + + def detect_encoding(readline): + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, + but disagree, a SyntaxError will be raised. If the encoding cookie is an + invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + try: + filename = readline.__self__.name + except AttributeError: + filename = None + bom_found = False + encoding = None + default = 'utf-8' + def read_or_stop(): + try: + return readline() + except StopIteration: + return b'' + + def find_cookie(line): + try: + # Decode as UTF-8. Either the line is an encoding declaration, + # in which case it should be pure ASCII, or it must be UTF-8 + # per default encoding. + line_string = line.decode('utf-8') + except UnicodeDecodeError: + msg = "invalid or missing encoding declaration" + if filename is not None: + msg = '{} for {!r}'.format(msg, filename) + raise SyntaxError(msg) + + matches = cookie_re.findall(line_string) + if not matches: + return None + encoding = _get_normal_name(matches[0]) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + if filename is None: + msg = "unknown encoding: " + encoding + else: + msg = "unknown encoding for {!r}: {}".format(filename, + encoding) + raise SyntaxError(msg) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + if filename is None: + msg = 'encoding problem: utf-8' + else: + msg = 'encoding problem for {!r}: utf-8'.format(filename) + raise SyntaxError(msg) + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + +# For converting & <-> & etc. +try: + from html import escape +except ImportError: + from cgi import escape +if sys.version_info[:2] < (3, 4): + unescape = HTMLParser().unescape +else: + from html import unescape + +try: + from collections import ChainMap +except ImportError: # pragma: no cover + from collections import MutableMapping + + try: + from reprlib import recursive_repr as _recursive_repr + except ImportError: + def _recursive_repr(fillvalue='...'): + ''' + Decorator to make a repr function return fillvalue for a recursive + call + ''' + + def decorating_function(user_function): + repr_running = set() + + def wrapper(self): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + result = user_function(self) + finally: + repr_running.discard(key) + return result + + # Can't use functools.wraps() here because of bootstrap issues + wrapper.__module__ = getattr(user_function, '__module__') + wrapper.__doc__ = getattr(user_function, '__doc__') + wrapper.__name__ = getattr(user_function, '__name__') + wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + return wrapper + + return decorating_function + + class ChainMap(MutableMapping): + ''' A ChainMap groups multiple dicts (or other mappings) together + to create a single, updateable view. + + The underlying mappings are stored in a list. That list is public and can + accessed or updated using the *maps* attribute. There is no other state. + + Lookups search the underlying mappings successively until a key is found. + In contrast, writes, updates, and deletions only operate on the first + mapping. + + ''' + + def __init__(self, *maps): + '''Initialize a ChainMap by setting *maps* to the given mappings. + If no mappings are provided, a single empty dictionary is used. + + ''' + self.maps = list(maps) or [{}] # always at least one map + + def __missing__(self, key): + raise KeyError(key) + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] # can't use 'key in mapping' with defaultdict + except KeyError: + pass + return self.__missing__(key) # support subclasses that define __missing__ + + def get(self, key, default=None): + return self[key] if key in self else default + + def __len__(self): + return len(set().union(*self.maps)) # reuses stored hash values if possible + + def __iter__(self): + return iter(set().union(*self.maps)) + + def __contains__(self, key): + return any(key in m for m in self.maps) + + def __bool__(self): + return any(self.maps) + + @_recursive_repr() + def __repr__(self): + return '{0.__class__.__name__}({1})'.format( + self, ', '.join(map(repr, self.maps))) + + @classmethod + def fromkeys(cls, iterable, *args): + 'Create a ChainMap with a single dict created from the iterable.' + return cls(dict.fromkeys(iterable, *args)) + + def copy(self): + 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' + return self.__class__(self.maps[0].copy(), *self.maps[1:]) + + __copy__ = copy + + def new_child(self): # like Django's Context.push() + 'New ChainMap with a new dict followed by all previous maps.' + return self.__class__({}, *self.maps) + + @property + def parents(self): # like Django's Context.pop() + 'New ChainMap from maps[1:].' + return self.__class__(*self.maps[1:]) + + def __setitem__(self, key, value): + self.maps[0][key] = value + + def __delitem__(self, key): + try: + del self.maps[0][key] + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def popitem(self): + 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' + try: + return self.maps[0].popitem() + except KeyError: + raise KeyError('No keys found in the first mapping.') + + def pop(self, key, *args): + 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' + try: + return self.maps[0].pop(key, *args) + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def clear(self): + 'Clear maps[0], leaving maps[1:] intact.' + self.maps[0].clear() + +try: + from importlib.util import cache_from_source # Python >= 3.4 +except ImportError: # pragma: no cover + try: + from imp import cache_from_source + except ImportError: # pragma: no cover + def cache_from_source(path, debug_override=None): + assert path.endswith('.py') + if debug_override is None: + debug_override = __debug__ + if debug_override: + suffix = 'c' + else: + suffix = 'o' + return path + suffix + +try: + from collections import OrderedDict +except ImportError: # pragma: no cover +## {{{ http://code.activestate.com/recipes/576693/ (r9) +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + try: + from thread import get_ident as _get_ident + except ImportError: + from dummy_thread import get_ident as _get_ident + + try: + from _abcoll import KeysView, ValuesView, ItemsView + except ImportError: + pass + + + class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running=None): + 'od.__repr__() <==> repr(od)' + if not _repr_running: _repr_running = {} + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + +try: + from logging.config import BaseConfigurator, valid_ident +except ImportError: # pragma: no cover + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) + + + def valid_ident(s): + m = IDENTIFIER.match(s) + if not m: + raise ValueError('Not a valid Python identifier: %r' % s) + return True + + + # The ConvertingXXX classes are wrappers around standard Python containers, + # and they serve to convert any suitable values in the container. The + # conversion converts base dicts, lists and tuples to their wrapped + # equivalents, whereas strings which match a conversion format are converted + # appropriately. + # + # Each wrapper should have a configurator attribute holding the actual + # configurator to use for conversion. + + class ConvertingDict(dict): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def get(self, key, default=None): + value = dict.get(self, key, default) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class ConvertingList(list): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, idx=-1): + value = list.pop(self, idx) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + class ConvertingTuple(tuple): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$') + + WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') + DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') + INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + DIGIT_PATTERN = re.compile(r'^\d+$') + + value_converters = { + 'ext' : 'ext_convert', + 'cfg' : 'cfg_convert', + } + + # We might want to use a different one, e.g. importlib + importer = staticmethod(__import__) + + def __init__(self, config): + self.config = ConvertingDict(config) + self.config.configurator = self + + def resolve(self, s): + """ + Resolve strings to objects using standard import and attribute + syntax. + """ + name = s.split('.') + used = name.pop(0) + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v + + def ext_convert(self, value): + """Default converter for the ext:// protocol.""" + return self.resolve(value) + + def cfg_convert(self, value): + """Default converter for the cfg:// protocol.""" + rest = value + m = self.WORD_PATTERN.match(rest) + if m is None: + raise ValueError("Unable to convert %r" % value) + else: + rest = rest[m.end():] + d = self.config[m.groups()[0]] + #print d, rest + while rest: + m = self.DOT_PATTERN.match(rest) + if m: + d = d[m.groups()[0]] + else: + m = self.INDEX_PATTERN.match(rest) + if m: + idx = m.groups()[0] + if not self.DIGIT_PATTERN.match(idx): + d = d[idx] + else: + try: + n = int(idx) # try as number first (most likely) + d = d[n] + except TypeError: + d = d[idx] + if m: + rest = rest[m.end():] + else: + raise ValueError('Unable to convert ' + '%r at %r' % (value, rest)) + #rest should be empty + return d + + def convert(self, value): + """ + Convert values to an appropriate type. dicts, lists and tuples are + replaced by their converting alternatives. Strings are checked to + see if they have a conversion format and are converted if they do. + """ + if not isinstance(value, ConvertingDict) and isinstance(value, dict): + value = ConvertingDict(value) + value.configurator = self + elif not isinstance(value, ConvertingList) and isinstance(value, list): + value = ConvertingList(value) + value.configurator = self + elif not isinstance(value, ConvertingTuple) and\ + isinstance(value, tuple): + value = ConvertingTuple(value) + value.configurator = self + elif isinstance(value, string_types): + m = self.CONVERT_PATTERN.match(value) + if m: + d = m.groupdict() + prefix = d['prefix'] + converter = self.value_converters.get(prefix, None) + if converter: + suffix = d['suffix'] + converter = getattr(self, converter) + value = converter(suffix) + return value + + def configure_custom(self, config): + """Configure an object with a user-supplied factory.""" + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + result = c(**kwargs) + if props: + for name, value in props.items(): + setattr(result, name, value) + return result + + def as_tuple(self, value): + """Utility function which converts lists to tuples.""" + if isinstance(value, list): + value = tuple(value) + return value diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/database.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/database.py new file mode 100644 index 0000000..a19905e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/database.py @@ -0,0 +1,1336 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""PEP 376 implementation.""" + +from __future__ import unicode_literals + +import base64 +import codecs +import contextlib +import hashlib +import logging +import os +import posixpath +import sys +import zipimport + +from . import DistlibException, resources +from .compat import StringIO +from .version import get_scheme, UnsupportedVersionError +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (parse_requirement, cached_property, parse_name_and_version, + read_exports, write_exports, CSVReader, CSVWriter) + + +__all__ = ['Distribution', 'BaseInstalledDistribution', + 'InstalledDistribution', 'EggInfoDistribution', + 'DistributionPath'] + + +logger = logging.getLogger(__name__) + +EXPORTS_FILENAME = 'pydist-exports.json' +COMMANDS_FILENAME = 'pydist-commands.json' + +DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', + 'RESOURCES', EXPORTS_FILENAME, 'SHARED') + +DISTINFO_EXT = '.dist-info' + + +class _Cache(object): + """ + A simple cache mapping names and .dist-info paths to distributions + """ + def __init__(self): + """ + Initialise an instance. There is normally one for each DistributionPath. + """ + self.name = {} + self.path = {} + self.generated = False + + def clear(self): + """ + Clear the cache, setting it to its initial state. + """ + self.name.clear() + self.path.clear() + self.generated = False + + def add(self, dist): + """ + Add a distribution to the cache. + :param dist: The distribution to add. + """ + if dist.path not in self.path: + self.path[dist.path] = dist + self.name.setdefault(dist.key, []).append(dist) + + +class DistributionPath(object): + """ + Represents a set of distributions installed on a path (typically sys.path). + """ + def __init__(self, path=None, include_egg=False): + """ + Create an instance from a path, optionally including legacy (distutils/ + setuptools/distribute) distributions. + :param path: The path to use, as a list of directories. If not specified, + sys.path is used. + :param include_egg: If True, this instance will look for and return legacy + distributions as well as those based on PEP 376. + """ + if path is None: + path = sys.path + self.path = path + self._include_dist = True + self._include_egg = include_egg + + self._cache = _Cache() + self._cache_egg = _Cache() + self._cache_enabled = True + self._scheme = get_scheme('default') + + def _get_cache_enabled(self): + return self._cache_enabled + + def _set_cache_enabled(self, value): + self._cache_enabled = value + + cache_enabled = property(_get_cache_enabled, _set_cache_enabled) + + def clear_cache(self): + """ + Clears the internal cache. + """ + self._cache.clear() + self._cache_egg.clear() + + + def _yield_distributions(self): + """ + Yield .dist-info and/or .egg(-info) distributions. + """ + # We need to check if we've seen some resources already, because on + # some Linux systems (e.g. some Debian/Ubuntu variants) there are + # symlinks which alias other files in the environment. + seen = set() + for path in self.path: + finder = resources.finder_for_path(path) + if finder is None: + continue + r = finder.find('') + if not r or not r.is_container: + continue + rset = sorted(r.resources) + for entry in rset: + r = finder.find(entry) + if not r or r.path in seen: + continue + if self._include_dist and entry.endswith(DISTINFO_EXT): + possible_filenames = [METADATA_FILENAME, WHEEL_METADATA_FILENAME] + for metadata_filename in possible_filenames: + metadata_path = posixpath.join(entry, metadata_filename) + pydist = finder.find(metadata_path) + if pydist: + break + else: + continue + + with contextlib.closing(pydist.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + logger.debug('Found %s', r.path) + seen.add(r.path) + yield new_dist_class(r.path, metadata=metadata, + env=self) + elif self._include_egg and entry.endswith(('.egg-info', + '.egg')): + logger.debug('Found %s', r.path) + seen.add(r.path) + yield old_dist_class(r.path, self) + + def _generate_cache(self): + """ + Scan the path for distributions and populate the cache with + those that are found. + """ + gen_dist = not self._cache.generated + gen_egg = self._include_egg and not self._cache_egg.generated + if gen_dist or gen_egg: + for dist in self._yield_distributions(): + if isinstance(dist, InstalledDistribution): + self._cache.add(dist) + else: + self._cache_egg.add(dist) + + if gen_dist: + self._cache.generated = True + if gen_egg: + self._cache_egg.generated = True + + @classmethod + def distinfo_dirname(cls, name, version): + """ + The *name* and *version* parameters are converted into their + filename-escaped form, i.e. any ``'-'`` characters are replaced + with ``'_'`` other than the one in ``'dist-info'`` and the one + separating the name from the version number. + + :parameter name: is converted to a standard distribution name by replacing + any runs of non- alphanumeric characters with a single + ``'-'``. + :type name: string + :parameter version: is converted to a standard version string. Spaces + become dots, and all other non-alphanumeric characters + (except dots) become dashes, with runs of multiple + dashes condensed to a single dash. + :type version: string + :returns: directory name + :rtype: string""" + name = name.replace('-', '_') + return '-'.join([name, version]) + DISTINFO_EXT + + def get_distributions(self): + """ + Provides an iterator that looks for distributions and returns + :class:`InstalledDistribution` or + :class:`EggInfoDistribution` instances for each one of them. + + :rtype: iterator of :class:`InstalledDistribution` and + :class:`EggInfoDistribution` instances + """ + if not self._cache_enabled: + for dist in self._yield_distributions(): + yield dist + else: + self._generate_cache() + + for dist in self._cache.path.values(): + yield dist + + if self._include_egg: + for dist in self._cache_egg.path.values(): + yield dist + + def get_distribution(self, name): + """ + Looks for a named distribution on the path. + + This function only returns the first result found, as no more than one + value is expected. If nothing is found, ``None`` is returned. + + :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` + or ``None`` + """ + result = None + name = name.lower() + if not self._cache_enabled: + for dist in self._yield_distributions(): + if dist.key == name: + result = dist + break + else: + self._generate_cache() + + if name in self._cache.name: + result = self._cache.name[name][0] + elif self._include_egg and name in self._cache_egg.name: + result = self._cache_egg.name[name][0] + return result + + def provides_distribution(self, name, version=None): + """ + Iterates over all distributions to find which distributions provide *name*. + If a *version* is provided, it will be used to filter the results. + + This function only returns the first result found, since no more than + one values are expected. If the directory is not found, returns ``None``. + + :parameter version: a version specifier that indicates the version + required, conforming to the format in ``PEP-345`` + + :type name: string + :type version: string + """ + matcher = None + if version is not None: + try: + matcher = self._scheme.matcher('%s (%s)' % (name, version)) + except ValueError: + raise DistlibException('invalid name or version: %r, %r' % + (name, version)) + + for dist in self.get_distributions(): + # We hit a problem on Travis where enum34 was installed and doesn't + # have a provides attribute ... + if not hasattr(dist, 'provides'): + logger.debug('No "provides": %s', dist) + else: + provided = dist.provides + + for p in provided: + p_name, p_ver = parse_name_and_version(p) + if matcher is None: + if p_name == name: + yield dist + break + else: + if p_name == name and matcher.match(p_ver): + yield dist + break + + def get_file_path(self, name, relative_path): + """ + Return the path to a resource file. + """ + dist = self.get_distribution(name) + if dist is None: + raise LookupError('no distribution named %r found' % name) + return dist.get_resource_path(relative_path) + + def get_exported_entries(self, category, name=None): + """ + Return all of the exported entries in a particular category. + + :param category: The category to search for entries. + :param name: If specified, only entries with that name are returned. + """ + for dist in self.get_distributions(): + r = dist.exports + if category in r: + d = r[category] + if name is not None: + if name in d: + yield d[name] + else: + for v in d.values(): + yield v + + +class Distribution(object): + """ + A base class for distributions, whether installed or from indexes. + Either way, it must have some metadata, so that's all that's needed + for construction. + """ + + build_time_dependency = False + """ + Set to True if it's known to be only a build-time dependency (i.e. + not needed after installation). + """ + + requested = False + """A boolean that indicates whether the ``REQUESTED`` metadata file is + present (in other words, whether the package was installed by user + request or it was installed as a dependency).""" + + def __init__(self, metadata): + """ + Initialise an instance. + :param metadata: The instance of :class:`Metadata` describing this + distribution. + """ + self.metadata = metadata + self.name = metadata.name + self.key = self.name.lower() # for case-insensitive comparisons + self.version = metadata.version + self.locator = None + self.digest = None + self.extras = None # additional features requested + self.context = None # environment marker overrides + self.download_urls = set() + self.digests = {} + + @property + def source_url(self): + """ + The source archive download URL for this distribution. + """ + return self.metadata.source_url + + download_url = source_url # Backward compatibility + + @property + def name_and_version(self): + """ + A utility property which displays the name and version in parentheses. + """ + return '%s (%s)' % (self.name, self.version) + + @property + def provides(self): + """ + A set of distribution names and versions provided by this distribution. + :return: A set of "name (version)" strings. + """ + plist = self.metadata.provides + s = '%s (%s)' % (self.name, self.version) + if s not in plist: + plist.append(s) + return plist + + def _get_requirements(self, req_attr): + md = self.metadata + logger.debug('Getting requirements from metadata %r', md.todict()) + reqts = getattr(md, req_attr) + return set(md.get_requirements(reqts, extras=self.extras, + env=self.context)) + + @property + def run_requires(self): + return self._get_requirements('run_requires') + + @property + def meta_requires(self): + return self._get_requirements('meta_requires') + + @property + def build_requires(self): + return self._get_requirements('build_requires') + + @property + def test_requires(self): + return self._get_requirements('test_requires') + + @property + def dev_requires(self): + return self._get_requirements('dev_requires') + + def matches_requirement(self, req): + """ + Say if this instance matches (fulfills) a requirement. + :param req: The requirement to match. + :rtype req: str + :return: True if it matches, else False. + """ + # Requirement may contain extras - parse to lose those + # from what's passed to the matcher + r = parse_requirement(req) + scheme = get_scheme(self.metadata.scheme) + try: + matcher = scheme.matcher(r.requirement) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + result = False + for p in self.provides: + p_name, p_ver = parse_name_and_version(p) + if p_name != name: + continue + try: + result = matcher.match(p_ver) + break + except UnsupportedVersionError: + pass + return result + + def __repr__(self): + """ + Return a textual representation of this instance, + """ + if self.source_url: + suffix = ' [%s]' % self.source_url + else: + suffix = '' + return '<Distribution %s (%s)%s>' % (self.name, self.version, suffix) + + def __eq__(self, other): + """ + See if this distribution is the same as another. + :param other: The distribution to compare with. To be equal to one + another. distributions must have the same type, name, + version and source_url. + :return: True if it is the same, else False. + """ + if type(other) is not type(self): + result = False + else: + result = (self.name == other.name and + self.version == other.version and + self.source_url == other.source_url) + return result + + def __hash__(self): + """ + Compute hash in a way which matches the equality test. + """ + return hash(self.name) + hash(self.version) + hash(self.source_url) + + +class BaseInstalledDistribution(Distribution): + """ + This is the base class for installed distributions (whether PEP 376 or + legacy). + """ + + hasher = None + + def __init__(self, metadata, path, env=None): + """ + Initialise an instance. + :param metadata: An instance of :class:`Metadata` which describes the + distribution. This will normally have been initialised + from a metadata file in the ``path``. + :param path: The path of the ``.dist-info`` or ``.egg-info`` + directory for the distribution. + :param env: This is normally the :class:`DistributionPath` + instance where this distribution was found. + """ + super(BaseInstalledDistribution, self).__init__(metadata) + self.path = path + self.dist_path = env + + def get_hash(self, data, hasher=None): + """ + Get the hash of some data, using a particular hash algorithm, if + specified. + + :param data: The data to be hashed. + :type data: bytes + :param hasher: The name of a hash implementation, supported by hashlib, + or ``None``. Examples of valid values are ``'sha1'``, + ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and + ``'sha512'``. If no hasher is specified, the ``hasher`` + attribute of the :class:`InstalledDistribution` instance + is used. If the hasher is determined to be ``None``, MD5 + is used as the hashing algorithm. + :returns: The hash of the data. If a hasher was explicitly specified, + the returned hash will be prefixed with the specified hasher + followed by '='. + :rtype: str + """ + if hasher is None: + hasher = self.hasher + if hasher is None: + hasher = hashlib.md5 + prefix = '' + else: + hasher = getattr(hashlib, hasher) + prefix = '%s=' % self.hasher + digest = hasher(data).digest() + digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') + return '%s%s' % (prefix, digest) + + +class InstalledDistribution(BaseInstalledDistribution): + """ + Created with the *path* of the ``.dist-info`` directory provided to the + constructor. It reads the metadata contained in ``pydist.json`` when it is + instantiated., or uses a passed in Metadata instance (useful for when + dry-run mode is being used). + """ + + hasher = 'sha256' + + def __init__(self, path, metadata=None, env=None): + self.modules = [] + self.finder = finder = resources.finder_for_path(path) + if finder is None: + raise ValueError('finder unavailable for %s' % path) + if env and env._cache_enabled and path in env._cache.path: + metadata = env._cache.path[path].metadata + elif metadata is None: + r = finder.find(METADATA_FILENAME) + # Temporary - for Wheel 0.23 support + if r is None: + r = finder.find(WHEEL_METADATA_FILENAME) + # Temporary - for legacy support + if r is None: + r = finder.find('METADATA') + if r is None: + raise ValueError('no %s found in %s' % (METADATA_FILENAME, + path)) + with contextlib.closing(r.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + + super(InstalledDistribution, self).__init__(metadata, path, env) + + if env and env._cache_enabled: + env._cache.add(self) + + r = finder.find('REQUESTED') + self.requested = r is not None + p = os.path.join(path, 'top_level.txt') + if os.path.exists(p): + with open(p, 'rb') as f: + data = f.read() + self.modules = data.splitlines() + + def __repr__(self): + return '<InstalledDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def _get_records(self): + """ + Get the list of installed files for the distribution + :return: A list of tuples of path, hash and size. Note that hash and + size might be ``None`` for some entries. The path is exactly + as stored in the file (which is as in PEP 376). + """ + results = [] + r = self.get_distinfo_resource('RECORD') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as record_reader: + # Base location is parent dir of .dist-info dir + #base_location = os.path.dirname(self.path) + #base_location = os.path.abspath(base_location) + for row in record_reader: + missing = [None for i in range(len(row), 3)] + path, checksum, size = row + missing + #if not os.path.isabs(path): + # path = path.replace('/', os.sep) + # path = os.path.join(base_location, path) + results.append((path, checksum, size)) + return results + + @cached_property + def exports(self): + """ + Return the information exported by this distribution. + :return: A dictionary of exports, mapping an export category to a dict + of :class:`ExportEntry` instances describing the individual + export entries, and keyed by name. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + result = self.read_exports() + return result + + def read_exports(self): + """ + Read exports data from a file in .ini format. + + :return: A dictionary of exports, mapping an export category to a list + of :class:`ExportEntry` instances describing the individual + export entries. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + with contextlib.closing(r.as_stream()) as stream: + result = read_exports(stream) + return result + + def write_exports(self, exports): + """ + Write a dictionary of exports to a file in .ini format. + :param exports: A dictionary of exports, mapping an export category to + a list of :class:`ExportEntry` instances describing the + individual export entries. + """ + rf = self.get_distinfo_file(EXPORTS_FILENAME) + with open(rf, 'w') as f: + write_exports(exports, f) + + def get_resource_path(self, relative_path): + """ + NOTE: This API may change in the future. + + Return the absolute path to a resource file with the given relative + path. + + :param relative_path: The path, relative to .dist-info, of the resource + of interest. + :return: The absolute path where the resource is to be found. + """ + r = self.get_distinfo_resource('RESOURCES') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as resources_reader: + for relative, destination in resources_reader: + if relative == relative_path: + return destination + raise KeyError('no resource file with relative path %r ' + 'is installed' % relative_path) + + def list_installed_files(self): + """ + Iterates over the ``RECORD`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: iterator of (path, hash, size) + """ + for result in self._get_records(): + yield result + + def write_installed_files(self, paths, prefix, dry_run=False): + """ + Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any + existing ``RECORD`` file is silently overwritten. + + prefix is used to determine when to write absolute paths. + """ + prefix = os.path.join(prefix, '') + base = os.path.dirname(self.path) + base_under_prefix = base.startswith(prefix) + base = os.path.join(base, '') + record_path = self.get_distinfo_file('RECORD') + logger.info('creating %s', record_path) + if dry_run: + return None + with CSVWriter(record_path) as writer: + for path in paths: + if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): + # do not put size and hash, as in PEP-376 + hash_value = size = '' + else: + size = '%d' % os.path.getsize(path) + with open(path, 'rb') as fp: + hash_value = self.get_hash(fp.read()) + if path.startswith(base) or (base_under_prefix and + path.startswith(prefix)): + path = os.path.relpath(path, base) + writer.writerow((path, hash_value, size)) + + # add the RECORD file itself + if record_path.startswith(base): + record_path = os.path.relpath(record_path, base) + writer.writerow((record_path, '', '')) + return record_path + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + base = os.path.dirname(self.path) + record_path = self.get_distinfo_file('RECORD') + for path, hash_value, size in self.list_installed_files(): + if not os.path.isabs(path): + path = os.path.join(base, path) + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + elif os.path.isfile(path): + actual_size = str(os.path.getsize(path)) + if size and actual_size != size: + mismatches.append((path, 'size', size, actual_size)) + elif hash_value: + if '=' in hash_value: + hasher = hash_value.split('=', 1)[0] + else: + hasher = None + + with open(path, 'rb') as f: + actual_hash = self.get_hash(f.read(), hasher) + if actual_hash != hash_value: + mismatches.append((path, 'hash', hash_value, actual_hash)) + return mismatches + + @cached_property + def shared_locations(self): + """ + A dictionary of shared locations whose keys are in the set 'prefix', + 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. + The corresponding value is the absolute path of that category for + this distribution, and takes into account any paths selected by the + user at installation time (e.g. via command-line arguments). In the + case of the 'namespace' key, this would be a list of absolute paths + for the roots of namespace packages in this distribution. + + The first time this property is accessed, the relevant information is + read from the SHARED file in the .dist-info directory. + """ + result = {} + shared_path = os.path.join(self.path, 'SHARED') + if os.path.isfile(shared_path): + with codecs.open(shared_path, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + for line in lines: + key, value = line.split('=', 1) + if key == 'namespace': + result.setdefault(key, []).append(value) + else: + result[key] = value + return result + + def write_shared_locations(self, paths, dry_run=False): + """ + Write shared location information to the SHARED file in .dist-info. + :param paths: A dictionary as described in the documentation for + :meth:`shared_locations`. + :param dry_run: If True, the action is logged but no file is actually + written. + :return: The path of the file written to. + """ + shared_path = os.path.join(self.path, 'SHARED') + logger.info('creating %s', shared_path) + if dry_run: + return None + lines = [] + for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): + path = paths[key] + if os.path.isdir(paths[key]): + lines.append('%s=%s' % (key, path)) + for ns in paths.get('namespace', ()): + lines.append('namespace=%s' % ns) + + with codecs.open(shared_path, 'w', encoding='utf-8') as f: + f.write('\n'.join(lines)) + return shared_path + + def get_distinfo_resource(self, path): + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + finder = resources.finder_for_path(self.path) + if finder is None: + raise DistlibException('Unable to get a finder for %s' % self.path) + return finder.find(path) + + def get_distinfo_file(self, path): + """ + Returns a path located under the ``.dist-info`` directory. Returns a + string representing the path. + + :parameter path: a ``'/'``-separated path relative to the + ``.dist-info`` directory or an absolute path; + If *path* is an absolute path and doesn't start + with the ``.dist-info`` directory path, + a :class:`DistlibException` is raised + :type path: str + :rtype: str + """ + # Check if it is an absolute path # XXX use relpath, add tests + if path.find(os.sep) >= 0: + # it's an absolute path? + distinfo_dirname, path = path.split(os.sep)[-2:] + if distinfo_dirname != self.path.split(os.sep)[-1]: + raise DistlibException( + 'dist-info file %r does not belong to the %r %s ' + 'distribution' % (path, self.name, self.version)) + + # The file must be relative + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + + return os.path.join(self.path, path) + + def list_distinfo_files(self): + """ + Iterates over the ``RECORD`` entries and returns paths for each line if + the path is pointing to a file located in the ``.dist-info`` directory + or one of its subdirectories. + + :returns: iterator of paths + """ + base = os.path.dirname(self.path) + for path, checksum, size in self._get_records(): + # XXX add separator or use real relpath algo + if not os.path.isabs(path): + path = os.path.join(base, path) + if path.startswith(self.path): + yield path + + def __eq__(self, other): + return (isinstance(other, InstalledDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + + +class EggInfoDistribution(BaseInstalledDistribution): + """Created with the *path* of the ``.egg-info`` directory or file provided + to the constructor. It reads the metadata contained in the file itself, or + if the given path happens to be a directory, the metadata is read from the + file ``PKG-INFO`` under that directory.""" + + requested = True # as we have no way of knowing, assume it was + shared_locations = {} + + def __init__(self, path, env=None): + def set_name_and_version(s, n, v): + s.name = n + s.key = n.lower() # for case-insensitive comparisons + s.version = v + + self.path = path + self.dist_path = env + if env and env._cache_enabled and path in env._cache_egg.path: + metadata = env._cache_egg.path[path].metadata + set_name_and_version(self, metadata.name, metadata.version) + else: + metadata = self._get_metadata(path) + + # Need to be set before caching + set_name_and_version(self, metadata.name, metadata.version) + + if env and env._cache_enabled: + env._cache_egg.add(self) + super(EggInfoDistribution, self).__init__(metadata, path, env) + + def _get_metadata(self, path): + requires = None + + def parse_requires_data(data): + """Create a list of dependencies from a requires.txt file. + + *data*: the contents of a setuptools-produced requires.txt file. + """ + reqs = [] + lines = data.splitlines() + for line in lines: + line = line.strip() + if line.startswith('['): + logger.warning('Unexpected line: quitting requirement scan: %r', + line) + break + r = parse_requirement(line) + if not r: + logger.warning('Not recognised as a requirement: %r', line) + continue + if r.extras: + logger.warning('extra requirements in requires.txt are ' + 'not supported') + if not r.constraints: + reqs.append(r.name) + else: + cons = ', '.join('%s%s' % c for c in r.constraints) + reqs.append('%s (%s)' % (r.name, cons)) + return reqs + + def parse_requires_path(req_path): + """Create a list of dependencies from a requires.txt file. + + *req_path*: the path to a setuptools-produced requires.txt file. + """ + + reqs = [] + try: + with codecs.open(req_path, 'r', 'utf-8') as fp: + reqs = parse_requires_data(fp.read()) + except IOError: + pass + return reqs + + tl_path = tl_data = None + if path.endswith('.egg'): + if os.path.isdir(path): + p = os.path.join(path, 'EGG-INFO') + meta_path = os.path.join(p, 'PKG-INFO') + metadata = Metadata(path=meta_path, scheme='legacy') + req_path = os.path.join(p, 'requires.txt') + tl_path = os.path.join(p, 'top_level.txt') + requires = parse_requires_path(req_path) + else: + # FIXME handle the case where zipfile is not available + zipf = zipimport.zipimporter(path) + fileobj = StringIO( + zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) + metadata = Metadata(fileobj=fileobj, scheme='legacy') + try: + data = zipf.get_data('EGG-INFO/requires.txt') + tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') + requires = parse_requires_data(data.decode('utf-8')) + except IOError: + requires = None + elif path.endswith('.egg-info'): + if os.path.isdir(path): + req_path = os.path.join(path, 'requires.txt') + requires = parse_requires_path(req_path) + path = os.path.join(path, 'PKG-INFO') + tl_path = os.path.join(path, 'top_level.txt') + metadata = Metadata(path=path, scheme='legacy') + else: + raise DistlibException('path must end with .egg-info or .egg, ' + 'got %r' % path) + + if requires: + metadata.add_requirements(requires) + # look for top-level modules in top_level.txt, if present + if tl_data is None: + if tl_path is not None and os.path.exists(tl_path): + with open(tl_path, 'rb') as f: + tl_data = f.read().decode('utf-8') + if not tl_data: + tl_data = [] + else: + tl_data = tl_data.splitlines() + self.modules = tl_data + return metadata + + def __repr__(self): + return '<EggInfoDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + for path, _, _ in self.list_installed_files(): + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + return mismatches + + def list_installed_files(self): + """ + Iterates over the ``installed-files.txt`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: a list of (path, hash, size) + """ + + def _md5(path): + f = open(path, 'rb') + try: + content = f.read() + finally: + f.close() + return hashlib.md5(content).hexdigest() + + def _size(path): + return os.stat(path).st_size + + record_path = os.path.join(self.path, 'installed-files.txt') + result = [] + if os.path.exists(record_path): + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + p = os.path.normpath(os.path.join(self.path, line)) + # "./" is present as a marker between installed files + # and installation metadata files + if not os.path.exists(p): + logger.warning('Non-existent file: %s', p) + if p.endswith(('.pyc', '.pyo')): + continue + #otherwise fall through and fail + if not os.path.isdir(p): + result.append((p, _md5(p), _size(p))) + result.append((record_path, None, None)) + return result + + def list_distinfo_files(self, absolute=False): + """ + Iterates over the ``installed-files.txt`` entries and returns paths for + each line if the path is pointing to a file located in the + ``.egg-info`` directory or one of its subdirectories. + + :parameter absolute: If *absolute* is ``True``, each returned path is + transformed into a local absolute path. Otherwise the + raw value from ``installed-files.txt`` is returned. + :type absolute: boolean + :returns: iterator of paths + """ + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + skip = True + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line == './': + skip = False + continue + if not skip: + p = os.path.normpath(os.path.join(self.path, line)) + if p.startswith(self.path): + if absolute: + yield p + else: + yield line + + def __eq__(self, other): + return (isinstance(other, EggInfoDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + +new_dist_class = InstalledDistribution +old_dist_class = EggInfoDistribution + + +class DependencyGraph(object): + """ + Represents a dependency graph between distributions. + + The dependency relationships are stored in an ``adjacency_list`` that maps + distributions to a list of ``(other, label)`` tuples where ``other`` + is a distribution and the edge is labeled with ``label`` (i.e. the version + specifier, if such was provided). Also, for more efficient traversal, for + every distribution ``x``, a list of predecessors is kept in + ``reverse_list[x]``. An edge from distribution ``a`` to + distribution ``b`` means that ``a`` depends on ``b``. If any missing + dependencies are found, they are stored in ``missing``, which is a + dictionary that maps distributions to a list of requirements that were not + provided by any other distributions. + """ + + def __init__(self): + self.adjacency_list = {} + self.reverse_list = {} + self.missing = {} + + def add_distribution(self, distribution): + """Add the *distribution* to the graph. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + """ + self.adjacency_list[distribution] = [] + self.reverse_list[distribution] = [] + #self.missing[distribution] = [] + + def add_edge(self, x, y, label=None): + """Add an edge from distribution *x* to distribution *y* with the given + *label*. + + :type x: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type y: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type label: ``str`` or ``None`` + """ + self.adjacency_list[x].append((y, label)) + # multiple edges are allowed, so be careful + if x not in self.reverse_list[y]: + self.reverse_list[y].append(x) + + def add_missing(self, distribution, requirement): + """ + Add a missing *requirement* for the given *distribution*. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + :type requirement: ``str`` + """ + logger.debug('%s missing %r', distribution, requirement) + self.missing.setdefault(distribution, []).append(requirement) + + def _repr_dist(self, dist): + return '%s %s' % (dist.name, dist.version) + + def repr_node(self, dist, level=1): + """Prints only a subgraph""" + output = [self._repr_dist(dist)] + for other, label in self.adjacency_list[dist]: + dist = self._repr_dist(other) + if label is not None: + dist = '%s [%s]' % (dist, label) + output.append(' ' * level + str(dist)) + suboutput = self.repr_node(other, level + 1) + subs = suboutput.split('\n') + output.extend(subs[1:]) + return '\n'.join(output) + + def to_dot(self, f, skip_disconnected=True): + """Writes a DOT output for the graph to the provided file *f*. + + If *skip_disconnected* is set to ``True``, then all distributions + that are not dependent on any other distribution are skipped. + + :type f: has to support ``file``-like operations + :type skip_disconnected: ``bool`` + """ + disconnected = [] + + f.write("digraph dependencies {\n") + for dist, adjs in self.adjacency_list.items(): + if len(adjs) == 0 and not skip_disconnected: + disconnected.append(dist) + for other, label in adjs: + if not label is None: + f.write('"%s" -> "%s" [label="%s"]\n' % + (dist.name, other.name, label)) + else: + f.write('"%s" -> "%s"\n' % (dist.name, other.name)) + if not skip_disconnected and len(disconnected) > 0: + f.write('subgraph disconnected {\n') + f.write('label = "Disconnected"\n') + f.write('bgcolor = red\n') + + for dist in disconnected: + f.write('"%s"' % dist.name) + f.write('\n') + f.write('}\n') + f.write('}\n') + + def topological_sort(self): + """ + Perform a topological sort of the graph. + :return: A tuple, the first element of which is a topologically sorted + list of distributions, and the second element of which is a + list of distributions that cannot be sorted because they have + circular dependencies and so form a cycle. + """ + result = [] + # Make a shallow copy of the adjacency list + alist = {} + for k, v in self.adjacency_list.items(): + alist[k] = v[:] + while True: + # See what we can remove in this run + to_remove = [] + for k, v in list(alist.items())[:]: + if not v: + to_remove.append(k) + del alist[k] + if not to_remove: + # What's left in alist (if anything) is a cycle. + break + # Remove from the adjacency list of others + for k, v in alist.items(): + alist[k] = [(d, r) for d, r in v if d not in to_remove] + logger.debug('Moving to result: %s', + ['%s (%s)' % (d.name, d.version) for d in to_remove]) + result.extend(to_remove) + return result, list(alist.keys()) + + def __repr__(self): + """Representation of the graph""" + output = [] + for dist, adjs in self.adjacency_list.items(): + output.append(self.repr_node(dist)) + return '\n'.join(output) + + +def make_graph(dists, scheme='default'): + """Makes a dependency graph from the given distributions. + + :parameter dists: a list of distributions + :type dists: list of :class:`distutils2.database.InstalledDistribution` and + :class:`distutils2.database.EggInfoDistribution` instances + :rtype: a :class:`DependencyGraph` instance + """ + scheme = get_scheme(scheme) + graph = DependencyGraph() + provided = {} # maps names to lists of (version, dist) tuples + + # first, build the graph and find out what's provided + for dist in dists: + graph.add_distribution(dist) + + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + provided.setdefault(name, []).append((version, dist)) + + # now make the edges + for dist in dists: + requires = (dist.run_requires | dist.meta_requires | + dist.build_requires | dist.dev_requires) + for req in requires: + try: + matcher = scheme.matcher(req) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + matched = False + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + graph.add_edge(dist, provider, req) + matched = True + break + if not matched: + graph.add_missing(dist, req) + return graph + + +def get_dependent_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + dependent on *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + dep = [dist] # dependent distributions + todo = graph.reverse_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop() + dep.append(d) + for succ in graph.reverse_list[d]: + if succ not in dep: + todo.append(succ) + + dep.pop(0) # remove dist from dep, was there to prevent infinite loops + return dep + + +def get_required_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + required by *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + req = [] # required distributions + todo = graph.adjacency_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop()[0] + req.append(d) + for pred in graph.adjacency_list[d]: + if pred not in req: + todo.append(pred) + + return req + + +def make_dist(name, version, **kwargs): + """ + A convenience method for making a dist given just a name and version. + """ + summary = kwargs.pop('summary', 'Placeholder for summary') + md = Metadata(**kwargs) + md.name = name + md.version = version + md.summary = summary or 'Placeholder for summary' + return Distribution(md) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/index.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/index.py new file mode 100644 index 0000000..2406be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/index.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import hashlib +import logging +import os +import shutil +import subprocess +import tempfile +try: + from threading import Thread +except ImportError: + from dummy_threading import Thread + +from . import DistlibException +from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, + urlparse, build_opener, string_types) +from .util import cached_property, zip_dir, ServerProxy + +logger = logging.getLogger(__name__) + +DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_REALM = 'pypi' + +class PackageIndex(object): + """ + This class represents a package index compatible with PyPI, the Python + Package Index. + """ + + boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' + + def __init__(self, url=None): + """ + Initialise an instance. + + :param url: The URL of the index. If not specified, the URL for PyPI is + used. + """ + self.url = url or DEFAULT_INDEX + self.read_configuration() + scheme, netloc, path, params, query, frag = urlparse(self.url) + if params or query or frag or scheme not in ('http', 'https'): + raise DistlibException('invalid repository: %s' % self.url) + self.password_handler = None + self.ssl_verifier = None + self.gpg = None + self.gpg_home = None + with open(os.devnull, 'w') as sink: + # Use gpg by default rather than gpg2, as gpg2 insists on + # prompting for passwords + for s in ('gpg', 'gpg2'): + try: + rc = subprocess.check_call([s, '--version'], stdout=sink, + stderr=sink) + if rc == 0: + self.gpg = s + break + except OSError: + pass + + def _get_pypirc_command(self): + """ + Get the distutils command for interacting with PyPI configurations. + :return: the command. + """ + from distutils.core import Distribution + from distutils.config import PyPIRCCommand + d = Distribution() + return PyPIRCCommand(d) + + def read_configuration(self): + """ + Read the PyPI access configuration as supported by distutils, getting + PyPI to do the actual work. This populates ``username``, ``password``, + ``realm`` and ``url`` attributes from the configuration. + """ + # get distutils to do the work + c = self._get_pypirc_command() + c.repository = self.url + cfg = c._read_pypirc() + self.username = cfg.get('username') + self.password = cfg.get('password') + self.realm = cfg.get('realm', 'pypi') + self.url = cfg.get('repository', self.url) + + def save_configuration(self): + """ + Save the PyPI access configuration. You must have set ``username`` and + ``password`` attributes before calling this method. + + Again, distutils is used to do the actual work. + """ + self.check_credentials() + # get distutils to do the work + c = self._get_pypirc_command() + c._store_pypirc(self.username, self.password) + + def check_credentials(self): + """ + Check that ``username`` and ``password`` have been set, and raise an + exception if not. + """ + if self.username is None or self.password is None: + raise DistlibException('username and password must be set') + pm = HTTPPasswordMgr() + _, netloc, _, _, _, _ = urlparse(self.url) + pm.add_password(self.realm, netloc, self.username, self.password) + self.password_handler = HTTPBasicAuthHandler(pm) + + def register(self, metadata): + """ + Register a distribution on PyPI, using the provided metadata. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the distribution to be + registered. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + metadata.validate() + d = metadata.todict() + d[':action'] = 'verify' + request = self.encode_request(d.items(), []) + response = self.send_request(request) + d[':action'] = 'submit' + request = self.encode_request(d.items(), []) + return self.send_request(request) + + def _reader(self, name, stream, outbuf): + """ + Thread runner for reading lines of from a subprocess into a buffer. + + :param name: The logical name of the stream (used for logging only). + :param stream: The stream to read from. This will typically a pipe + connected to the output stream of a subprocess. + :param outbuf: The list to append the read lines to. + """ + while True: + s = stream.readline() + if not s: + break + s = s.decode('utf-8').rstrip() + outbuf.append(s) + logger.debug('%s: %s' % (name, s)) + stream.close() + + def get_sign_command(self, filename, signer, sign_password, + keystore=None): + """ + Return a suitable command for signing a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The signing command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + if sign_password is not None: + cmd.extend(['--batch', '--passphrase-fd', '0']) + td = tempfile.mkdtemp() + sf = os.path.join(td, os.path.basename(filename) + '.asc') + cmd.extend(['--detach-sign', '--armor', '--local-user', + signer, '--output', sf, filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd, sf + + def run_command(self, cmd, input_data=None): + """ + Run a command in a child process , passing it any input data specified. + + :param cmd: The command to run. + :param input_data: If specified, this must be a byte string containing + data to be sent to the child process. + :return: A tuple consisting of the subprocess' exit code, a list of + lines read from the subprocess' ``stdout``, and a list of + lines read from the subprocess' ``stderr``. + """ + kwargs = { + 'stdout': subprocess.PIPE, + 'stderr': subprocess.PIPE, + } + if input_data is not None: + kwargs['stdin'] = subprocess.PIPE + stdout = [] + stderr = [] + p = subprocess.Popen(cmd, **kwargs) + # We don't use communicate() here because we may need to + # get clever with interacting with the command + t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) + t1.start() + t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) + t2.start() + if input_data is not None: + p.stdin.write(input_data) + p.stdin.close() + + p.wait() + t1.join() + t2.join() + return p.returncode, stdout, stderr + + def sign_file(self, filename, signer, sign_password, keystore=None): + """ + Sign a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The absolute pathname of the file where the signature is + stored. + """ + cmd, sig_file = self.get_sign_command(filename, signer, sign_password, + keystore) + rc, stdout, stderr = self.run_command(cmd, + sign_password.encode('utf-8')) + if rc != 0: + raise DistlibException('sign command failed with error ' + 'code %s' % rc) + return sig_file + + def upload_file(self, metadata, filename, signer=None, sign_password=None, + filetype='sdist', pyversion='source', keystore=None): + """ + Upload a release file to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the file to be uploaded. + :param filename: The pathname of the file to be uploaded. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param filetype: The type of the file being uploaded. This is the + distutils command which produced that file, e.g. + ``sdist`` or ``bdist_wheel``. + :param pyversion: The version of Python which the release relates + to. For code compatible with any Python, this would + be ``source``, otherwise it would be e.g. ``3.2``. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.exists(filename): + raise DistlibException('not found: %s' % filename) + metadata.validate() + d = metadata.todict() + sig_file = None + if signer: + if not self.gpg: + logger.warning('no signing program available - not signed') + else: + sig_file = self.sign_file(filename, signer, sign_password, + keystore) + with open(filename, 'rb') as f: + file_data = f.read() + md5_digest = hashlib.md5(file_data).hexdigest() + sha256_digest = hashlib.sha256(file_data).hexdigest() + d.update({ + ':action': 'file_upload', + 'protocol_version': '1', + 'filetype': filetype, + 'pyversion': pyversion, + 'md5_digest': md5_digest, + 'sha256_digest': sha256_digest, + }) + files = [('content', os.path.basename(filename), file_data)] + if sig_file: + with open(sig_file, 'rb') as f: + sig_data = f.read() + files.append(('gpg_signature', os.path.basename(sig_file), + sig_data)) + shutil.rmtree(os.path.dirname(sig_file)) + request = self.encode_request(d.items(), files) + return self.send_request(request) + + def upload_documentation(self, metadata, doc_dir): + """ + Upload documentation to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the documentation to be + uploaded. + :param doc_dir: The pathname of the directory which contains the + documentation. This should be the directory that + contains the ``index.html`` for the documentation. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.isdir(doc_dir): + raise DistlibException('not a directory: %r' % doc_dir) + fn = os.path.join(doc_dir, 'index.html') + if not os.path.exists(fn): + raise DistlibException('not found: %r' % fn) + metadata.validate() + name, version = metadata.name, metadata.version + zip_data = zip_dir(doc_dir).getvalue() + fields = [(':action', 'doc_upload'), + ('name', name), ('version', version)] + files = [('content', name, zip_data)] + request = self.encode_request(fields, files) + return self.send_request(request) + + def get_verify_command(self, signature_filename, data_filename, + keystore=None): + """ + Return a suitable command for verifying a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The verifying command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + cmd.extend(['--verify', signature_filename, data_filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd + + def verify_signature(self, signature_filename, data_filename, + keystore=None): + """ + Verify a signature for a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: True if the signature was verified, else False. + """ + if not self.gpg: + raise DistlibException('verification unavailable because gpg ' + 'unavailable') + cmd = self.get_verify_command(signature_filename, data_filename, + keystore) + rc, stdout, stderr = self.run_command(cmd) + if rc not in (0, 1): + raise DistlibException('verify command failed with error ' + 'code %s' % rc) + return rc == 0 + + def download_file(self, url, destfile, digest=None, reporthook=None): + """ + This is a convenience method for downloading a file from an URL. + Normally, this will be a file from the index, though currently + no check is made for this (i.e. a file can be downloaded from + anywhere). + + The method is just like the :func:`urlretrieve` function in the + standard library, except that it allows digest computation to be + done during download and checking that the downloaded data + matched any expected value. + + :param url: The URL of the file to be downloaded (assumed to be + available via an HTTP GET request). + :param destfile: The pathname where the downloaded file is to be + saved. + :param digest: If specified, this must be a (hasher, value) + tuple, where hasher is the algorithm used (e.g. + ``'md5'``) and ``value`` is the expected value. + :param reporthook: The same as for :func:`urlretrieve` in the + standard library. + """ + if digest is None: + digester = None + logger.debug('No digest specified') + else: + if isinstance(digest, (list, tuple)): + hasher, digest = digest + else: + hasher = 'md5' + digester = getattr(hashlib, hasher)() + logger.debug('Digest specified: %s' % digest) + # The following code is equivalent to urlretrieve. + # We need to do it this way so that we can compute the + # digest of the file as we go. + with open(destfile, 'wb') as dfp: + # addinfourl is not a context manager on 2.x + # so we have to use try/finally + sfp = self.send_request(Request(url)) + try: + headers = sfp.info() + blocksize = 8192 + size = -1 + read = 0 + blocknum = 0 + if "content-length" in headers: + size = int(headers["Content-Length"]) + if reporthook: + reporthook(blocknum, blocksize, size) + while True: + block = sfp.read(blocksize) + if not block: + break + read += len(block) + dfp.write(block) + if digester: + digester.update(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, blocksize, size) + finally: + sfp.close() + + # check that we got the whole file, if we can + if size >= 0 and read < size: + raise DistlibException( + 'retrieval incomplete: got only %d out of %d bytes' + % (read, size)) + # if we have a digest, it must match. + if digester: + actual = digester.hexdigest() + if digest != actual: + raise DistlibException('%s digest mismatch for %s: expected ' + '%s, got %s' % (hasher, destfile, + digest, actual)) + logger.debug('Digest verified: %s', digest) + + def send_request(self, req): + """ + Send a standard library :class:`Request` to PyPI and return its + response. + + :param req: The request to send. + :return: The HTTP response from PyPI (a standard library HTTPResponse). + """ + handlers = [] + if self.password_handler: + handlers.append(self.password_handler) + if self.ssl_verifier: + handlers.append(self.ssl_verifier) + opener = build_opener(*handlers) + return opener.open(req) + + def encode_request(self, fields, files): + """ + Encode fields and files for posting to an HTTP server. + + :param fields: The fields to send as a list of (fieldname, value) + tuples. + :param files: The files to send as a list of (fieldname, filename, + file_bytes) tuple. + """ + # Adapted from packaging, which in turn was adapted from + # http://code.activestate.com/recipes/146306 + + parts = [] + boundary = self.boundary + for k, values in fields: + if not isinstance(values, (list, tuple)): + values = [values] + + for v in values: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"' % + k).encode('utf-8'), + b'', + v.encode('utf-8'))) + for key, filename, value in files: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)).encode('utf-8'), + b'', + value)) + + parts.extend((b'--' + boundary + b'--', b'')) + + body = b'\r\n'.join(parts) + ct = b'multipart/form-data; boundary=' + boundary + headers = { + 'Content-type': ct, + 'Content-length': str(len(body)) + } + return Request(self.url, body, headers) + + def search(self, terms, operator=None): + if isinstance(terms, string_types): + terms = {'name': terms} + rpc_proxy = ServerProxy(self.url, timeout=3.0) + try: + return rpc_proxy.search(terms, operator or 'and') + finally: + rpc_proxy('close')() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/locators.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/locators.py new file mode 100644 index 0000000..11d2636 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/locators.py @@ -0,0 +1,1292 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# + +import gzip +from io import BytesIO +import json +import logging +import os +import posixpath +import re +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import zlib + +from . import DistlibException +from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, + queue, quote, unescape, string_types, build_opener, + HTTPRedirectHandler as BaseRedirectHandler, text_type, + Request, HTTPError, URLError) +from .database import Distribution, DistributionPath, make_dist +from .metadata import Metadata, MetadataInvalidError +from .util import (cached_property, parse_credentials, ensure_slash, + split_filename, get_project_data, parse_requirement, + parse_name_and_version, ServerProxy, normalize_name) +from .version import get_scheme, UnsupportedVersionError +from .wheel import Wheel, is_compatible + +logger = logging.getLogger(__name__) + +HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') +CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) +HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +DEFAULT_INDEX = 'https://pypi.python.org/pypi' + +def get_all_distribution_names(url=None): + """ + Return all distribution names known by an index. + :param url: The URL of the index. + :return: A list of all known distribution names. + """ + if url is None: + url = DEFAULT_INDEX + client = ServerProxy(url, timeout=3.0) + try: + return client.list_packages() + finally: + client('close')() + +class RedirectHandler(BaseRedirectHandler): + """ + A class to work around a bug in some Python 3.2.x releases. + """ + # There's a bug in the base version for some 3.2.x + # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header + # returns e.g. /abc, it bails because it says the scheme '' + # is bogus, when actually it should use the request's + # URL for the scheme. See Python issue #13696. + def http_error_302(self, req, fp, code, msg, headers): + # Some servers (incorrectly) return multiple Location headers + # (so probably same goes for URI). Use first header. + newurl = None + for key in ('location', 'uri'): + if key in headers: + newurl = headers[key] + break + if newurl is None: # pragma: no cover + return + urlparts = urlparse(newurl) + if urlparts.scheme == '': + newurl = urljoin(req.get_full_url(), newurl) + if hasattr(headers, 'replace_header'): + headers.replace_header(key, newurl) + else: + headers[key] = newurl + return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, + headers) + + http_error_301 = http_error_303 = http_error_307 = http_error_302 + +class Locator(object): + """ + A base class for locators - things that locate distributions. + """ + source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') + binary_extensions = ('.egg', '.exe', '.whl') + excluded_extensions = ('.pdf',) + + # A list of tags indicating which wheels you want to match. The default + # value of None matches against the tags compatible with the running + # Python. If you want to match other values, set wheel_tags on a locator + # instance to a list of tuples (pyver, abi, arch) which you want to match. + wheel_tags = None + + downloadable_extensions = source_extensions + ('.whl',) + + def __init__(self, scheme='default'): + """ + Initialise an instance. + :param scheme: Because locators look for most recent versions, they + need to know the version scheme to use. This specifies + the current PEP-recommended scheme - use ``'legacy'`` + if you need to support existing distributions on PyPI. + """ + self._cache = {} + self.scheme = scheme + # Because of bugs in some of the handlers on some of the platforms, + # we use our own opener rather than just using urlopen. + self.opener = build_opener(RedirectHandler()) + # If get_project() is called from locate(), the matcher instance + # is set from the requirement passed to locate(). See issue #18 for + # why this can be useful to know. + self.matcher = None + self.errors = queue.Queue() + + def get_errors(self): + """ + Return any errors which have occurred. + """ + result = [] + while not self.errors.empty(): # pragma: no cover + try: + e = self.errors.get(False) + result.append(e) + except self.errors.Empty: + continue + self.errors.task_done() + return result + + def clear_errors(self): + """ + Clear any errors which may have been logged. + """ + # Just get the errors and throw them away + self.get_errors() + + def clear_cache(self): + self._cache.clear() + + def _get_scheme(self): + return self._scheme + + def _set_scheme(self, value): + self._scheme = value + + scheme = property(_get_scheme, _set_scheme) + + def _get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This should be implemented in subclasses. + + If called from a locate() request, self.matcher will be set to a + matcher for the requirement to satisfy, otherwise it will be None. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This calls _get_project to do all the work, and just implements a caching layer on top. + """ + if self._cache is None: # pragma: no cover + result = self._get_project(name) + elif name in self._cache: + result = self._cache[name] + else: + self.clear_errors() + result = self._get_project(name) + self._cache[name] = result + return result + + def score_url(self, url): + """ + Give an url a score which can be used to choose preferred URLs + for a given project release. + """ + t = urlparse(url) + basename = posixpath.basename(t.path) + compatible = True + is_wheel = basename.endswith('.whl') + is_downloadable = basename.endswith(self.downloadable_extensions) + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) + return (t.scheme == 'https', 'pypi.python.org' in t.netloc, + is_downloadable, is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): + """ + Choose one of two URLs where both are candidates for distribution + archives for the same version of a distribution (for example, + .tar.gz vs. zip). + + The current implementation favours https:// URLs over http://, archives + from PyPI over those from other locations, wheel compatibility (if a + wheel) and then the archive name. + """ + result = url2 + if url1: + s1 = self.score_url(url1) + s2 = self.score_url(url2) + if s1 > s2: + result = url1 + if result != url2: + logger.debug('Not replacing %r with %r', url1, url2) + else: + logger.debug('Replacing %r with %r', url1, url2) + return result + + def split_filename(self, filename, project_name): + """ + Attempt to split a filename in project name, version and Python version. + """ + return split_filename(filename, project_name) + + def convert_url_to_download_info(self, url, project_name): + """ + See if a URL is a candidate for a download URL for a project (the URL + has typically been scraped from an HTML page). + + If it is, a dictionary is returned with keys "name", "version", + "filename" and "url"; otherwise, None is returned. + """ + def same_project(name1, name2): + return normalize_name(name1) == normalize_name(name2) + + result = None + scheme, netloc, path, params, query, frag = urlparse(url) + if frag.lower().startswith('egg='): # pragma: no cover + logger.debug('%s: version hint in fragment: %r', + project_name, frag) + m = HASHER_HASH.match(frag) + if m: + algo, digest = m.groups() + else: + algo, digest = None, None + origpath = path + if path and path[-1] == '/': # pragma: no cover + path = path[:-1] + if path.endswith('.whl'): + try: + wheel = Wheel(path) + if is_compatible(wheel, self.wheel_tags): + if project_name is None: + include = True + else: + include = same_project(wheel.name, project_name) + if include: + result = { + 'name': wheel.name, + 'version': wheel.version, + 'filename': wheel.filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + 'python-version': ', '.join( + ['.'.join(list(v[2:])) for v in wheel.pyver]), + } + except Exception as e: # pragma: no cover + logger.warning('invalid path for wheel: %s', path) + elif not path.endswith(self.downloadable_extensions): # pragma: no cover + logger.debug('Not downloadable: %s', path) + else: # downloadable extension + path = filename = posixpath.basename(path) + for ext in self.downloadable_extensions: + if path.endswith(ext): + path = path[:-len(ext)] + t = self.split_filename(path, project_name) + if not t: # pragma: no cover + logger.debug('No match for project/version: %s', path) + else: + name, version, pyver = t + if not project_name or same_project(project_name, name): + result = { + 'name': name, + 'version': version, + 'filename': filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + #'packagetype': 'sdist', + } + if pyver: # pragma: no cover + result['python-version'] = pyver + break + if result and algo: + result['%s_digest' % algo] = digest + return result + + def _get_digest(self, info): + """ + Get a digest from a dictionary by looking at keys of the form + 'algo_digest'. + + Returns a 2-tuple (algo, digest) if found, else None. Currently + looks only for SHA256, then MD5. + """ + result = None + for algo in ('sha256', 'md5'): + key = '%s_digest' % algo + if key in info: + result = (algo, info[key]) + break + return result + + def _update_version_data(self, result, info): + """ + Update a result dictionary (the final result from _get_project) with a + dictionary for a specific version, which typically holds information + gleaned from a filename or URL for an archive for the distribution. + """ + name = info.pop('name') + version = info.pop('version') + if version in result: + dist = result[version] + md = dist.metadata + else: + dist = make_dist(name, version, scheme=self.scheme) + md = dist.metadata + dist.digest = digest = self._get_digest(info) + url = info['url'] + result['digests'][url] = digest + if md.source_url != info['url']: + md.source_url = self.prefer_url(md.source_url, url) + result['urls'].setdefault(version, set()).add(url) + dist.locator = self + result[version] = dist + + def locate(self, requirement, prereleases=False): + """ + Find the most recent distribution which matches the given + requirement. + + :param requirement: A requirement of the form 'foo (1.0)' or perhaps + 'foo (>= 1.0, < 2.0, != 1.3)' + :param prereleases: If ``True``, allow pre-release versions + to be located. Otherwise, pre-release versions + are not returned. + :return: A :class:`Distribution` instance, or ``None`` if no such + distribution could be located. + """ + result = None + r = parse_requirement(requirement) + if r is None: # pragma: no cover + raise DistlibException('Not a valid requirement: %r' % requirement) + scheme = get_scheme(self.scheme) + self.matcher = matcher = scheme.matcher(r.requirement) + logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) + versions = self.get_project(r.name) + if len(versions) > 2: # urls and digests keys are present + # sometimes, versions are invalid + slist = [] + vcls = matcher.version_class + for k in versions: + if k in ('urls', 'digests'): + continue + try: + if not matcher.match(k): + logger.debug('%s did not match %r', matcher, k) + else: + if prereleases or not vcls(k).is_prerelease: + slist.append(k) + else: + logger.debug('skipping pre-release ' + 'version %s of %s', k, matcher.name) + except Exception: # pragma: no cover + logger.warning('error matching %s with %r', matcher, k) + pass # slist.append(k) + if len(slist) > 1: + slist = sorted(slist, key=scheme.key) + if slist: + logger.debug('sorted list: %s', slist) + version = slist[-1] + result = versions[version] + if result: + if r.extras: + result.extras = r.extras + result.download_urls = versions.get('urls', {}).get(version, set()) + d = {} + sd = versions.get('digests', {}) + for url in result.download_urls: + if url in sd: # pragma: no cover + d[url] = sd[url] + result.digests = d + self.matcher = None + return result + + +class PyPIRPCLocator(Locator): + """ + This locator uses XML-RPC to locate distributions. It therefore + cannot be used with simple mirrors (that only mirror file content). + """ + def __init__(self, url, **kwargs): + """ + Initialise an instance. + + :param url: The URL to use for XML-RPC. + :param kwargs: Passed to the superclass constructor. + """ + super(PyPIRPCLocator, self).__init__(**kwargs) + self.base_url = url + self.client = ServerProxy(url, timeout=3.0) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + return set(self.client.list_packages()) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + versions = self.client.package_releases(name, True) + for v in versions: + urls = self.client.release_urls(name, v) + data = self.client.release_data(name, v) + metadata = Metadata(scheme=self.scheme) + metadata.name = data['name'] + metadata.version = data['version'] + metadata.license = data.get('license') + metadata.keywords = data.get('keywords', []) + metadata.summary = data.get('summary') + dist = Distribution(metadata) + if urls: + info = urls[0] + metadata.source_url = info['url'] + dist.digest = self._get_digest(info) + dist.locator = self + result[v] = dist + for info in urls: + url = info['url'] + digest = self._get_digest(info) + result['urls'].setdefault(v, set()).add(url) + result['digests'][url] = digest + return result + +class PyPIJSONLocator(Locator): + """ + This locator uses PyPI's JSON interface. It's very limited in functionality + and probably not worth using. + """ + def __init__(self, url, **kwargs): + super(PyPIJSONLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + url = urljoin(self.base_url, '%s/json' % quote(name)) + try: + resp = self.opener.open(url) + data = resp.read().decode() # for now + d = json.loads(data) + md = Metadata(scheme=self.scheme) + data = d['info'] + md.name = data['name'] + md.version = data['version'] + md.license = data.get('license') + md.keywords = data.get('keywords', []) + md.summary = data.get('summary') + dist = Distribution(md) + dist.locator = self + urls = d['urls'] + result[md.version] = dist + for info in d['urls']: + url = info['url'] + dist.download_urls.add(url) + dist.digests[url] = self._get_digest(info) + result['urls'].setdefault(md.version, set()).add(url) + result['digests'][url] = self._get_digest(info) + # Now get other releases + for version, infos in d['releases'].items(): + if version == md.version: + continue # already done + omd = Metadata(scheme=self.scheme) + omd.name = md.name + omd.version = version + odist = Distribution(omd) + odist.locator = self + result[version] = odist + for info in infos: + url = info['url'] + odist.download_urls.add(url) + odist.digests[url] = self._get_digest(info) + result['urls'].setdefault(version, set()).add(url) + result['digests'][url] = self._get_digest(info) +# for info in urls: +# md.source_url = info['url'] +# dist.digest = self._get_digest(info) +# dist.locator = self +# for info in urls: +# url = info['url'] +# result['urls'].setdefault(md.version, set()).add(url) +# result['digests'][url] = self._get_digest(info) + except Exception as e: + self.errors.put(text_type(e)) + logger.exception('JSON fetch failed: %s', e) + return result + + +class Page(object): + """ + This class represents a scraped HTML page. + """ + # The following slightly hairy-looking regex just looks for the contents of + # an anchor link, which has an attribute "href" either immediately preceded + # or immediately followed by a "rel" attribute. The attribute values can be + # declared with double quotes, single quotes or no quotes - which leads to + # the length of the expression. + _href = re.compile(""" +(rel\\s*=\\s*(?:"(?P<rel1>[^"]*)"|'(?P<rel2>[^']*)'|(?P<rel3>[^>\\s\n]*))\\s+)? +href\\s*=\\s*(?:"(?P<url1>[^"]*)"|'(?P<url2>[^']*)'|(?P<url3>[^>\\s\n]*)) +(\\s+rel\\s*=\\s*(?:"(?P<rel4>[^"]*)"|'(?P<rel5>[^']*)'|(?P<rel6>[^>\\s\n]*)))? +""", re.I | re.S | re.X) + _base = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I | re.S) + + def __init__(self, data, url): + """ + Initialise an instance with the Unicode page contents and the URL they + came from. + """ + self.data = data + self.base_url = self.url = url + m = self._base.search(self.data) + if m: + self.base_url = m.group(1) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + @cached_property + def links(self): + """ + Return the URLs of all the links on a page together with information + about their "rel" attribute, for determining which ones to treat as + downloads and which ones to queue for further scraping. + """ + def clean(url): + "Tidy up an URL." + scheme, netloc, path, params, query, frag = urlparse(url) + return urlunparse((scheme, netloc, quote(path), + params, query, frag)) + + result = set() + for match in self._href.finditer(self.data): + d = match.groupdict('') + rel = (d['rel1'] or d['rel2'] or d['rel3'] or + d['rel4'] or d['rel5'] or d['rel6']) + url = d['url1'] or d['url2'] or d['url3'] + url = urljoin(self.base_url, url) + url = unescape(url) + url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) + result.add((url, rel)) + # We sort the result, hoping to bring the most recent versions + # to the front + result = sorted(result, key=lambda t: t[0], reverse=True) + return result + + +class SimpleScrapingLocator(Locator): + """ + A locator which scrapes HTML pages to locate downloads for a distribution. + This runs multiple threads to do the I/O; performance is at least as good + as pip's PackageFinder, which works in an analogous fashion. + """ + + # These are used to deal with various Content-Encoding schemes. + decoders = { + 'deflate': zlib.decompress, + 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(d)).read(), + 'none': lambda b: b, + } + + def __init__(self, url, timeout=None, num_workers=10, **kwargs): + """ + Initialise an instance. + :param url: The root URL to use for scraping. + :param timeout: The timeout, in seconds, to be applied to requests. + This defaults to ``None`` (no timeout specified). + :param num_workers: The number of worker threads you want to do I/O, + This defaults to 10. + :param kwargs: Passed to the superclass. + """ + super(SimpleScrapingLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + self.timeout = timeout + self._page_cache = {} + self._seen = set() + self._to_fetch = queue.Queue() + self._bad_hosts = set() + self.skip_externals = False + self.num_workers = num_workers + self._lock = threading.RLock() + # See issue #45: we need to be resilient when the locator is used + # in a thread, e.g. with concurrent.futures. We can't use self._lock + # as it is for coordinating our internal threads - the ones created + # in _prepare_threads. + self._gplock = threading.RLock() + + def _prepare_threads(self): + """ + Threads are created only when get_project is called, and terminate + before it returns. They are there primarily to parallelise I/O (i.e. + fetching web pages). + """ + self._threads = [] + for i in range(self.num_workers): + t = threading.Thread(target=self._fetch) + t.setDaemon(True) + t.start() + self._threads.append(t) + + def _wait_threads(self): + """ + Tell all the threads to terminate (by sending a sentinel value) and + wait for them to do so. + """ + # Note that you need two loops, since you can't say which + # thread will get each sentinel + for t in self._threads: + self._to_fetch.put(None) # sentinel + for t in self._threads: + t.join() + self._threads = [] + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + with self._gplock: + self.result = result + self.project_name = name + url = urljoin(self.base_url, '%s/' % quote(name)) + self._seen.clear() + self._page_cache.clear() + self._prepare_threads() + try: + logger.debug('Queueing %s', url) + self._to_fetch.put(url) + self._to_fetch.join() + finally: + self._wait_threads() + del self.result + return result + + platform_dependent = re.compile(r'\b(linux-(i\d86|x86_64|arm\w+)|' + r'win(32|-amd64)|macosx-?\d+)\b', re.I) + + def _is_platform_dependent(self, url): + """ + Does an URL refer to a platform-specific download? + """ + return self.platform_dependent.search(url) + + def _process_download(self, url): + """ + See if an URL is a suitable download for a project. + + If it is, register information in the result dictionary (for + _get_project) about the specific version it's for. + + Note that the return value isn't actually used other than as a boolean + value. + """ + if self._is_platform_dependent(url): + info = None + else: + info = self.convert_url_to_download_info(url, self.project_name) + logger.debug('process_download: %s -> %s', url, info) + if info: + with self._lock: # needed because self.result is shared + self._update_version_data(self.result, info) + return info + + def _should_queue(self, link, referrer, rel): + """ + Determine whether a link URL from a referring page and with a + particular "rel" attribute should be queued for scraping. + """ + scheme, netloc, path, _, _, _ = urlparse(link) + if path.endswith(self.source_extensions + self.binary_extensions + + self.excluded_extensions): + result = False + elif self.skip_externals and not link.startswith(self.base_url): + result = False + elif not referrer.startswith(self.base_url): + result = False + elif rel not in ('homepage', 'download'): + result = False + elif scheme not in ('http', 'https', 'ftp'): + result = False + elif self._is_platform_dependent(link): + result = False + else: + host = netloc.split(':', 1)[0] + if host.lower() == 'localhost': + result = False + else: + result = True + logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, + referrer, result) + return result + + def _fetch(self): + """ + Get a URL to fetch from the work queue, get the HTML page, examine its + links for download candidates and candidates for further scraping. + + This is a handy method to run in a thread. + """ + while True: + url = self._to_fetch.get() + try: + if url: + page = self.get_page(url) + if page is None: # e.g. after an error + continue + for link, rel in page.links: + if link not in self._seen: + try: + self._seen.add(link) + if (not self._process_download(link) and + self._should_queue(link, url, rel)): + logger.debug('Queueing %s from %s', link, url) + self._to_fetch.put(link) + except MetadataInvalidError: # e.g. invalid versions + pass + except Exception as e: # pragma: no cover + self.errors.put(text_type(e)) + finally: + # always do this, to avoid hangs :-) + self._to_fetch.task_done() + if not url: + #logger.debug('Sentinel seen, quitting.') + break + + def get_page(self, url): + """ + Get the HTML for an URL, possibly from an in-memory cache. + + XXX TODO Note: this cache is never actually cleared. It's assumed that + the data won't get stale over the lifetime of a locator instance (not + necessarily true for the default_locator). + """ + # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api + scheme, netloc, path, _, _, _ = urlparse(url) + if scheme == 'file' and os.path.isdir(url2pathname(path)): + url = urljoin(ensure_slash(url), 'index.html') + + if url in self._page_cache: + result = self._page_cache[url] + logger.debug('Returning %s from cache: %s', url, result) + else: + host = netloc.split(':', 1)[0] + result = None + if host in self._bad_hosts: + logger.debug('Skipping %s due to bad host %s', url, host) + else: + req = Request(url, headers={'Accept-encoding': 'identity'}) + try: + logger.debug('Fetching %s', url) + resp = self.opener.open(req, timeout=self.timeout) + logger.debug('Fetched %s', url) + headers = resp.info() + content_type = headers.get('Content-Type', '') + if HTML_CONTENT_TYPE.match(content_type): + final_url = resp.geturl() + data = resp.read() + encoding = headers.get('Content-Encoding') + if encoding: + decoder = self.decoders[encoding] # fail if not found + data = decoder(data) + encoding = 'utf-8' + m = CHARSET.search(content_type) + if m: + encoding = m.group(1) + try: + data = data.decode(encoding) + except UnicodeError: # pragma: no cover + data = data.decode('latin-1') # fallback + result = Page(data, final_url) + self._page_cache[final_url] = result + except HTTPError as e: + if e.code != 404: + logger.exception('Fetch failed: %s: %s', url, e) + except URLError as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + with self._lock: + self._bad_hosts.add(host) + except Exception as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + finally: + self._page_cache[url] = result # even if None (failure) + return result + + _distname_re = re.compile('<a href=[^>]*>([^<]+)<') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + page = self.get_page(self.base_url) + if not page: + raise DistlibException('Unable to get %s' % self.base_url) + for match in self._distname_re.finditer(page.data): + result.add(match.group(1)) + return result + +class DirectoryLocator(Locator): + """ + This class locates distributions in a directory tree. + """ + + def __init__(self, path, **kwargs): + """ + Initialise an instance. + :param path: The root of the directory tree to search. + :param kwargs: Passed to the superclass constructor, + except for: + * recursive - if True (the default), subdirectories are + recursed into. If False, only the top-level directory + is searched, + """ + self.recursive = kwargs.pop('recursive', True) + super(DirectoryLocator, self).__init__(**kwargs) + path = os.path.abspath(path) + if not os.path.isdir(path): # pragma: no cover + raise DistlibException('Not a directory: %r' % path) + self.base_dir = path + + def should_include(self, filename, parent): + """ + Should a filename be considered as a candidate for a distribution + archive? As well as the filename, the directory which contains it + is provided, though not used by the current implementation. + """ + return filename.endswith(self.downloadable_extensions) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, name) + if info: + self._update_version_data(result, info) + if not self.recursive: + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, None) + if info: + result.add(info['name']) + if not self.recursive: + break + return result + +class JSONLocator(Locator): + """ + This locator uses special extended metadata (not available on PyPI) and is + the basis of performant dependency resolution in distlib. Other locators + require archive downloads before dependencies can be determined! As you + might imagine, that can be slow. + """ + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + data = get_project_data(name) + if data: + for info in data.get('files', []): + if info['ptype'] != 'sdist' or info['pyversion'] != 'source': + continue + # We don't store summary in project metadata as it makes + # the data bigger for no benefit during dependency + # resolution + dist = make_dist(data['name'], info['version'], + summary=data.get('summary', + 'Placeholder for summary'), + scheme=self.scheme) + md = dist.metadata + md.source_url = info['url'] + # TODO SHA256 digest + if 'digest' in info and info['digest']: + dist.digest = ('md5', info['digest']) + md.dependencies = info.get('requirements', {}) + dist.exports = info.get('exports', {}) + result[dist.version] = dist + result['urls'].setdefault(dist.version, set()).add(info['url']) + return result + +class DistPathLocator(Locator): + """ + This locator finds installed distributions in a path. It can be useful for + adding to an :class:`AggregatingLocator`. + """ + def __init__(self, distpath, **kwargs): + """ + Initialise an instance. + + :param distpath: A :class:`DistributionPath` instance to search. + """ + super(DistPathLocator, self).__init__(**kwargs) + assert isinstance(distpath, DistributionPath) + self.distpath = distpath + + def _get_project(self, name): + dist = self.distpath.get_distribution(name) + if dist is None: + result = {'urls': {}, 'digests': {}} + else: + result = { + dist.version: dist, + 'urls': {dist.version: set([dist.source_url])}, + 'digests': {dist.version: set([None])} + } + return result + + +class AggregatingLocator(Locator): + """ + This class allows you to chain and/or merge a list of locators. + """ + def __init__(self, *locators, **kwargs): + """ + Initialise an instance. + + :param locators: The list of locators to search. + :param kwargs: Passed to the superclass constructor, + except for: + * merge - if False (the default), the first successful + search from any of the locators is returned. If True, + the results from all locators are merged (this can be + slow). + """ + self.merge = kwargs.pop('merge', False) + self.locators = locators + super(AggregatingLocator, self).__init__(**kwargs) + + def clear_cache(self): + super(AggregatingLocator, self).clear_cache() + for locator in self.locators: + locator.clear_cache() + + def _set_scheme(self, value): + self._scheme = value + for locator in self.locators: + locator.scheme = value + + scheme = property(Locator.scheme.fget, _set_scheme) + + def _get_project(self, name): + result = {} + for locator in self.locators: + d = locator.get_project(name) + if d: + if self.merge: + files = result.get('urls', {}) + digests = result.get('digests', {}) + # next line could overwrite result['urls'], result['digests'] + result.update(d) + df = result.get('urls') + if files and df: + for k, v in files.items(): + if k in df: + df[k] |= v + else: + df[k] = v + dd = result.get('digests') + if digests and dd: + dd.update(digests) + else: + # See issue #18. If any dists are found and we're looking + # for specific constraints, we only return something if + # a match is found. For example, if a DirectoryLocator + # returns just foo (1.0) while we're looking for + # foo (>= 2.0), we'll pretend there was nothing there so + # that subsequent locators can be queried. Otherwise we + # would just return foo (1.0) which would then lead to a + # failure to find foo (>= 2.0), because other locators + # weren't searched. Note that this only matters when + # merge=False. + if self.matcher is None: + found = True + else: + found = False + for k in d: + if self.matcher.match(k): + found = True + break + if found: + result = d + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for locator in self.locators: + try: + result |= locator.get_distribution_names() + except NotImplementedError: + pass + return result + + +# We use a legacy scheme simply because most of the dists on PyPI use legacy +# versions which don't conform to PEP 426 / PEP 440. +default_locator = AggregatingLocator( + JSONLocator(), + SimpleScrapingLocator('https://pypi.python.org/simple/', + timeout=3.0), + scheme='legacy') + +locate = default_locator.locate + +NAME_VERSION_RE = re.compile(r'(?P<name>[\w-]+)\s*' + r'\(\s*(==\s*)?(?P<ver>[^)]+)\)$') + +class DependencyFinder(object): + """ + Locate dependencies for distributions. + """ + + def __init__(self, locator=None): + """ + Initialise an instance, using the specified locator + to locate distributions. + """ + self.locator = locator or default_locator + self.scheme = get_scheme(self.locator.scheme) + + def add_distribution(self, dist): + """ + Add a distribution to the finder. This will update internal information + about who provides what. + :param dist: The distribution to add. + """ + logger.debug('adding distribution %s', dist) + name = dist.key + self.dists_by_name[name] = dist + self.dists[(name, dist.version)] = dist + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + self.provided.setdefault(name, set()).add((version, dist)) + + def remove_distribution(self, dist): + """ + Remove a distribution from the finder. This will update internal + information about who provides what. + :param dist: The distribution to remove. + """ + logger.debug('removing distribution %s', dist) + name = dist.key + del self.dists_by_name[name] + del self.dists[(name, dist.version)] + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Remove from provided: %s, %s, %s', name, version, dist) + s = self.provided[name] + s.remove((version, dist)) + if not s: + del self.provided[name] + + def get_matcher(self, reqt): + """ + Get a version matcher for a requirement. + :param reqt: The requirement + :type reqt: str + :return: A version matcher (an instance of + :class:`distlib.version.Matcher`). + """ + try: + matcher = self.scheme.matcher(reqt) + except UnsupportedVersionError: # pragma: no cover + # XXX compat-mode if cannot read the version + name = reqt.split()[0] + matcher = self.scheme.matcher(name) + return matcher + + def find_providers(self, reqt): + """ + Find the distributions which can fulfill a requirement. + + :param reqt: The requirement. + :type reqt: str + :return: A set of distribution which can fulfill the requirement. + """ + matcher = self.get_matcher(reqt) + name = matcher.key # case-insensitive + result = set() + provided = self.provided + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + result.add(provider) + break + return result + + def try_to_replace(self, provider, other, problems): + """ + Attempt to replace one provider with another. This is typically used + when resolving dependencies from multiple sources, e.g. A requires + (B >= 1.0) while C requires (B >= 1.1). + + For successful replacement, ``provider`` must meet all the requirements + which ``other`` fulfills. + + :param provider: The provider we are trying to replace with. + :param other: The provider we're trying to replace. + :param problems: If False is returned, this will contain what + problems prevented replacement. This is currently + a tuple of the literal string 'cantreplace', + ``provider``, ``other`` and the set of requirements + that ``provider`` couldn't fulfill. + :return: True if we can replace ``other`` with ``provider``, else + False. + """ + rlist = self.reqts[other] + unmatched = set() + for s in rlist: + matcher = self.get_matcher(s) + if not matcher.match(provider.version): + unmatched.add(s) + if unmatched: + # can't replace other with provider + problems.add(('cantreplace', provider, other, + frozenset(unmatched))) + result = False + else: + # can replace other with provider + self.remove_distribution(other) + del self.reqts[other] + for s in rlist: + self.reqts.setdefault(provider, set()).add(s) + self.add_distribution(provider) + result = True + return result + + def find(self, requirement, meta_extras=None, prereleases=False): + """ + Find a distribution and all distributions it depends on. + + :param requirement: The requirement specifying the distribution to + find, or a Distribution instance. + :param meta_extras: A list of meta extras such as :test:, :build: and + so on. + :param prereleases: If ``True``, allow pre-release versions to be + returned - otherwise, don't return prereleases + unless they're all that's available. + + Return a set of :class:`Distribution` instances and a set of + problems. + + The distributions returned should be such that they have the + :attr:`required` attribute set to ``True`` if they were + from the ``requirement`` passed to ``find()``, and they have the + :attr:`build_time_dependency` attribute set to ``True`` unless they + are post-installation dependencies of the ``requirement``. + + The problems should be a tuple consisting of the string + ``'unsatisfied'`` and the requirement which couldn't be satisfied + by any distribution known to the locator. + """ + + self.provided = {} + self.dists = {} + self.dists_by_name = {} + self.reqts = {} + + meta_extras = set(meta_extras or []) + if ':*:' in meta_extras: + meta_extras.remove(':*:') + # :meta: and :run: are implicitly included + meta_extras |= set([':test:', ':build:', ':dev:']) + + if isinstance(requirement, Distribution): + dist = odist = requirement + logger.debug('passed %s as requirement', odist) + else: + dist = odist = self.locator.locate(requirement, + prereleases=prereleases) + if dist is None: + raise DistlibException('Unable to locate %r' % requirement) + logger.debug('located %s', odist) + dist.requested = True + problems = set() + todo = set([dist]) + install_dists = set([odist]) + while todo: + dist = todo.pop() + name = dist.key # case-insensitive + if name not in self.dists_by_name: + self.add_distribution(dist) + else: + #import pdb; pdb.set_trace() + other = self.dists_by_name[name] + if other != dist: + self.try_to_replace(dist, other, problems) + + ireqts = dist.run_requires | dist.meta_requires + sreqts = dist.build_requires + ereqts = set() + if meta_extras and dist in install_dists: + for key in ('test', 'build', 'dev'): + e = ':%s:' % key + if e in meta_extras: + ereqts |= getattr(dist, '%s_requires' % key) + all_reqts = ireqts | sreqts | ereqts + for r in all_reqts: + providers = self.find_providers(r) + if not providers: + logger.debug('No providers found for %r', r) + provider = self.locator.locate(r, prereleases=prereleases) + # If no provider is found and we didn't consider + # prereleases, consider them now. + if provider is None and not prereleases: + provider = self.locator.locate(r, prereleases=True) + if provider is None: + logger.debug('Cannot satisfy %r', r) + problems.add(('unsatisfied', r)) + else: + n, v = provider.key, provider.version + if (n, v) not in self.dists: + todo.add(provider) + providers.add(provider) + if r in ireqts and dist in install_dists: + install_dists.add(provider) + logger.debug('Adding %s to install_dists', + provider.name_and_version) + for p in providers: + name = p.key + if name not in self.dists_by_name: + self.reqts.setdefault(p, set()).add(r) + else: + other = self.dists_by_name[name] + if other != p: + # see if other can be replaced by p + self.try_to_replace(p, other, problems) + + dists = set(self.dists.values()) + for dist in dists: + dist.build_time_dependency = dist not in install_dists + if dist.build_time_dependency: + logger.debug('%s is a build-time dependency only.', + dist.name_and_version) + logger.debug('find done for %s', odist) + return dists, problems diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/manifest.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/manifest.py new file mode 100644 index 0000000..ca0fe44 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/manifest.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Class representing the list of files in a distribution. + +Equivalent to distutils.filelist, but fixes some problems. +""" +import fnmatch +import logging +import os +import re +import sys + +from . import DistlibException +from .compat import fsdecode +from .util import convert_path + + +__all__ = ['Manifest'] + +logger = logging.getLogger(__name__) + +# a \ followed by some spaces + EOL +_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) +_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) + +# +# Due to the different results returned by fnmatch.translate, we need +# to do slightly different processing for Python 2.7 and 3.2 ... this needed +# to be brought in for Python 3.6 onwards. +# +_PYTHON_VERSION = sys.version_info[:2] + +class Manifest(object): + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + """ + + def __init__(self, base=None): + """ + Initialise an instance. + + :param base: The base directory to explore under. + """ + self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) + self.prefix = self.base + os.sep + self.allfiles = None + self.files = set() + + # + # Public API + # + + def findall(self): + """Find all files under the base and set ``allfiles`` to the absolute + pathnames of files found. + """ + from stat import S_ISREG, S_ISDIR, S_ISLNK + + self.allfiles = allfiles = [] + root = self.base + stack = [root] + pop = stack.pop + push = stack.append + + while stack: + root = pop() + names = os.listdir(root) + + for name in names: + fullname = os.path.join(root, name) + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat.st_mode + if S_ISREG(mode): + allfiles.append(fsdecode(fullname)) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + def add(self, item): + """ + Add a file to the manifest. + + :param item: The pathname to add. This can be relative to the base. + """ + if not item.startswith(self.prefix): + item = os.path.join(self.base, item) + self.files.add(os.path.normpath(item)) + + def add_many(self, items): + """ + Add a list of files to the manifest. + + :param items: The pathnames to add. These can be relative to the base. + """ + for item in items: + self.add(item) + + def sorted(self, wantdirs=False): + """ + Return sorted files in directory order + """ + + def add_dir(dirs, d): + dirs.add(d) + logger.debug('add_dir added %s', d) + if d != self.base: + parent, _ = os.path.split(d) + assert parent not in ('', '/') + add_dir(dirs, parent) + + result = set(self.files) # make a copy! + if wantdirs: + dirs = set() + for f in result: + add_dir(dirs, os.path.dirname(f)) + result |= dirs + return [os.path.join(*path_tuple) for path_tuple in + sorted(os.path.split(path) for path in result)] + + def clear(self): + """Clear all collected files.""" + self.files = set() + self.allfiles = [] + + def process_directive(self, directive): + """ + Process a directive which either adds some files from ``allfiles`` to + ``files``, or removes some files from ``files``. + + :param directive: The directive to process. This should be in a format + compatible with distutils ``MANIFEST.in`` files: + + http://docs.python.org/distutils/sourcedist.html#commands + """ + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dirpattern). + action, patterns, thedir, dirpattern = self._parse_directive(directive) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=True): + logger.warning('no files found matching %r', pattern) + + elif action == 'exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=True) + #if not found: + # logger.warning('no previously-included files ' + # 'found matching %r', pattern) + + elif action == 'global-include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=False): + logger.warning('no files found matching %r ' + 'anywhere in distribution', pattern) + + elif action == 'global-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=False) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found anywhere in ' + # 'distribution', pattern) + + elif action == 'recursive-include': + for pattern in patterns: + if not self._include_pattern(pattern, prefix=thedir): + logger.warning('no files found matching %r ' + 'under directory %r', pattern, thedir) + + elif action == 'recursive-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, prefix=thedir) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found under directory %r', + # pattern, thedir) + + elif action == 'graft': + if not self._include_pattern(None, prefix=dirpattern): + logger.warning('no directories found matching %r', + dirpattern) + + elif action == 'prune': + if not self._exclude_pattern(None, prefix=dirpattern): + logger.warning('no previously-included directories found ' + 'matching %r', dirpattern) + else: # pragma: no cover + # This should never happen, as it should be caught in + # _parse_template_line + raise DistlibException( + 'invalid action %r' % action) + + # + # Private API + # + + def _parse_directive(self, directive): + """ + Validate a directive. + :param directive: The directive to validate. + :return: A tuple of action, patterns, thedir, dir_patterns + """ + words = directive.split() + if len(words) == 1 and words[0] not in ('include', 'exclude', + 'global-include', + 'global-exclude', + 'recursive-include', + 'recursive-exclude', + 'graft', 'prune'): + # no action given, let's use the default 'include' + words.insert(0, 'include') + + action = words[0] + patterns = thedir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistlibException( + '%r expects <pattern1> <pattern2> ...' % action) + + patterns = [convert_path(word) for word in words[1:]] + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistlibException( + '%r expects <dir> <pattern1> <pattern2> ...' % action) + + thedir = convert_path(words[1]) + patterns = [convert_path(word) for word in words[2:]] + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistlibException( + '%r expects a single <dir_pattern>' % action) + + dir_pattern = convert_path(words[1]) + + else: + raise DistlibException('unknown action %r' % action) + + return action, patterns, thedir, dir_pattern + + def _include_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. + + Patterns are not quite the same as implemented by the 'fnmatch' + module: '*' and '?' match non-special characters, where "special" + is platform-dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return True if files are found. + """ + # XXX docstring lying about what the special chars are? + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.files.add(name) + found = True + return found + + def _exclude_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. + + Other parameters are the same as for 'include_pattern()', above. + The list 'self.files' is modified in place. Return True if files are + found. + + This API is public to allow e.g. exclusion of SCM subdirs, e.g. when + packaging source distributions + """ + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + for f in list(self.files): + if pattern_re.search(f): + self.files.remove(f) + found = True + return found + + def _translate_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Translate a shell-like wildcard pattern to a compiled regular + expression. + + Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if isinstance(pattern, str): + return re.compile(pattern) + else: + return pattern + + if _PYTHON_VERSION > (3, 2): + # ditch start and end characters + start, _, end = self._glob_to_re('_').partition('_') + + if pattern: + pattern_re = self._glob_to_re(pattern) + if _PYTHON_VERSION > (3, 2): + assert pattern_re.startswith(start) and pattern_re.endswith(end) + else: + pattern_re = '' + + base = re.escape(os.path.join(self.base, '')) + if prefix is not None: + # ditch end of pattern character + if _PYTHON_VERSION <= (3, 2): + empty_pattern = self._glob_to_re('') + prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] + else: + prefix_re = self._glob_to_re(prefix) + assert prefix_re.startswith(start) and prefix_re.endswith(end) + prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] + sep = os.sep + if os.sep == '\\': + sep = r'\\' + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + sep.join((prefix_re, + '.*' + pattern_re)) + else: + pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] + pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, + pattern_re, end) + else: # no prefix -- respect anchor flag + if anchor: + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + pattern_re + else: + pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) + + return re.compile(pattern_re) + + def _glob_to_re(self, pattern): + """Translate a shell-like glob pattern to a regular expression. + + Return a string containing the regex. Differs from + 'fnmatch.translate()' in that '*' does not match "special characters" + (which are platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters (currently: just os.sep). + sep = os.sep + if os.sep == '\\': + # we're using a regex to manipulate a regex, so we need + # to escape the backslash twice + sep = r'\\\\' + escaped = r'\1[^%s]' % sep + pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) + return pattern_re diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/markers.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/markers.py new file mode 100644 index 0000000..ee1f3e2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/markers.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Parser for the environment markers micro-language defined in PEP 508. +""" + +# Note: In PEP 345, the micro-language was Python compatible, so the ast +# module could be used to parse it. However, PEP 508 introduced operators such +# as ~= and === which aren't in Python, necessitating a different approach. + +import os +import sys +import platform +import re + +from .compat import python_implementation, urlparse, string_types +from .util import in_venv, parse_marker + +__all__ = ['interpret'] + +def _is_literal(o): + if not isinstance(o, string_types) or not o: + return False + return o[0] in '\'"' + +class Evaluator(object): + """ + This class is used to evaluate marker expessions. + """ + + operations = { + '==': lambda x, y: x == y, + '===': lambda x, y: x == y, + '~=': lambda x, y: x == y or x > y, + '!=': lambda x, y: x != y, + '<': lambda x, y: x < y, + '<=': lambda x, y: x == y or x < y, + '>': lambda x, y: x > y, + '>=': lambda x, y: x == y or x > y, + 'and': lambda x, y: x and y, + 'or': lambda x, y: x or y, + 'in': lambda x, y: x in y, + 'not in': lambda x, y: x not in y, + } + + def evaluate(self, expr, context): + """ + Evaluate a marker expression returned by the :func:`parse_requirement` + function in the specified context. + """ + if isinstance(expr, string_types): + if expr[0] in '\'"': + result = expr[1:-1] + else: + if expr not in context: + raise SyntaxError('unknown variable: %s' % expr) + result = context[expr] + else: + assert isinstance(expr, dict) + op = expr['op'] + if op not in self.operations: + raise NotImplementedError('op not implemented: %s' % op) + elhs = expr['lhs'] + erhs = expr['rhs'] + if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): + raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) + + lhs = self.evaluate(elhs, context) + rhs = self.evaluate(erhs, context) + result = self.operations[op](lhs, rhs) + return result + +def default_context(): + def format_full_version(info): + version = '%s.%s.%s' % (info.major, info.minor, info.micro) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + implementation_version = '0' + implementation_name = '' + + result = { + 'implementation_name': implementation_name, + 'implementation_version': implementation_version, + 'os_name': os.name, + 'platform_machine': platform.machine(), + 'platform_python_implementation': platform.python_implementation(), + 'platform_release': platform.release(), + 'platform_system': platform.system(), + 'platform_version': platform.version(), + 'platform_in_venv': str(in_venv()), + 'python_full_version': platform.python_version(), + 'python_version': platform.python_version()[:3], + 'sys_platform': sys.platform, + } + return result + +DEFAULT_CONTEXT = default_context() +del default_context + +evaluator = Evaluator() + +def interpret(marker, execution_context=None): + """ + Interpret a marker and return a result depending on environment. + + :param marker: The marker to interpret. + :type marker: str + :param execution_context: The context used for name lookup. + :type execution_context: mapping + """ + try: + expr, rest = parse_marker(marker) + except Exception as e: + raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) + if rest and rest[0] != '#': + raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) + context = dict(DEFAULT_CONTEXT) + if execution_context: + context.update(execution_context) + return evaluator.evaluate(expr, context) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/metadata.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/metadata.py new file mode 100644 index 0000000..6d6470f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/metadata.py @@ -0,0 +1,1091 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Implementation of the Metadata for Python packages PEPs. + +Supports all metadata formats (1.0, 1.1, 1.2, and 2.0 experimental). +""" +from __future__ import unicode_literals + +import codecs +from email import message_from_file +import json +import logging +import re + + +from . import DistlibException, __version__ +from .compat import StringIO, string_types, text_type +from .markers import interpret +from .util import extract_by_key, get_extras +from .version import get_scheme, PEP440_VERSION_RE + +logger = logging.getLogger(__name__) + + +class MetadataMissingError(DistlibException): + """A required metadata is missing""" + + +class MetadataConflictError(DistlibException): + """Attempt to read or write metadata fields that are conflictual.""" + + +class MetadataUnrecognizedVersionError(DistlibException): + """Unknown metadata version number.""" + + +class MetadataInvalidError(DistlibException): + """A metadata value is invalid""" + +# public API of this module +__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] + +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + +# preferred version. Hopefully will be changed +# to 1.2 once PEP 345 is supported everywhere +PKG_INFO_PREFERRED_VERSION = '1.1' + +_LINE_PREFIX_1_2 = re.compile('\n \\|') +_LINE_PREFIX_PRE_1_2 = re.compile('\n ') +_241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License') + +_314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License', 'Classifier', 'Download-URL', 'Obsoletes', + 'Provides', 'Requires') + +_314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', + 'Download-URL') + +_345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External') + +_345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', + 'Obsoletes-Dist', 'Requires-External', 'Maintainer', + 'Maintainer-email', 'Project-URL') + +_426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External', 'Private-Version', + 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', + 'Provides-Extra') + +_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', + 'Setup-Requires-Dist', 'Extension') + +_566_FIELDS = _426_FIELDS + ('Description-Content-Type',) + +_566_MARKERS = ('Description-Content-Type',) + +_ALL_FIELDS = set() +_ALL_FIELDS.update(_241_FIELDS) +_ALL_FIELDS.update(_314_FIELDS) +_ALL_FIELDS.update(_345_FIELDS) +_ALL_FIELDS.update(_426_FIELDS) +_ALL_FIELDS.update(_566_FIELDS) + +EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') + + +def _version2fieldlist(version): + if version == '1.0': + return _241_FIELDS + elif version == '1.1': + return _314_FIELDS + elif version == '1.2': + return _345_FIELDS + elif version in ('1.3', '2.1'): + return _345_FIELDS + _566_FIELDS + elif version == '2.0': + return _426_FIELDS + raise MetadataUnrecognizedVersionError(version) + + +def _best_version(fields): + """Detect the best version depending on the fields used.""" + def _has_marker(keys, markers): + for marker in markers: + if marker in keys: + return True + return False + + keys = [] + for key, value in fields.items(): + if value in ([], 'UNKNOWN', None): + continue + keys.append(key) + + possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] + + # first let's try to see if a field is not part of one of the version + for key in keys: + if key not in _241_FIELDS and '1.0' in possible_versions: + possible_versions.remove('1.0') + logger.debug('Removed 1.0 due to %s', key) + if key not in _314_FIELDS and '1.1' in possible_versions: + possible_versions.remove('1.1') + logger.debug('Removed 1.1 due to %s', key) + if key not in _345_FIELDS and '1.2' in possible_versions: + possible_versions.remove('1.2') + logger.debug('Removed 1.2 due to %s', key) + if key not in _566_FIELDS and '1.3' in possible_versions: + possible_versions.remove('1.3') + logger.debug('Removed 1.3 due to %s', key) + if key not in _566_FIELDS and '2.1' in possible_versions: + if key != 'Description': # In 2.1, description allowed after headers + possible_versions.remove('2.1') + logger.debug('Removed 2.1 due to %s', key) + if key not in _426_FIELDS and '2.0' in possible_versions: + possible_versions.remove('2.0') + logger.debug('Removed 2.0 due to %s', key) + + # possible_version contains qualified versions + if len(possible_versions) == 1: + return possible_versions[0] # found ! + elif len(possible_versions) == 0: + logger.debug('Out of options - unknown metadata set: %s', fields) + raise MetadataConflictError('Unknown metadata set') + + # let's see if one unique marker is found + is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) + is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) + is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) + is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) + if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: + raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') + + # we have the choice, 1.0, or 1.2, or 2.0 + # - 1.0 has a broken Summary field but works with all tools + # - 1.1 is to avoid + # - 1.2 fixes Summary but has little adoption + # - 2.0 adds more features and is very new + if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: + # we couldn't find any specific marker + if PKG_INFO_PREFERRED_VERSION in possible_versions: + return PKG_INFO_PREFERRED_VERSION + if is_1_1: + return '1.1' + if is_1_2: + return '1.2' + if is_2_1: + return '2.1' + + return '2.0' + +_ATTR2FIELD = { + 'metadata_version': 'Metadata-Version', + 'name': 'Name', + 'version': 'Version', + 'platform': 'Platform', + 'supported_platform': 'Supported-Platform', + 'summary': 'Summary', + 'description': 'Description', + 'keywords': 'Keywords', + 'home_page': 'Home-page', + 'author': 'Author', + 'author_email': 'Author-email', + 'maintainer': 'Maintainer', + 'maintainer_email': 'Maintainer-email', + 'license': 'License', + 'classifier': 'Classifier', + 'download_url': 'Download-URL', + 'obsoletes_dist': 'Obsoletes-Dist', + 'provides_dist': 'Provides-Dist', + 'requires_dist': 'Requires-Dist', + 'setup_requires_dist': 'Setup-Requires-Dist', + 'requires_python': 'Requires-Python', + 'requires_external': 'Requires-External', + 'requires': 'Requires', + 'provides': 'Provides', + 'obsoletes': 'Obsoletes', + 'project_url': 'Project-URL', + 'private_version': 'Private-Version', + 'obsoleted_by': 'Obsoleted-By', + 'extension': 'Extension', + 'provides_extra': 'Provides-Extra', +} + +_PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') +_VERSIONS_FIELDS = ('Requires-Python',) +_VERSION_FIELDS = ('Version',) +_LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', + 'Requires', 'Provides', 'Obsoletes-Dist', + 'Provides-Dist', 'Requires-Dist', 'Requires-External', + 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', + 'Provides-Extra', 'Extension') +_LISTTUPLEFIELDS = ('Project-URL',) + +_ELEMENTSFIELD = ('Keywords',) + +_UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') + +_MISSING = object() + +_FILESAFE = re.compile('[^A-Za-z0-9.]+') + + +def _get_name_and_version(name, version, for_filename=False): + """Return the distribution name with version. + + If for_filename is true, return a filename-escaped form.""" + if for_filename: + # For both name and version any runs of non-alphanumeric or '.' + # characters are replaced with a single '-'. Additionally any + # spaces in the version string become '.' + name = _FILESAFE.sub('-', name) + version = _FILESAFE.sub('-', version.replace(' ', '.')) + return '%s-%s' % (name, version) + + +class LegacyMetadata(object): + """The legacy metadata of a release. + + Supports versions 1.0, 1.1 and 1.2 (auto-detected). You can + instantiate the class with one of these arguments (or none): + - *path*, the path to a metadata file + - *fileobj* give a file-like object with metadata as content + - *mapping* is a dict-like object + - *scheme* is a version scheme name + """ + # TODO document the mapping API and UNKNOWN default key + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._fields = {} + self.requires_files = [] + self._dependencies = None + self.scheme = scheme + if path is not None: + self.read(path) + elif fileobj is not None: + self.read_file(fileobj) + elif mapping is not None: + self.update(mapping) + self.set_metadata_version() + + def set_metadata_version(self): + self._fields['Metadata-Version'] = _best_version(self._fields) + + def _write_field(self, fileobj, name, value): + fileobj.write('%s: %s\n' % (name, value)) + + def __getitem__(self, name): + return self.get(name) + + def __setitem__(self, name, value): + return self.set(name, value) + + def __delitem__(self, name): + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) + + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + + def _convert_name(self, name): + if name in _ALL_FIELDS: + return name + name = name.replace('-', '_').lower() + return _ATTR2FIELD.get(name, name) + + def _default_value(self, name): + if name in _LISTFIELDS or name in _ELEMENTSFIELD: + return [] + return 'UNKNOWN' + + def _remove_line_prefix(self, value): + if self.metadata_version in ('1.0', '1.1'): + return _LINE_PREFIX_PRE_1_2.sub('\n', value) + else: + return _LINE_PREFIX_1_2.sub('\n', value) + + def __getattr__(self, name): + if name in _ATTR2FIELD: + return self[name] + raise AttributeError(name) + + # + # Public API + # + +# dependencies = property(_get_dependencies, _set_dependencies) + + def get_fullname(self, filesafe=False): + """Return the distribution name with version. + + If filesafe is true, return a filename-escaped form.""" + return _get_name_and_version(self['Name'], self['Version'], filesafe) + + def is_field(self, name): + """return True if name is a valid metadata key""" + name = self._convert_name(name) + return name in _ALL_FIELDS + + def is_multi_field(self, name): + name = self._convert_name(name) + return name in _LISTFIELDS + + def read(self, filepath): + """Read the metadata values from a file path.""" + fp = codecs.open(filepath, 'r', encoding='utf-8') + try: + self.read_file(fp) + finally: + fp.close() + + def read_file(self, fileob): + """Read the metadata values from a file object.""" + msg = message_from_file(fileob) + self._fields['Metadata-Version'] = msg['metadata-version'] + + # When reading, get all the fields we can + for field in _ALL_FIELDS: + if field not in msg: + continue + if field in _LISTFIELDS: + # we can have multiple lines + values = msg.get_all(field) + if field in _LISTTUPLEFIELDS and values is not None: + values = [tuple(value.split(',')) for value in values] + self.set(field, values) + else: + # single line + value = msg[field] + if value is not None and value != 'UNKNOWN': + self.set(field, value) + logger.debug('Attempting to set metadata for %s', self) + self.set_metadata_version() + + def write(self, filepath, skip_unknown=False): + """Write the metadata fields to filepath.""" + fp = codecs.open(filepath, 'w', encoding='utf-8') + try: + self.write_file(fp, skip_unknown) + finally: + fp.close() + + def write_file(self, fileobject, skip_unknown=False): + """Write the PKG-INFO format data to a file object.""" + self.set_metadata_version() + + for field in _version2fieldlist(self['Metadata-Version']): + values = self.get(field) + if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): + continue + if field in _ELEMENTSFIELD: + self._write_field(fileobject, field, ','.join(values)) + continue + if field not in _LISTFIELDS: + if field == 'Description': + if self.metadata_version in ('1.0', '1.1'): + values = values.replace('\n', '\n ') + else: + values = values.replace('\n', '\n |') + values = [values] + + if field in _LISTTUPLEFIELDS: + values = [','.join(value) for value in values] + + for value in values: + self._write_field(fileobject, field, value) + + def update(self, other=None, **kwargs): + """Set metadata values from the given iterable `other` and kwargs. + + Behavior is like `dict.update`: If `other` has a ``keys`` method, + they are looped over and ``self[key]`` is assigned ``other[key]``. + Else, ``other`` is an iterable of ``(key, value)`` iterables. + + Keys that don't match a metadata field or that have an empty value are + dropped. + """ + def _set(key, value): + if key in _ATTR2FIELD and value: + self.set(self._convert_name(key), value) + + if not other: + # other is None or empty container + pass + elif hasattr(other, 'keys'): + for k in other.keys(): + _set(k, other[k]) + else: + for k, v in other: + _set(k, v) + + if kwargs: + for k, v in kwargs.items(): + _set(k, v) + + def set(self, name, value): + """Control then set a metadata field.""" + name = self._convert_name(name) + + if ((name in _ELEMENTSFIELD or name == 'Platform') and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [v.strip() for v in value.split(',')] + else: + value = [] + elif (name in _LISTFIELDS and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [value] + else: + value = [] + + if logger.isEnabledFor(logging.WARNING): + project_name = self['Name'] + + scheme = get_scheme(self.scheme) + if name in _PREDICATE_FIELDS and value is not None: + for v in value: + # check that the values are valid + if not scheme.is_valid_matcher(v.split(';')[0]): + logger.warning( + "'%s': '%s' is not valid (field '%s')", + project_name, v, name) + # FIXME this rejects UNKNOWN, is that right? + elif name in _VERSIONS_FIELDS and value is not None: + if not scheme.is_valid_constraint_list(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + elif name in _VERSION_FIELDS and value is not None: + if not scheme.is_valid_version(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + + if name in _UNICODEFIELDS: + if name == 'Description': + value = self._remove_line_prefix(value) + + self._fields[name] = value + + def get(self, name, default=_MISSING): + """Get a metadata field.""" + name = self._convert_name(name) + if name not in self._fields: + if default is _MISSING: + default = self._default_value(name) + return default + if name in _UNICODEFIELDS: + value = self._fields[name] + return value + elif name in _LISTFIELDS: + value = self._fields[name] + if value is None: + return [] + res = [] + for val in value: + if name not in _LISTTUPLEFIELDS: + res.append(val) + else: + # That's for Project-URL + res.append((val[0], val[1])) + return res + + elif name in _ELEMENTSFIELD: + value = self._fields[name] + if isinstance(value, string_types): + return value.split(',') + return self._fields[name] + + def check(self, strict=False): + """Check if the metadata is compliant. If strict is True then raise if + no Name or Version are provided""" + self.set_metadata_version() + + # XXX should check the versions (if the file was loaded) + missing, warnings = [], [] + + for attr in ('Name', 'Version'): # required by PEP 345 + if attr not in self: + missing.append(attr) + + if strict and missing != []: + msg = 'missing required metadata: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + + for attr in ('Home-page', 'Author'): + if attr not in self: + missing.append(attr) + + # checking metadata 1.2 (XXX needs to check 1.1, 1.0) + if self['Metadata-Version'] != '1.2': + return missing, warnings + + scheme = get_scheme(self.scheme) + + def are_valid_constraints(value): + for v in value: + if not scheme.is_valid_matcher(v.split(';')[0]): + return False + return True + + for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), + (_VERSIONS_FIELDS, + scheme.is_valid_constraint_list), + (_VERSION_FIELDS, + scheme.is_valid_version)): + for field in fields: + value = self.get(field, None) + if value is not None and not controller(value): + warnings.append("Wrong value for '%s': %s" % (field, value)) + + return missing, warnings + + def todict(self, skip_missing=False): + """Return fields as a dict. + + Field names will be converted to use the underscore-lowercase style + instead of hyphen-mixed case (i.e. home_page instead of Home-page). + """ + self.set_metadata_version() + + mapping_1_0 = ( + ('metadata_version', 'Metadata-Version'), + ('name', 'Name'), + ('version', 'Version'), + ('summary', 'Summary'), + ('home_page', 'Home-page'), + ('author', 'Author'), + ('author_email', 'Author-email'), + ('license', 'License'), + ('description', 'Description'), + ('keywords', 'Keywords'), + ('platform', 'Platform'), + ('classifiers', 'Classifier'), + ('download_url', 'Download-URL'), + ) + + data = {} + for key, field_name in mapping_1_0: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + if self['Metadata-Version'] == '1.2': + mapping_1_2 = ( + ('requires_dist', 'Requires-Dist'), + ('requires_python', 'Requires-Python'), + ('requires_external', 'Requires-External'), + ('provides_dist', 'Provides-Dist'), + ('obsoletes_dist', 'Obsoletes-Dist'), + ('project_url', 'Project-URL'), + ('maintainer', 'Maintainer'), + ('maintainer_email', 'Maintainer-email'), + ) + for key, field_name in mapping_1_2: + if not skip_missing or field_name in self._fields: + if key != 'project_url': + data[key] = self[field_name] + else: + data[key] = [','.join(u) for u in self[field_name]] + + elif self['Metadata-Version'] == '1.1': + mapping_1_1 = ( + ('provides', 'Provides'), + ('requires', 'Requires'), + ('obsoletes', 'Obsoletes'), + ) + for key, field_name in mapping_1_1: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + return data + + def add_requirements(self, requirements): + if self['Metadata-Version'] == '1.1': + # we can't have 1.1 metadata *and* Setuptools requires + for field in ('Obsoletes', 'Requires', 'Provides'): + if field in self: + del self[field] + self['Requires-Dist'] += requirements + + # Mapping API + # TODO could add iter* variants + + def keys(self): + return list(_version2fieldlist(self['Metadata-Version'])) + + def __iter__(self): + for key in self.keys(): + yield key + + def values(self): + return [self[key] for key in self.keys()] + + def items(self): + return [(key, self[key]) for key in self.keys()] + + def __repr__(self): + return '<%s %s %s>' % (self.__class__.__name__, self.name, + self.version) + + +METADATA_FILENAME = 'pydist.json' +WHEEL_METADATA_FILENAME = 'metadata.json' + + +class Metadata(object): + """ + The metadata of a release. This implementation uses 2.0 (JSON) + metadata where possible. If not possible, it wraps a LegacyMetadata + instance which handles the key-value metadata format. + """ + + METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') + + NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) + + VERSION_MATCHER = PEP440_VERSION_RE + + SUMMARY_MATCHER = re.compile('.{1,2047}') + + METADATA_VERSION = '2.0' + + GENERATOR = 'distlib (%s)' % __version__ + + MANDATORY_KEYS = { + 'name': (), + 'version': (), + 'summary': ('legacy',), + } + + INDEX_KEYS = ('name version license summary description author ' + 'author_email keywords platform home_page classifiers ' + 'download_url') + + DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' + 'dev_requires provides meta_requires obsoleted_by ' + 'supports_environments') + + SYNTAX_VALIDATORS = { + 'metadata_version': (METADATA_VERSION_MATCHER, ()), + 'name': (NAME_MATCHER, ('legacy',)), + 'version': (VERSION_MATCHER, ('legacy',)), + 'summary': (SUMMARY_MATCHER, ('legacy',)), + } + + __slots__ = ('_legacy', '_data', 'scheme') + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._legacy = None + self._data = None + self.scheme = scheme + #import pdb; pdb.set_trace() + if mapping is not None: + try: + self._validate_mapping(mapping, scheme) + self._data = mapping + except MetadataUnrecognizedVersionError: + self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) + self.validate() + else: + data = None + if path: + with open(path, 'rb') as f: + data = f.read() + elif fileobj: + data = fileobj.read() + if data is None: + # Initialised with no args - to be added + self._data = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + else: + if not isinstance(data, text_type): + data = data.decode('utf-8') + try: + self._data = json.loads(data) + self._validate_mapping(self._data, scheme) + except ValueError: + # Note: MetadataUnrecognizedVersionError does not + # inherit from ValueError (it's a DistlibException, + # which should not inherit from ValueError). + # The ValueError comes from the json.load - if that + # succeeds and we get a validation error, we want + # that to propagate + self._legacy = LegacyMetadata(fileobj=StringIO(data), + scheme=scheme) + self.validate() + + common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) + + none_list = (None, list) + none_dict = (None, dict) + + mapped_keys = { + 'run_requires': ('Requires-Dist', list), + 'build_requires': ('Setup-Requires-Dist', list), + 'dev_requires': none_list, + 'test_requires': none_list, + 'meta_requires': none_list, + 'extras': ('Provides-Extra', list), + 'modules': none_list, + 'namespaces': none_list, + 'exports': none_dict, + 'commands': none_dict, + 'classifiers': ('Classifier', list), + 'source_url': ('Download-URL', None), + 'metadata_version': ('Metadata-Version', None), + } + + del none_list, none_dict + + def __getattribute__(self, key): + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, maker = mapped[key] + if self._legacy: + if lk is None: + result = None if maker is None else maker() + else: + result = self._legacy.get(lk) + else: + value = None if maker is None else maker() + if key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + result = self._data.get(key, value) + else: + # special cases for PEP 459 + sentinel = object() + result = sentinel + d = self._data.get('extensions') + if d: + if key == 'commands': + result = d.get('python.commands', value) + elif key == 'classifiers': + d = d.get('python.details') + if d: + result = d.get(key, value) + else: + d = d.get('python.exports') + if not d: + d = self._data.get('python.exports') + if d: + result = d.get(key, value) + if result is sentinel: + result = value + elif key not in common: + result = object.__getattribute__(self, key) + elif self._legacy: + result = self._legacy.get(key) + else: + result = self._data.get(key) + return result + + def _validate_value(self, key, value, scheme=None): + if key in self.SYNTAX_VALIDATORS: + pattern, exclusions = self.SYNTAX_VALIDATORS[key] + if (scheme or self.scheme) not in exclusions: + m = pattern.match(value) + if not m: + raise MetadataInvalidError("'%s' is an invalid value for " + "the '%s' property" % (value, + key)) + + def __setattr__(self, key, value): + self._validate_value(key, value) + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, _ = mapped[key] + if self._legacy: + if lk is None: + raise NotImplementedError + self._legacy[lk] = value + elif key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + self._data[key] = value + else: + # special cases for PEP 459 + d = self._data.setdefault('extensions', {}) + if key == 'commands': + d['python.commands'] = value + elif key == 'classifiers': + d = d.setdefault('python.details', {}) + d[key] = value + else: + d = d.setdefault('python.exports', {}) + d[key] = value + elif key not in common: + object.__setattr__(self, key, value) + else: + if key == 'keywords': + if isinstance(value, string_types): + value = value.strip() + if value: + value = value.split() + else: + value = [] + if self._legacy: + self._legacy[key] = value + else: + self._data[key] = value + + @property + def name_and_version(self): + return _get_name_and_version(self.name, self.version, True) + + @property + def provides(self): + if self._legacy: + result = self._legacy['Provides-Dist'] + else: + result = self._data.setdefault('provides', []) + s = '%s (%s)' % (self.name, self.version) + if s not in result: + result.append(s) + return result + + @provides.setter + def provides(self, value): + if self._legacy: + self._legacy['Provides-Dist'] = value + else: + self._data['provides'] = value + + def get_requirements(self, reqts, extras=None, env=None): + """ + Base method to get dependencies, given a set of extras + to satisfy and an optional environment context. + :param reqts: A list of sometimes-wanted dependencies, + perhaps dependent on extras and environment. + :param extras: A list of optional components being requested. + :param env: An optional environment for marker evaluation. + """ + if self._legacy: + result = reqts + else: + result = [] + extras = get_extras(extras or [], self.extras) + for d in reqts: + if 'extra' not in d and 'environment' not in d: + # unconditional + include = True + else: + if 'extra' not in d: + # Not extra-dependent - only environment-dependent + include = True + else: + include = d.get('extra') in extras + if include: + # Not excluded because of extras, check environment + marker = d.get('environment') + if marker: + include = interpret(marker, env) + if include: + result.extend(d['requires']) + for key in ('build', 'dev', 'test'): + e = ':%s:' % key + if e in extras: + extras.remove(e) + # A recursive call, but it should terminate since 'test' + # has been removed from the extras + reqts = self._data.get('%s_requires' % key, []) + result.extend(self.get_requirements(reqts, extras=extras, + env=env)) + return result + + @property + def dictionary(self): + if self._legacy: + return self._from_legacy() + return self._data + + @property + def dependencies(self): + if self._legacy: + raise NotImplementedError + else: + return extract_by_key(self._data, self.DEPENDENCY_KEYS) + + @dependencies.setter + def dependencies(self, value): + if self._legacy: + raise NotImplementedError + else: + self._data.update(value) + + def _validate_mapping(self, mapping, scheme): + if mapping.get('metadata_version') != self.METADATA_VERSION: + raise MetadataUnrecognizedVersionError() + missing = [] + for key, exclusions in self.MANDATORY_KEYS.items(): + if key not in mapping: + if scheme not in exclusions: + missing.append(key) + if missing: + msg = 'Missing metadata items: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + for k, v in mapping.items(): + self._validate_value(k, v, scheme) + + def validate(self): + if self._legacy: + missing, warnings = self._legacy.check(True) + if missing or warnings: + logger.warning('Metadata: missing: %s, warnings: %s', + missing, warnings) + else: + self._validate_mapping(self._data, self.scheme) + + def todict(self): + if self._legacy: + return self._legacy.todict(True) + else: + result = extract_by_key(self._data, self.INDEX_KEYS) + return result + + def _from_legacy(self): + assert self._legacy and not self._data + result = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + lmd = self._legacy.todict(True) # skip missing ones + for k in ('name', 'version', 'license', 'summary', 'description', + 'classifier'): + if k in lmd: + if k == 'classifier': + nk = 'classifiers' + else: + nk = k + result[nk] = lmd[k] + kw = lmd.get('Keywords', []) + if kw == ['']: + kw = [] + result['keywords'] = kw + keys = (('requires_dist', 'run_requires'), + ('setup_requires_dist', 'build_requires')) + for ok, nk in keys: + if ok in lmd and lmd[ok]: + result[nk] = [{'requires': lmd[ok]}] + result['provides'] = self.provides + author = {} + maintainer = {} + return result + + LEGACY_MAPPING = { + 'name': 'Name', + 'version': 'Version', + 'license': 'License', + 'summary': 'Summary', + 'description': 'Description', + 'classifiers': 'Classifier', + } + + def _to_legacy(self): + def process_entries(entries): + reqts = set() + for e in entries: + extra = e.get('extra') + env = e.get('environment') + rlist = e['requires'] + for r in rlist: + if not env and not extra: + reqts.add(r) + else: + marker = '' + if extra: + marker = 'extra == "%s"' % extra + if env: + if marker: + marker = '(%s) and %s' % (env, marker) + else: + marker = env + reqts.add(';'.join((r, marker))) + return reqts + + assert self._data and not self._legacy + result = LegacyMetadata() + nmd = self._data + for nk, ok in self.LEGACY_MAPPING.items(): + if nk in nmd: + result[ok] = nmd[nk] + r1 = process_entries(self.run_requires + self.meta_requires) + r2 = process_entries(self.build_requires + self.dev_requires) + if self.extras: + result['Provides-Extra'] = sorted(self.extras) + result['Requires-Dist'] = sorted(r1) + result['Setup-Requires-Dist'] = sorted(r2) + # TODO: other fields such as contacts + return result + + def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): + if [path, fileobj].count(None) != 1: + raise ValueError('Exactly one of path and fileobj is needed') + self.validate() + if legacy: + if self._legacy: + legacy_md = self._legacy + else: + legacy_md = self._to_legacy() + if path: + legacy_md.write(path, skip_unknown=skip_unknown) + else: + legacy_md.write_file(fileobj, skip_unknown=skip_unknown) + else: + if self._legacy: + d = self._from_legacy() + else: + d = self._data + if fileobj: + json.dump(d, fileobj, ensure_ascii=True, indent=2, + sort_keys=True) + else: + with codecs.open(path, 'w', 'utf-8') as f: + json.dump(d, f, ensure_ascii=True, indent=2, + sort_keys=True) + + def add_requirements(self, requirements): + if self._legacy: + self._legacy.add_requirements(requirements) + else: + run_requires = self._data.setdefault('run_requires', []) + always = None + for entry in run_requires: + if 'environment' not in entry and 'extra' not in entry: + always = entry + break + if always is None: + always = { 'requires': requirements } + run_requires.insert(0, always) + else: + rset = set(always['requires']) | set(requirements) + always['requires'] = sorted(rset) + + def __repr__(self): + name = self.name or '(no name)' + version = self.version or 'no version' + return '<%s %s %s (%s)>' % (self.__class__.__name__, + self.metadata_version, name, version) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/resources.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/resources.py new file mode 100644 index 0000000..1884016 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/resources.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import bisect +import io +import logging +import os +import pkgutil +import shutil +import sys +import types +import zipimport + +from . import DistlibException +from .util import cached_property, get_cache_base, path_to_cache_dir, Cache + +logger = logging.getLogger(__name__) + + +cache = None # created when needed + + +class ResourceCache(Cache): + def __init__(self, base=None): + if base is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('resource-cache')) + super(ResourceCache, self).__init__(base) + + def is_stale(self, resource, path): + """ + Is the cache stale for the given resource? + + :param resource: The :class:`Resource` being cached. + :param path: The path of the resource in the cache. + :return: True if the cache is stale. + """ + # Cache invalidation is a hard problem :-) + return True + + def get(self, resource): + """ + Get a resource into the cache, + + :param resource: A :class:`Resource` instance. + :return: The pathname of the resource in the cache. + """ + prefix, path = resource.finder.get_cache_info(resource) + if prefix is None: + result = path + else: + result = os.path.join(self.base, self.prefix_to_dir(prefix), path) + dirname = os.path.dirname(result) + if not os.path.isdir(dirname): + os.makedirs(dirname) + if not os.path.exists(result): + stale = True + else: + stale = self.is_stale(resource, path) + if stale: + # write the bytes of the resource to the cache location + with open(result, 'wb') as f: + f.write(resource.bytes) + return result + + +class ResourceBase(object): + def __init__(self, finder, name): + self.finder = finder + self.name = name + + +class Resource(ResourceBase): + """ + A class representing an in-package resource, such as a data file. This is + not normally instantiated by user code, but rather by a + :class:`ResourceFinder` which manages the resource. + """ + is_container = False # Backwards compatibility + + def as_stream(self): + """ + Get the resource as a stream. + + This is not a property to make it obvious that it returns a new stream + each time. + """ + return self.finder.get_stream(self) + + @cached_property + def file_path(self): + global cache + if cache is None: + cache = ResourceCache() + return cache.get(self) + + @cached_property + def bytes(self): + return self.finder.get_bytes(self) + + @cached_property + def size(self): + return self.finder.get_size(self) + + +class ResourceContainer(ResourceBase): + is_container = True # Backwards compatibility + + @cached_property + def resources(self): + return self.finder.get_resources(self) + + +class ResourceFinder(object): + """ + Resource finder for file system resources. + """ + + if sys.platform.startswith('java'): + skipped_extensions = ('.pyc', '.pyo', '.class') + else: + skipped_extensions = ('.pyc', '.pyo') + + def __init__(self, module): + self.module = module + self.loader = getattr(module, '__loader__', None) + self.base = os.path.dirname(getattr(module, '__file__', '')) + + def _adjust_path(self, path): + return os.path.realpath(path) + + def _make_path(self, resource_name): + # Issue #50: need to preserve type of path on Python 2.x + # like os.path._get_sep + if isinstance(resource_name, bytes): # should only happen on 2.x + sep = b'/' + else: + sep = '/' + parts = resource_name.split(sep) + parts.insert(0, self.base) + result = os.path.join(*parts) + return self._adjust_path(result) + + def _find(self, path): + return os.path.exists(path) + + def get_cache_info(self, resource): + return None, resource.path + + def find(self, resource_name): + path = self._make_path(resource_name) + if not self._find(path): + result = None + else: + if self._is_directory(path): + result = ResourceContainer(self, resource_name) + else: + result = Resource(self, resource_name) + result.path = path + return result + + def get_stream(self, resource): + return open(resource.path, 'rb') + + def get_bytes(self, resource): + with open(resource.path, 'rb') as f: + return f.read() + + def get_size(self, resource): + return os.path.getsize(resource.path) + + def get_resources(self, resource): + def allowed(f): + return (f != '__pycache__' and not + f.endswith(self.skipped_extensions)) + return set([f for f in os.listdir(resource.path) if allowed(f)]) + + def is_container(self, resource): + return self._is_directory(resource.path) + + _is_directory = staticmethod(os.path.isdir) + + def iterator(self, resource_name): + resource = self.find(resource_name) + if resource is not None: + todo = [resource] + while todo: + resource = todo.pop(0) + yield resource + if resource.is_container: + rname = resource.name + for name in resource.resources: + if not rname: + new_name = name + else: + new_name = '/'.join([rname, name]) + child = self.find(new_name) + if child.is_container: + todo.append(child) + else: + yield child + + +class ZipResourceFinder(ResourceFinder): + """ + Resource finder for resources in .zip files. + """ + def __init__(self, module): + super(ZipResourceFinder, self).__init__(module) + archive = self.loader.archive + self.prefix_len = 1 + len(archive) + # PyPy doesn't have a _files attr on zipimporter, and you can't set one + if hasattr(self.loader, '_files'): + self._files = self.loader._files + else: + self._files = zipimport._zip_directory_cache[archive] + self.index = sorted(self._files) + + def _adjust_path(self, path): + return path + + def _find(self, path): + path = path[self.prefix_len:] + if path in self._files: + result = True + else: + if path and path[-1] != os.sep: + path = path + os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + if not result: + logger.debug('_find failed: %r %r', path, self.loader.prefix) + else: + logger.debug('_find worked: %r %r', path, self.loader.prefix) + return result + + def get_cache_info(self, resource): + prefix = self.loader.archive + path = resource.path[1 + len(prefix):] + return prefix, path + + def get_bytes(self, resource): + return self.loader.get_data(resource.path) + + def get_stream(self, resource): + return io.BytesIO(self.get_bytes(resource)) + + def get_size(self, resource): + path = resource.path[self.prefix_len:] + return self._files[path][3] + + def get_resources(self, resource): + path = resource.path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + plen = len(path) + result = set() + i = bisect.bisect(self.index, path) + while i < len(self.index): + if not self.index[i].startswith(path): + break + s = self.index[i][plen:] + result.add(s.split(os.sep, 1)[0]) # only immediate children + i += 1 + return result + + def _is_directory(self, path): + path = path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + return result + +_finder_registry = { + type(None): ResourceFinder, + zipimport.zipimporter: ZipResourceFinder +} + +try: + # In Python 3.6, _frozen_importlib -> _frozen_importlib_external + try: + import _frozen_importlib_external as _fi + except ImportError: + import _frozen_importlib as _fi + _finder_registry[_fi.SourceFileLoader] = ResourceFinder + _finder_registry[_fi.FileFinder] = ResourceFinder + del _fi +except (ImportError, AttributeError): + pass + + +def register_finder(loader, finder_maker): + _finder_registry[type(loader)] = finder_maker + +_finder_cache = {} + + +def finder(package): + """ + Return a resource finder for a package. + :param package: The name of the package. + :return: A :class:`ResourceFinder` instance for the package. + """ + if package in _finder_cache: + result = _finder_cache[package] + else: + if package not in sys.modules: + __import__(package) + module = sys.modules[package] + path = getattr(module, '__path__', None) + if path is None: + raise DistlibException('You cannot get a finder for a module, ' + 'only for a package') + loader = getattr(module, '__loader__', None) + finder_maker = _finder_registry.get(type(loader)) + if finder_maker is None: + raise DistlibException('Unable to locate finder for %r' % package) + result = finder_maker(module) + _finder_cache[package] = result + return result + + +_dummy_module = types.ModuleType(str('__dummy__')) + + +def finder_for_path(path): + """ + Return a resource finder for a path, which should represent a container. + + :param path: The path. + :return: A :class:`ResourceFinder` instance for the path. + """ + result = None + # calls any path hooks, gets importer into cache + pkgutil.get_importer(path) + loader = sys.path_importer_cache.get(path) + finder = _finder_registry.get(type(loader)) + if finder: + module = _dummy_module + module.__file__ = os.path.join(path, '') + module.__loader__ = loader + result = finder(module) + return result diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/scripts.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/scripts.py new file mode 100644 index 0000000..0b7c3d0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/scripts.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from io import BytesIO +import logging +import os +import re +import struct +import sys + +from .compat import sysconfig, detect_encoding, ZipFile +from .resources import finder +from .util import (FileOperator, get_export_entry, convert_path, + get_executable, in_venv) + +logger = logging.getLogger(__name__) + +_DEFAULT_MANIFEST = ''' +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="%s" + type="win32"/> + + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly>'''.strip() + +# check if Python is called on the first line with this expression +FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') +SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- +if __name__ == '__main__': + import sys, re + + def _resolve(module, func): + __import__(module) + mod = sys.modules[module] + parts = func.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + try: + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + + func = _resolve('%(module)s', '%(func)s') + rc = func() # None interpreted as 0 + except Exception as e: # only supporting Python >= 2.6 + sys.stderr.write('%%s\n' %% e) + rc = 1 + sys.exit(rc) +''' + + +def _enquote_executable(executable): + if ' ' in executable: + # make sure we quote only the executable in case of env + # for example /usr/bin/env "/dir with spaces/bin/jython" + # instead of "/usr/bin/env /dir with spaces/bin/jython" + # otherwise whole + if executable.startswith('/usr/bin/env '): + env, _executable = executable.split(' ', 1) + if ' ' in _executable and not _executable.startswith('"'): + executable = '%s "%s"' % (env, _executable) + else: + if not executable.startswith('"'): + executable = '"%s"' % executable + return executable + + +class ScriptMaker(object): + """ + A class to copy or create scripts from source scripts or callable + specifications. + """ + script_template = SCRIPT_TEMPLATE + + executable = None # for shebangs + + def __init__(self, source_dir, target_dir, add_launchers=True, + dry_run=False, fileop=None): + self.source_dir = source_dir + self.target_dir = target_dir + self.add_launchers = add_launchers + self.force = False + self.clobber = False + # It only makes sense to set mode bits on POSIX. + self.set_mode = (os.name == 'posix') or (os.name == 'java' and + os._name == 'posix') + self.variants = set(('', 'X.Y')) + self._fileop = fileop or FileOperator(dry_run) + + self._is_nt = os.name == 'nt' or ( + os.name == 'java' and os._name == 'nt') + + def _get_alternate_executable(self, executable, options): + if options.get('gui', False) and self._is_nt: # pragma: no cover + dn, fn = os.path.split(executable) + fn = fn.replace('python', 'pythonw') + executable = os.path.join(dn, fn) + return executable + + if sys.platform.startswith('java'): # pragma: no cover + def _is_shell(self, executable): + """ + Determine if the specified executable is a script + (contains a #! line) + """ + try: + with open(executable) as fp: + return fp.read(2) == '#!' + except (OSError, IOError): + logger.warning('Failed to open %s', executable) + return False + + def _fix_jython_executable(self, executable): + if self._is_shell(executable): + # Workaround for Jython is not needed on Linux systems. + import java + + if java.lang.System.getProperty('os.name') == 'Linux': + return executable + elif executable.lower().endswith('jython.exe'): + # Use wrapper exe for Jython on Windows + return executable + return '/usr/bin/env %s' % executable + + def _build_shebang(self, executable, post_interp): + """ + Build a shebang line. In the simple case (on Windows, or a shebang line + which is not too long or contains spaces) use a simple formulation for + the shebang. Otherwise, use /bin/sh as the executable, with a contrived + shebang which allows the script to run either under Python or sh, using + suitable quoting. Thanks to Harald Nordgren for his input. + + See also: http://www.in-ulm.de/~mascheck/various/shebang/#length + https://hg.mozilla.org/mozilla-central/file/tip/mach + """ + if os.name != 'posix': + simple_shebang = True + else: + # Add 3 for '#!' prefix and newline suffix. + shebang_length = len(executable) + len(post_interp) + 3 + if sys.platform == 'darwin': + max_shebang_length = 512 + else: + max_shebang_length = 127 + simple_shebang = ((b' ' not in executable) and + (shebang_length <= max_shebang_length)) + + if simple_shebang: + result = b'#!' + executable + post_interp + b'\n' + else: + result = b'#!/bin/sh\n' + result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' + result += b"' '''" + return result + + def _get_shebang(self, encoding, post_interp=b'', options=None): + enquote = True + if self.executable: + executable = self.executable + enquote = False # assume this will be taken care of + elif not sysconfig.is_python_build(): + executable = get_executable() + elif in_venv(): # pragma: no cover + executable = os.path.join(sysconfig.get_path('scripts'), + 'python%s' % sysconfig.get_config_var('EXE')) + else: # pragma: no cover + executable = os.path.join( + sysconfig.get_config_var('BINDIR'), + 'python%s%s' % (sysconfig.get_config_var('VERSION'), + sysconfig.get_config_var('EXE'))) + if options: + executable = self._get_alternate_executable(executable, options) + + if sys.platform.startswith('java'): # pragma: no cover + executable = self._fix_jython_executable(executable) + # Normalise case for Windows + executable = os.path.normcase(executable) + # If the user didn't specify an executable, it may be necessary to + # cater for executable paths with spaces (not uncommon on Windows) + if enquote: + executable = _enquote_executable(executable) + # Issue #51: don't use fsencode, since we later try to + # check that the shebang is decodable using utf-8. + executable = executable.encode('utf-8') + # in case of IronPython, play safe and enable frames support + if (sys.platform == 'cli' and '-X:Frames' not in post_interp + and '-X:FullFrames' not in post_interp): # pragma: no cover + post_interp += b' -X:Frames' + shebang = self._build_shebang(executable, post_interp) + # Python parser starts to read a script using UTF-8 until + # it gets a #coding:xxx cookie. The shebang has to be the + # first line of a file, the #coding:xxx cookie cannot be + # written before. So the shebang has to be decodable from + # UTF-8. + try: + shebang.decode('utf-8') + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable from utf-8' % shebang) + # If the script is encoded to a custom encoding (use a + # #coding:xxx cookie), the shebang has to be decodable from + # the script encoding too. + if encoding != 'utf-8': + try: + shebang.decode(encoding) + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable ' + 'from the script encoding (%r)' % (shebang, encoding)) + return shebang + + def _get_script_text(self, entry): + return self.script_template % dict(module=entry.prefix, + func=entry.suffix) + + manifest = _DEFAULT_MANIFEST + + def get_manifest(self, exename): + base = os.path.basename(exename) + return self.manifest % base + + def _write_script(self, names, shebang, script_bytes, filenames, ext): + use_launcher = self.add_launchers and self._is_nt + linesep = os.linesep.encode('utf-8') + if not use_launcher: + script_bytes = shebang + linesep + script_bytes + else: # pragma: no cover + if ext == 'py': + launcher = self._get_launcher('t') + else: + launcher = self._get_launcher('w') + stream = BytesIO() + with ZipFile(stream, 'w') as zf: + zf.writestr('__main__.py', script_bytes) + zip_data = stream.getvalue() + script_bytes = launcher + shebang + linesep + zip_data + for name in names: + outname = os.path.join(self.target_dir, name) + if use_launcher: # pragma: no cover + n, e = os.path.splitext(outname) + if e.startswith('.py'): + outname = n + outname = '%s.exe' % outname + try: + self._fileop.write_binary_file(outname, script_bytes) + except Exception: + # Failed writing an executable - it might be in use. + logger.warning('Failed to write executable - trying to ' + 'use .deleteme logic') + dfname = '%s.deleteme' % outname + if os.path.exists(dfname): + os.remove(dfname) # Not allowed to fail here + os.rename(outname, dfname) # nor here + self._fileop.write_binary_file(outname, script_bytes) + logger.debug('Able to replace executable using ' + '.deleteme logic') + try: + os.remove(dfname) + except Exception: + pass # still in use - ignore error + else: + if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover + outname = '%s.%s' % (outname, ext) + if os.path.exists(outname) and not self.clobber: + logger.warning('Skipping existing file %s', outname) + continue + self._fileop.write_binary_file(outname, script_bytes) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + + def _make_script(self, entry, filenames, options=None): + post_interp = b'' + if options: + args = options.get('interpreter_args', []) + if args: + args = ' %s' % ' '.join(args) + post_interp = args.encode('utf-8') + shebang = self._get_shebang('utf-8', post_interp, options=options) + script = self._get_script_text(entry).encode('utf-8') + name = entry.name + scriptnames = set() + if '' in self.variants: + scriptnames.add(name) + if 'X' in self.variants: + scriptnames.add('%s%s' % (name, sys.version[0])) + if 'X.Y' in self.variants: + scriptnames.add('%s-%s' % (name, sys.version[:3])) + if options and options.get('gui', False): + ext = 'pyw' + else: + ext = 'py' + self._write_script(scriptnames, shebang, script, filenames, ext) + + def _copy_script(self, script, filenames): + adjust = False + script = os.path.join(self.source_dir, convert_path(script)) + outname = os.path.join(self.target_dir, os.path.basename(script)) + if not self.force and not self._fileop.newer(script, outname): + logger.debug('not copying %s (up-to-date)', script) + return + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, 'rb') + except IOError: # pragma: no cover + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: # pragma: no cover + logger.warning('%s: %s is an empty file (skipping)', + self.get_command_name(), script) + return + + match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) + if match: + adjust = True + post_interp = match.group(1) or b'' + + if not adjust: + if f: + f.close() + self._fileop.copy_file(script, outname) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + else: + logger.info('copying and adjusting %s -> %s', script, + self.target_dir) + if not self._fileop.dry_run: + encoding, lines = detect_encoding(f.readline) + f.seek(0) + shebang = self._get_shebang(encoding, post_interp) + if b'pythonw' in first_line: # pragma: no cover + ext = 'pyw' + else: + ext = 'py' + n = os.path.basename(outname) + self._write_script([n], shebang, f.read(), filenames, ext) + if f: + f.close() + + @property + def dry_run(self): + return self._fileop.dry_run + + @dry_run.setter + def dry_run(self, value): + self._fileop.dry_run = value + + if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover + # Executable launcher support. + # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ + + def _get_launcher(self, kind): + if struct.calcsize('P') == 8: # 64-bit + bits = '64' + else: + bits = '32' + name = '%s%s.exe' % (kind, bits) + # Issue 31: don't hardcode an absolute package name, but + # determine it relative to the current package + distlib_package = __name__.rsplit('.', 1)[0] + result = finder(distlib_package).find(name).bytes + return result + + # Public API follows + + def make(self, specification, options=None): + """ + Make a script. + + :param specification: The specification, which is either a valid export + entry specification (to make a script from a + callable) or a filename (to make a script by + copying from a source location). + :param options: A dictionary of options controlling script generation. + :return: A list of all absolute pathnames written to. + """ + filenames = [] + entry = get_export_entry(specification) + if entry is None: + self._copy_script(specification, filenames) + else: + self._make_script(entry, filenames, options=options) + return filenames + + def make_multiple(self, specifications, options=None): + """ + Take a list of specifications and make scripts from them, + :param specifications: A list of specifications. + :return: A list of all absolute pathnames written to, + """ + filenames = [] + for specification in specifications: + filenames.extend(self.make(specification, options)) + return filenames diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t32.exe b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t32.exe new file mode 100644 index 0000000..a09d926 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t32.exe differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t64.exe b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t64.exe new file mode 100644 index 0000000..9da9b40 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/t64.exe differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/util.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/util.py new file mode 100644 index 0000000..0b14a93 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/util.py @@ -0,0 +1,1755 @@ +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import codecs +from collections import deque +import contextlib +import csv +from glob import iglob as std_iglob +import io +import json +import logging +import os +import py_compile +import re +import socket +try: + import ssl +except ImportError: # pragma: no cover + ssl = None +import subprocess +import sys +import tarfile +import tempfile +import textwrap + +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import time + +from . import DistlibException +from .compat import (string_types, text_type, shutil, raw_input, StringIO, + cache_from_source, urlopen, urljoin, httplib, xmlrpclib, + splittype, HTTPHandler, BaseConfigurator, valid_ident, + Container, configparser, URLError, ZipFile, fsdecode, + unquote, urlparse) + +logger = logging.getLogger(__name__) + +# +# Requirement parsing code as per PEP 508 +# + +IDENTIFIER = re.compile(r'^([\w\.-]+)\s*') +VERSION_IDENTIFIER = re.compile(r'^([\w\.*+-]+)\s*') +COMPARE_OP = re.compile(r'^(<=?|>=?|={2,3}|[~!]=)\s*') +MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') +OR = re.compile(r'^or\b\s*') +AND = re.compile(r'^and\b\s*') +NON_SPACE = re.compile(r'(\S+)\s*') +STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') + + +def parse_marker(marker_string): + """ + Parse a marker string and return a dictionary containing a marker expression. + + The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in + the expression grammar, or strings. A string contained in quotes is to be + interpreted as a literal string, and a string not contained in quotes is a + variable (such as os_name). + """ + def marker_var(remaining): + # either identifier, or literal string + m = IDENTIFIER.match(remaining) + if m: + result = m.groups()[0] + remaining = remaining[m.end():] + elif not remaining: + raise SyntaxError('unexpected end of input') + else: + q = remaining[0] + if q not in '\'"': + raise SyntaxError('invalid expression: %s' % remaining) + oq = '\'"'.replace(q, '') + remaining = remaining[1:] + parts = [q] + while remaining: + # either a string chunk, or oq, or q to terminate + if remaining[0] == q: + break + elif remaining[0] == oq: + parts.append(oq) + remaining = remaining[1:] + else: + m = STRING_CHUNK.match(remaining) + if not m: + raise SyntaxError('error in string literal: %s' % remaining) + parts.append(m.groups()[0]) + remaining = remaining[m.end():] + else: + s = ''.join(parts) + raise SyntaxError('unterminated string: %s' % s) + parts.append(q) + result = ''.join(parts) + remaining = remaining[1:].lstrip() # skip past closing quote + return result, remaining + + def marker_expr(remaining): + if remaining and remaining[0] == '(': + result, remaining = marker(remaining[1:].lstrip()) + if remaining[0] != ')': + raise SyntaxError('unterminated parenthesis: %s' % remaining) + remaining = remaining[1:].lstrip() + else: + lhs, remaining = marker_var(remaining) + while remaining: + m = MARKER_OP.match(remaining) + if not m: + break + op = m.groups()[0] + remaining = remaining[m.end():] + rhs, remaining = marker_var(remaining) + lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} + result = lhs + return result, remaining + + def marker_and(remaining): + lhs, remaining = marker_expr(remaining) + while remaining: + m = AND.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_expr(remaining) + lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + def marker(remaining): + lhs, remaining = marker_and(remaining) + while remaining: + m = OR.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_and(remaining) + lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + return marker(marker_string) + + +def parse_requirement(req): + """ + Parse a requirement passed in as a string. Return a Container + whose attributes contain the various parts of the requirement. + """ + remaining = req.strip() + if not remaining or remaining.startswith('#'): + return None + m = IDENTIFIER.match(remaining) + if not m: + raise SyntaxError('name expected: %s' % remaining) + distname = m.groups()[0] + remaining = remaining[m.end():] + extras = mark_expr = versions = uri = None + if remaining and remaining[0] == '[': + i = remaining.find(']', 1) + if i < 0: + raise SyntaxError('unterminated extra: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + extras = [] + while s: + m = IDENTIFIER.match(s) + if not m: + raise SyntaxError('malformed extra: %s' % s) + extras.append(m.groups()[0]) + s = s[m.end():] + if not s: + break + if s[0] != ',': + raise SyntaxError('comma expected in extras: %s' % s) + s = s[1:].lstrip() + if not extras: + extras = None + if remaining: + if remaining[0] == '@': + # it's a URI + remaining = remaining[1:].lstrip() + m = NON_SPACE.match(remaining) + if not m: + raise SyntaxError('invalid URI: %s' % remaining) + uri = m.groups()[0] + t = urlparse(uri) + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not (t.scheme and t.netloc): + raise SyntaxError('Invalid URL: %s' % uri) + remaining = remaining[m.end():].lstrip() + else: + + def get_versions(ver_remaining): + """ + Return a list of operator, version tuples if any are + specified, else None. + """ + m = COMPARE_OP.match(ver_remaining) + versions = None + if m: + versions = [] + while True: + op = m.groups()[0] + ver_remaining = ver_remaining[m.end():] + m = VERSION_IDENTIFIER.match(ver_remaining) + if not m: + raise SyntaxError('invalid version: %s' % ver_remaining) + v = m.groups()[0] + versions.append((op, v)) + ver_remaining = ver_remaining[m.end():] + if not ver_remaining or ver_remaining[0] != ',': + break + ver_remaining = ver_remaining[1:].lstrip() + m = COMPARE_OP.match(ver_remaining) + if not m: + raise SyntaxError('invalid constraint: %s' % ver_remaining) + if not versions: + versions = None + return versions, ver_remaining + + if remaining[0] != '(': + versions, remaining = get_versions(remaining) + else: + i = remaining.find(')', 1) + if i < 0: + raise SyntaxError('unterminated parenthesis: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + # As a special diversion from PEP 508, allow a version number + # a.b.c in parentheses as a synonym for ~= a.b.c (because this + # is allowed in earlier PEPs) + if COMPARE_OP.match(s): + versions, _ = get_versions(s) + else: + m = VERSION_IDENTIFIER.match(s) + if not m: + raise SyntaxError('invalid constraint: %s' % s) + v = m.groups()[0] + s = s[m.end():].lstrip() + if s: + raise SyntaxError('invalid constraint: %s' % s) + versions = [('~=', v)] + + if remaining: + if remaining[0] != ';': + raise SyntaxError('invalid requirement: %s' % remaining) + remaining = remaining[1:].lstrip() + + mark_expr, remaining = parse_marker(remaining) + + if remaining and remaining[0] != '#': + raise SyntaxError('unexpected trailing data: %s' % remaining) + + if not versions: + rs = distname + else: + rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) + return Container(name=distname, extras=extras, constraints=versions, + marker=mark_expr, url=uri, requirement=rs) + + +def get_resources_dests(resources_root, rules): + """Find destinations for resources files""" + + def get_rel_path(root, path): + # normalizes and returns a lstripped-/-separated path + root = root.replace(os.path.sep, '/') + path = path.replace(os.path.sep, '/') + assert path.startswith(root) + return path[len(root):].lstrip('/') + + destinations = {} + for base, suffix, dest in rules: + prefix = os.path.join(resources_root, base) + for abs_base in iglob(prefix): + abs_glob = os.path.join(abs_base, suffix) + for abs_path in iglob(abs_glob): + resource_file = get_rel_path(resources_root, abs_path) + if dest is None: # remove the entry if it was here + destinations.pop(resource_file, None) + else: + rel_path = get_rel_path(abs_base, abs_path) + rel_dest = dest.replace(os.path.sep, '/').rstrip('/') + destinations[resource_file] = rel_dest + '/' + rel_path + return destinations + + +def in_venv(): + if hasattr(sys, 'real_prefix'): + # virtualenv venvs + result = True + else: + # PEP 405 venvs + result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) + return result + + +def get_executable(): +# The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as +# changes to the stub launcher mean that sys.executable always points +# to the stub on OS X +# if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' +# in os.environ): +# result = os.environ['__PYVENV_LAUNCHER__'] +# else: +# result = sys.executable +# return result + result = os.path.normcase(sys.executable) + if not isinstance(result, text_type): + result = fsdecode(result) + return result + + +def proceed(prompt, allowed_chars, error_prompt=None, default=None): + p = prompt + while True: + s = raw_input(p) + p = prompt + if not s and default: + s = default + if s: + c = s[0].lower() + if c in allowed_chars: + break + if error_prompt: + p = '%c: %s\n%s' % (c, error_prompt, prompt) + return c + + +def extract_by_key(d, keys): + if isinstance(keys, string_types): + keys = keys.split() + result = {} + for key in keys: + if key in d: + result[key] = d[key] + return result + +def read_exports(stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + # Try to load as JSON, falling back on legacy format + data = stream.read() + stream = StringIO(data) + try: + jdata = json.load(stream) + result = jdata['extensions']['python.exports']['exports'] + for group, entries in result.items(): + for k, v in entries.items(): + s = '%s = %s' % (k, v) + entry = get_export_entry(s) + assert entry is not None + entries[k] = entry + return result + except Exception: + stream.seek(0, 0) + + def read_stream(cp, stream): + if hasattr(cp, 'read_file'): + cp.read_file(stream) + else: + cp.readfp(stream) + + cp = configparser.ConfigParser() + try: + read_stream(cp, stream) + except configparser.MissingSectionHeaderError: + stream.close() + data = textwrap.dedent(data) + stream = StringIO(data) + read_stream(cp, stream) + + result = {} + for key in cp.sections(): + result[key] = entries = {} + for name, value in cp.items(key): + s = '%s = %s' % (name, value) + entry = get_export_entry(s) + assert entry is not None + #entry.dist = self + entries[name] = entry + return result + + +def write_exports(exports, stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getwriter('utf-8')(stream) + cp = configparser.ConfigParser() + for k, v in exports.items(): + # TODO check k, v for valid values + cp.add_section(k) + for entry in v.values(): + if entry.suffix is None: + s = entry.prefix + else: + s = '%s:%s' % (entry.prefix, entry.suffix) + if entry.flags: + s = '%s [%s]' % (s, ', '.join(entry.flags)) + cp.set(k, entry.name, s) + cp.write(stream) + + +@contextlib.contextmanager +def tempdir(): + td = tempfile.mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +@contextlib.contextmanager +def chdir(d): + cwd = os.getcwd() + try: + os.chdir(d) + yield + finally: + os.chdir(cwd) + + +@contextlib.contextmanager +def socket_timeout(seconds=15): + cto = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(seconds) + yield + finally: + socket.setdefaulttimeout(cto) + + +class cached_property(object): + def __init__(self, func): + self.func = func + #for attr in ('__name__', '__module__', '__doc__'): + # setattr(self, attr, getattr(func, attr, None)) + + def __get__(self, obj, cls=None): + if obj is None: + return self + value = self.func(obj) + object.__setattr__(obj, self.func.__name__, value) + #obj.__dict__[self.func.__name__] = value = self.func(obj) + return value + +def convert_path(pathname): + """Return 'pathname' as a name that will work on the native filesystem. + + The path is split on '/' and put back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError("path '%s' cannot be absolute" % pathname) + if pathname[-1] == '/': + raise ValueError("path '%s' cannot end with '/'" % pathname) + + paths = pathname.split('/') + while os.curdir in paths: + paths.remove(os.curdir) + if not paths: + return os.curdir + return os.path.join(*paths) + + +class FileOperator(object): + def __init__(self, dry_run=False): + self.dry_run = dry_run + self.ensured = set() + self._init_record() + + def _init_record(self): + self.record = False + self.files_written = set() + self.dirs_created = set() + + def record_as_written(self, path): + if self.record: + self.files_written.add(path) + + def newer(self, source, target): + """Tell if the target is newer than the source. + + Returns true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Returns false if both exist and 'target' is the same age or younger + than 'source'. Raise PackagingFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same + second will have the same "age". + """ + if not os.path.exists(source): + raise DistlibException("file '%r' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return True + + return os.stat(source).st_mtime > os.stat(target).st_mtime + + def copy_file(self, infile, outfile, check=True): + """Copy a file respecting dry-run and force flags. + """ + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying %s to %s', infile, outfile) + if not self.dry_run: + msg = None + if check: + if os.path.islink(outfile): + msg = '%s is a symlink' % outfile + elif os.path.exists(outfile) and not os.path.isfile(outfile): + msg = '%s is a non-regular file' % outfile + if msg: + raise ValueError(msg + ' which would be overwritten') + shutil.copyfile(infile, outfile) + self.record_as_written(outfile) + + def copy_stream(self, instream, outfile, encoding=None): + assert not os.path.isdir(outfile) + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying stream %s to %s', instream, outfile) + if not self.dry_run: + if encoding is None: + outstream = open(outfile, 'wb') + else: + outstream = codecs.open(outfile, 'w', encoding=encoding) + try: + shutil.copyfileobj(instream, outstream) + finally: + outstream.close() + self.record_as_written(outfile) + + def write_binary_file(self, path, data): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data) + self.record_as_written(path) + + def write_text_file(self, path, data, encoding): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data.encode(encoding)) + self.record_as_written(path) + + def set_mode(self, bits, mask, files): + if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): + # Set the executable bits (owner, group, and world) on + # all the files specified. + for f in files: + if self.dry_run: + logger.info("changing mode of %s", f) + else: + mode = (os.stat(f).st_mode | bits) & mask + logger.info("changing mode of %s to %o", f, mode) + os.chmod(f, mode) + + set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) + + def ensure_dir(self, path): + path = os.path.abspath(path) + if path not in self.ensured and not os.path.exists(path): + self.ensured.add(path) + d, f = os.path.split(path) + self.ensure_dir(d) + logger.info('Creating %s' % path) + if not self.dry_run: + os.mkdir(path) + if self.record: + self.dirs_created.add(path) + + def byte_compile(self, path, optimize=False, force=False, prefix=None): + dpath = cache_from_source(path, not optimize) + logger.info('Byte-compiling %s to %s', path, dpath) + if not self.dry_run: + if force or self.newer(path, dpath): + if not prefix: + diagpath = None + else: + assert path.startswith(prefix) + diagpath = path[len(prefix):] + py_compile.compile(path, dpath, diagpath, True) # raise error + self.record_as_written(dpath) + return dpath + + def ensure_removed(self, path): + if os.path.exists(path): + if os.path.isdir(path) and not os.path.islink(path): + logger.debug('Removing directory tree at %s', path) + if not self.dry_run: + shutil.rmtree(path) + if self.record: + if path in self.dirs_created: + self.dirs_created.remove(path) + else: + if os.path.islink(path): + s = 'link' + else: + s = 'file' + logger.debug('Removing %s %s', s, path) + if not self.dry_run: + os.remove(path) + if self.record: + if path in self.files_written: + self.files_written.remove(path) + + def is_writable(self, path): + result = False + while not result: + if os.path.exists(path): + result = os.access(path, os.W_OK) + break + parent = os.path.dirname(path) + if parent == path: + break + path = parent + return result + + def commit(self): + """ + Commit recorded changes, turn off recording, return + changes. + """ + assert self.record + result = self.files_written, self.dirs_created + self._init_record() + return result + + def rollback(self): + if not self.dry_run: + for f in list(self.files_written): + if os.path.exists(f): + os.remove(f) + # dirs should all be empty now, except perhaps for + # __pycache__ subdirs + # reverse so that subdirs appear before their parents + dirs = sorted(self.dirs_created, reverse=True) + for d in dirs: + flist = os.listdir(d) + if flist: + assert flist == ['__pycache__'] + sd = os.path.join(d, flist[0]) + os.rmdir(sd) + os.rmdir(d) # should fail if non-empty + self._init_record() + +def resolve(module_name, dotted_path): + if module_name in sys.modules: + mod = sys.modules[module_name] + else: + mod = __import__(module_name) + if dotted_path is None: + result = mod + else: + parts = dotted_path.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + +class ExportEntry(object): + def __init__(self, name, prefix, suffix, flags): + self.name = name + self.prefix = prefix + self.suffix = suffix + self.flags = flags + + @cached_property + def value(self): + return resolve(self.prefix, self.suffix) + + def __repr__(self): # pragma: no cover + return '<ExportEntry %s = %s:%s %s>' % (self.name, self.prefix, + self.suffix, self.flags) + + def __eq__(self, other): + if not isinstance(other, ExportEntry): + result = False + else: + result = (self.name == other.name and + self.prefix == other.prefix and + self.suffix == other.suffix and + self.flags == other.flags) + return result + + __hash__ = object.__hash__ + + +ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+) + \s*=\s*(?P<callable>(\w+)([:\.]\w+)*) + \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? + ''', re.VERBOSE) + +def get_export_entry(specification): + m = ENTRY_RE.search(specification) + if not m: + result = None + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + else: + d = m.groupdict() + name = d['name'] + path = d['callable'] + colons = path.count(':') + if colons == 0: + prefix, suffix = path, None + else: + if colons != 1: + raise DistlibException("Invalid specification " + "'%s'" % specification) + prefix, suffix = path.split(':') + flags = d['flags'] + if flags is None: + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + flags = [] + else: + flags = [f.strip() for f in flags.split(',')] + result = ExportEntry(name, prefix, suffix, flags) + return result + + +def get_cache_base(suffix=None): + """ + Return the default base location for distlib caches. If the directory does + not exist, it is created. Use the suffix provided for the base directory, + and default to '.distlib' if it isn't provided. + + On Windows, if LOCALAPPDATA is defined in the environment, then it is + assumed to be a directory, and will be the parent directory of the result. + On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home + directory - using os.expanduser('~') - will be the parent directory of + the result. + + The result is just the directory '.distlib' in the parent directory as + determined above, or with the name specified with ``suffix``. + """ + if suffix is None: + suffix = '.distlib' + if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: + result = os.path.expandvars('$localappdata') + else: + # Assume posix, or old Windows + result = os.path.expanduser('~') + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if os.path.isdir(result): + usable = os.access(result, os.W_OK) + if not usable: + logger.warning('Directory exists but is not writable: %s', result) + else: + try: + os.makedirs(result) + usable = True + except OSError: + logger.warning('Unable to create %s', result, exc_info=True) + usable = False + if not usable: + result = tempfile.mkdtemp() + logger.warning('Default location unusable, using %s', result) + return os.path.join(result, suffix) + + +def path_to_cache_dir(path): + """ + Convert an absolute path to a directory name for use in a cache. + + The algorithm used is: + + #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. + #. Any occurrence of ``os.sep`` is replaced with ``'--'``. + #. ``'.cache'`` is appended. + """ + d, p = os.path.splitdrive(os.path.abspath(path)) + if d: + d = d.replace(':', '---') + p = p.replace(os.sep, '--') + return d + p + '.cache' + + +def ensure_slash(s): + if not s.endswith('/'): + return s + '/' + return s + + +def parse_credentials(netloc): + username = password = None + if '@' in netloc: + prefix, netloc = netloc.split('@', 1) + if ':' not in prefix: + username = prefix + else: + username, password = prefix.split(':', 1) + return username, password, netloc + + +def get_process_umask(): + result = os.umask(0o22) + os.umask(result) + return result + +def is_string_sequence(seq): + result = True + i = None + for i, s in enumerate(seq): + if not isinstance(s, string_types): + result = False + break + assert i is not None + return result + +PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' + '([a-z0-9_.+-]+)', re.I) +PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') + + +def split_filename(filename, project_name=None): + """ + Extract name, version, python version from a filename (no extension) + + Return name, version, pyver or None + """ + result = None + pyver = None + filename = unquote(filename).replace(' ', '-') + m = PYTHON_VERSION.search(filename) + if m: + pyver = m.group(1) + filename = filename[:m.start()] + if project_name and len(filename) > len(project_name) + 1: + m = re.match(re.escape(project_name) + r'\b', filename) + if m: + n = m.end() + result = filename[:n], filename[n + 1:], pyver + if result is None: + m = PROJECT_NAME_AND_VERSION.match(filename) + if m: + result = m.group(1), m.group(3), pyver + return result + +# Allow spaces in name because of legacy dists like "Twisted Core" +NAME_VERSION_RE = re.compile(r'(?P<name>[\w .-]+)\s*' + r'\(\s*(?P<ver>[^\s)]+)\)$') + +def parse_name_and_version(p): + """ + A utility method used to get name and version from a string. + + From e.g. a Provides-Dist value. + + :param p: A value in a form 'foo (1.0)' + :return: The name and version as a tuple. + """ + m = NAME_VERSION_RE.match(p) + if not m: + raise DistlibException('Ill-formed name/version string: \'%s\'' % p) + d = m.groupdict() + return d['name'].strip().lower(), d['ver'] + +def get_extras(requested, available): + result = set() + requested = set(requested or []) + available = set(available or []) + if '*' in requested: + requested.remove('*') + result |= available + for r in requested: + if r == '-': + result.add(r) + elif r.startswith('-'): + unwanted = r[1:] + if unwanted not in available: + logger.warning('undeclared extra: %s' % unwanted) + if unwanted in result: + result.remove(unwanted) + else: + if r not in available: + logger.warning('undeclared extra: %s' % r) + result.add(r) + return result +# +# Extended metadata functionality +# + +def _get_external_data(url): + result = {} + try: + # urlopen might fail if it runs into redirections, + # because of Python issue #13696. Fixed in locators + # using a custom redirect handler. + resp = urlopen(url) + headers = resp.info() + ct = headers.get('Content-Type') + if not ct.startswith('application/json'): + logger.debug('Unexpected response for JSON request: %s', ct) + else: + reader = codecs.getreader('utf-8')(resp) + #data = reader.read().decode('utf-8') + #result = json.loads(data) + result = json.load(reader) + except Exception as e: + logger.exception('Failed to get external data for %s: %s', url, e) + return result + +_external_data_base_url = 'https://www.red-dove.com/pypi/projects/' + +def get_project_data(name): + url = '%s/%s/project.json' % (name[0].upper(), name) + url = urljoin(_external_data_base_url, url) + result = _get_external_data(url) + return result + +def get_package_data(name, version): + url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) + url = urljoin(_external_data_base_url, url) + return _get_external_data(url) + + +class Cache(object): + """ + A class implementing a cache for resources that need to live in the file system + e.g. shared libraries. This class was moved from resources to here because it + could be used by other modules, e.g. the wheel module. + """ + + def __init__(self, base): + """ + Initialise an instance. + + :param base: The base directory where the cache should be located. + """ + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if not os.path.isdir(base): # pragma: no cover + os.makedirs(base) + if (os.stat(base).st_mode & 0o77) != 0: + logger.warning('Directory \'%s\' is not private', base) + self.base = os.path.abspath(os.path.normpath(base)) + + def prefix_to_dir(self, prefix): + """ + Converts a resource prefix to a directory name in the cache. + """ + return path_to_cache_dir(prefix) + + def clear(self): + """ + Clear the cache. + """ + not_removed = [] + for fn in os.listdir(self.base): + fn = os.path.join(self.base, fn) + try: + if os.path.islink(fn) or os.path.isfile(fn): + os.remove(fn) + elif os.path.isdir(fn): + shutil.rmtree(fn) + except Exception: + not_removed.append(fn) + return not_removed + + +class EventMixin(object): + """ + A very simple publish/subscribe system. + """ + def __init__(self): + self._subscribers = {} + + def add(self, event, subscriber, append=True): + """ + Add a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be added (and called when the + event is published). + :param append: Whether to append or prepend the subscriber to an + existing subscriber list for the event. + """ + subs = self._subscribers + if event not in subs: + subs[event] = deque([subscriber]) + else: + sq = subs[event] + if append: + sq.append(subscriber) + else: + sq.appendleft(subscriber) + + def remove(self, event, subscriber): + """ + Remove a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be removed. + """ + subs = self._subscribers + if event not in subs: + raise ValueError('No subscribers: %r' % event) + subs[event].remove(subscriber) + + def get_subscribers(self, event): + """ + Return an iterator for the subscribers for an event. + :param event: The event to return subscribers for. + """ + return iter(self._subscribers.get(event, ())) + + def publish(self, event, *args, **kwargs): + """ + Publish a event and return a list of values returned by its + subscribers. + + :param event: The event to publish. + :param args: The positional arguments to pass to the event's + subscribers. + :param kwargs: The keyword arguments to pass to the event's + subscribers. + """ + result = [] + for subscriber in self.get_subscribers(event): + try: + value = subscriber(event, *args, **kwargs) + except Exception: + logger.exception('Exception during event publication') + value = None + result.append(value) + logger.debug('publish %s: args = %s, kwargs = %s, result = %s', + event, args, kwargs, result) + return result + +# +# Simple sequencing +# +class Sequencer(object): + def __init__(self): + self._preds = {} + self._succs = {} + self._nodes = set() # nodes with no preds/succs + + def add_node(self, node): + self._nodes.add(node) + + def remove_node(self, node, edges=False): + if node in self._nodes: + self._nodes.remove(node) + if edges: + for p in set(self._preds.get(node, ())): + self.remove(p, node) + for s in set(self._succs.get(node, ())): + self.remove(node, s) + # Remove empties + for k, v in list(self._preds.items()): + if not v: + del self._preds[k] + for k, v in list(self._succs.items()): + if not v: + del self._succs[k] + + def add(self, pred, succ): + assert pred != succ + self._preds.setdefault(succ, set()).add(pred) + self._succs.setdefault(pred, set()).add(succ) + + def remove(self, pred, succ): + assert pred != succ + try: + preds = self._preds[succ] + succs = self._succs[pred] + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of anything' % succ) + try: + preds.remove(pred) + succs.remove(succ) + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of %r' % (succ, pred)) + + def is_step(self, step): + return (step in self._preds or step in self._succs or + step in self._nodes) + + def get_steps(self, final): + if not self.is_step(final): + raise ValueError('Unknown: %r' % final) + result = [] + todo = [] + seen = set() + todo.append(final) + while todo: + step = todo.pop(0) + if step in seen: + # if a step was already seen, + # move it to the end (so it will appear earlier + # when reversed on return) ... but not for the + # final step, as that would be confusing for + # users + if step != final: + result.remove(step) + result.append(step) + else: + seen.add(step) + result.append(step) + preds = self._preds.get(step, ()) + todo.extend(preds) + return reversed(result) + + @property + def strong_connections(self): + #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm + index_counter = [0] + stack = [] + lowlinks = {} + index = {} + result = [] + + graph = self._succs + + def strongconnect(node): + # set the depth index for this node to the smallest unused index + index[node] = index_counter[0] + lowlinks[node] = index_counter[0] + index_counter[0] += 1 + stack.append(node) + + # Consider successors + try: + successors = graph[node] + except Exception: + successors = [] + for successor in successors: + if successor not in lowlinks: + # Successor has not yet been visited + strongconnect(successor) + lowlinks[node] = min(lowlinks[node],lowlinks[successor]) + elif successor in stack: + # the successor is in the stack and hence in the current + # strongly connected component (SCC) + lowlinks[node] = min(lowlinks[node],index[successor]) + + # If `node` is a root node, pop the stack and generate an SCC + if lowlinks[node] == index[node]: + connected_component = [] + + while True: + successor = stack.pop() + connected_component.append(successor) + if successor == node: break + component = tuple(connected_component) + # storing the result + result.append(component) + + for node in graph: + if node not in lowlinks: + strongconnect(node) + + return result + + @property + def dot(self): + result = ['digraph G {'] + for succ in self._preds: + preds = self._preds[succ] + for pred in preds: + result.append(' %s -> %s;' % (pred, succ)) + for node in self._nodes: + result.append(' %s;' % node) + result.append('}') + return '\n'.join(result) + +# +# Unarchiving functionality for zip, tar, tgz, tbz, whl +# + +ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', + '.tgz', '.tbz', '.whl') + +def unarchive(archive_filename, dest_dir, format=None, check=True): + + def check_path(path): + if not isinstance(path, text_type): + path = path.decode('utf-8') + p = os.path.abspath(os.path.join(dest_dir, path)) + if not p.startswith(dest_dir) or p[plen] != os.sep: + raise ValueError('path outside destination: %r' % p) + + dest_dir = os.path.abspath(dest_dir) + plen = len(dest_dir) + archive = None + if format is None: + if archive_filename.endswith(('.zip', '.whl')): + format = 'zip' + elif archive_filename.endswith(('.tar.gz', '.tgz')): + format = 'tgz' + mode = 'r:gz' + elif archive_filename.endswith(('.tar.bz2', '.tbz')): + format = 'tbz' + mode = 'r:bz2' + elif archive_filename.endswith('.tar'): + format = 'tar' + mode = 'r' + else: # pragma: no cover + raise ValueError('Unknown format for %r' % archive_filename) + try: + if format == 'zip': + archive = ZipFile(archive_filename, 'r') + if check: + names = archive.namelist() + for name in names: + check_path(name) + else: + archive = tarfile.open(archive_filename, mode) + if check: + names = archive.getnames() + for name in names: + check_path(name) + if format != 'zip' and sys.version_info[0] < 3: + # See Python issue 17153. If the dest path contains Unicode, + # tarfile extraction fails on Python 2.x if a member path name + # contains non-ASCII characters - it leads to an implicit + # bytes -> unicode conversion using ASCII to decode. + for tarinfo in archive.getmembers(): + if not isinstance(tarinfo.name, text_type): + tarinfo.name = tarinfo.name.decode('utf-8') + archive.extractall(dest_dir) + + finally: + if archive: + archive.close() + + +def zip_dir(directory): + """zip a directory tree into a BytesIO object""" + result = io.BytesIO() + dlen = len(directory) + with ZipFile(result, "w") as zf: + for root, dirs, files in os.walk(directory): + for name in files: + full = os.path.join(root, name) + rel = root[dlen:] + dest = os.path.join(rel, name) + zf.write(full, dest) + return result + +# +# Simple progress bar +# + +UNITS = ('', 'K', 'M', 'G','T','P') + + +class Progress(object): + unknown = 'UNKNOWN' + + def __init__(self, minval=0, maxval=100): + assert maxval is None or maxval >= minval + self.min = self.cur = minval + self.max = maxval + self.started = None + self.elapsed = 0 + self.done = False + + def update(self, curval): + assert self.min <= curval + assert self.max is None or curval <= self.max + self.cur = curval + now = time.time() + if self.started is None: + self.started = now + else: + self.elapsed = now - self.started + + def increment(self, incr): + assert incr >= 0 + self.update(self.cur + incr) + + def start(self): + self.update(self.min) + return self + + def stop(self): + if self.max is not None: + self.update(self.max) + self.done = True + + @property + def maximum(self): + return self.unknown if self.max is None else self.max + + @property + def percentage(self): + if self.done: + result = '100 %' + elif self.max is None: + result = ' ?? %' + else: + v = 100.0 * (self.cur - self.min) / (self.max - self.min) + result = '%3d %%' % v + return result + + def format_duration(self, duration): + if (duration <= 0) and self.max is None or self.cur == self.min: + result = '??:??:??' + #elif duration < 1: + # result = '--:--:--' + else: + result = time.strftime('%H:%M:%S', time.gmtime(duration)) + return result + + @property + def ETA(self): + if self.done: + prefix = 'Done' + t = self.elapsed + #import pdb; pdb.set_trace() + else: + prefix = 'ETA ' + if self.max is None: + t = -1 + elif self.elapsed == 0 or (self.cur == self.min): + t = 0 + else: + #import pdb; pdb.set_trace() + t = float(self.max - self.min) + t /= self.cur - self.min + t = (t - 1) * self.elapsed + return '%s: %s' % (prefix, self.format_duration(t)) + + @property + def speed(self): + if self.elapsed == 0: + result = 0.0 + else: + result = (self.cur - self.min) / self.elapsed + for unit in UNITS: + if result < 1000: + break + result /= 1000.0 + return '%d %sB/s' % (result, unit) + +# +# Glob functionality +# + +RICH_GLOB = re.compile(r'\{([^}]*)\}') +_CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') +_CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') + + +def iglob(path_glob): + """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" + if _CHECK_RECURSIVE_GLOB.search(path_glob): + msg = """invalid glob %r: recursive glob "**" must be used alone""" + raise ValueError(msg % path_glob) + if _CHECK_MISMATCH_SET.search(path_glob): + msg = """invalid glob %r: mismatching set marker '{' or '}'""" + raise ValueError(msg % path_glob) + return _iglob(path_glob) + + +def _iglob(path_glob): + rich_path_glob = RICH_GLOB.split(path_glob, 1) + if len(rich_path_glob) > 1: + assert len(rich_path_glob) == 3, rich_path_glob + prefix, set, suffix = rich_path_glob + for item in set.split(','): + for path in _iglob(''.join((prefix, item, suffix))): + yield path + else: + if '**' not in path_glob: + for item in std_iglob(path_glob): + yield item + else: + prefix, radical = path_glob.split('**', 1) + if prefix == '': + prefix = '.' + if radical == '': + radical = '*' + else: + # we support both + radical = radical.lstrip('/') + radical = radical.lstrip('\\') + for path, dir, files in os.walk(prefix): + path = os.path.normpath(path) + for fn in _iglob(os.path.join(path, radical)): + yield fn + +if ssl: + from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, + CertificateError) + + +# +# HTTPSConnection which verifies certificates/matches domains +# + + class HTTPSConnection(httplib.HTTPSConnection): + ca_certs = None # set this to the path to the certs file (.pem) + check_domain = True # only used if ca_certs is not None + + # noinspection PyPropertyAccess + def connect(self): + sock = socket.create_connection((self.host, self.port), self.timeout) + if getattr(self, '_tunnel_host', False): + self.sock = sock + self._tunnel() + + if not hasattr(ssl, 'SSLContext'): + # For 2.x + if self.ca_certs: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, + cert_reqs=cert_reqs, + ssl_version=ssl.PROTOCOL_SSLv23, + ca_certs=self.ca_certs) + else: # pragma: no cover + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.options |= ssl.OP_NO_SSLv2 + if self.cert_file: + context.load_cert_chain(self.cert_file, self.key_file) + kwargs = {} + if self.ca_certs: + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(cafile=self.ca_certs) + if getattr(ssl, 'HAS_SNI', False): + kwargs['server_hostname'] = self.host + self.sock = context.wrap_socket(sock, **kwargs) + if self.ca_certs and self.check_domain: + try: + match_hostname(self.sock.getpeercert(), self.host) + logger.debug('Host verified: %s', self.host) + except CertificateError: # pragma: no cover + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + class HTTPSHandler(BaseHTTPSHandler): + def __init__(self, ca_certs, check_domain=True): + BaseHTTPSHandler.__init__(self) + self.ca_certs = ca_certs + self.check_domain = check_domain + + def _conn_maker(self, *args, **kwargs): + """ + This is called to create a connection instance. Normally you'd + pass a connection class to do_open, but it doesn't actually check for + a class, and just expects a callable. As long as we behave just as a + constructor would have, we should be OK. If it ever changes so that + we *must* pass a class, we'll create an UnsafeHTTPSConnection class + which just sets check_domain to False in the class definition, and + choose which one to pass to do_open. + """ + result = HTTPSConnection(*args, **kwargs) + if self.ca_certs: + result.ca_certs = self.ca_certs + result.check_domain = self.check_domain + return result + + def https_open(self, req): + try: + return self.do_open(self._conn_maker, req) + except URLError as e: + if 'certificate verify failed' in str(e.reason): + raise CertificateError('Unable to verify server certificate ' + 'for %s' % req.host) + else: + raise + + # + # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- + # Middle proxy using HTTP listens on port 443, or an index mistakenly serves + # HTML containing a http://xyz link when it should be https://xyz), + # you can use the following handler class, which does not allow HTTP traffic. + # + # It works by inheriting from HTTPHandler - so build_opener won't add a + # handler for HTTP itself. + # + class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): + def http_open(self, req): + raise URLError('Unexpected HTTP request on what should be a secure ' + 'connection: %s' % req) + +# +# XML-RPC with timeouts +# + +_ver_info = sys.version_info[:2] + +if _ver_info == (2, 6): + class HTTP(httplib.HTTP): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + + if ssl: + class HTTPS(httplib.HTTPS): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + +class Transport(xmlrpclib.Transport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.Transport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, x509 = self.get_host_info(host) + if _ver_info == (2, 6): + result = HTTP(h, timeout=self.timeout) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPConnection(h) + result = self._connection[1] + return result + +if ssl: + class SafeTransport(xmlrpclib.SafeTransport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.SafeTransport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, kwargs = self.get_host_info(host) + if not kwargs: + kwargs = {} + kwargs['timeout'] = self.timeout + if _ver_info == (2, 6): + result = HTTPS(host, None, **kwargs) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPSConnection(h, None, + **kwargs) + result = self._connection[1] + return result + + +class ServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, **kwargs): + self.timeout = timeout = kwargs.pop('timeout', None) + # The above classes only come into play if a timeout + # is specified + if timeout is not None: + scheme, _ = splittype(uri) + use_datetime = kwargs.get('use_datetime', 0) + if scheme == 'https': + tcls = SafeTransport + else: + tcls = Transport + kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) + self.transport = t + xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) + +# +# CSV functionality. This is provided because on 2.x, the csv module can't +# handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. +# + +def _csv_open(fn, mode, **kwargs): + if sys.version_info[0] < 3: + mode += 'b' + else: + kwargs['newline'] = '' + # Python 3 determines encoding from locale. Force 'utf-8' + # file encoding to match other forced utf-8 encoding + kwargs['encoding'] = 'utf-8' + return open(fn, mode, **kwargs) + + +class CSVBase(object): + defaults = { + 'delimiter': str(','), # The strs are used because we need native + 'quotechar': str('"'), # str in the csv API (2.x won't take + 'lineterminator': str('\n') # Unicode) + } + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.stream.close() + + +class CSVReader(CSVBase): + def __init__(self, **kwargs): + if 'stream' in kwargs: + stream = kwargs['stream'] + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + self.stream = stream + else: + self.stream = _csv_open(kwargs['path'], 'r') + self.reader = csv.reader(self.stream, **self.defaults) + + def __iter__(self): + return self + + def next(self): + result = next(self.reader) + if sys.version_info[0] < 3: + for i, item in enumerate(result): + if not isinstance(item, text_type): + result[i] = item.decode('utf-8') + return result + + __next__ = next + +class CSVWriter(CSVBase): + def __init__(self, fn, **kwargs): + self.stream = _csv_open(fn, 'w') + self.writer = csv.writer(self.stream, **self.defaults) + + def writerow(self, row): + if sys.version_info[0] < 3: + r = [] + for item in row: + if isinstance(item, text_type): + item = item.encode('utf-8') + r.append(item) + row = r + self.writer.writerow(row) + +# +# Configurator functionality +# + +class Configurator(BaseConfigurator): + + value_converters = dict(BaseConfigurator.value_converters) + value_converters['inc'] = 'inc_convert' + + def __init__(self, config, base=None): + super(Configurator, self).__init__(config) + self.base = base or os.getcwd() + + def configure_custom(self, config): + def convert(o): + if isinstance(o, (list, tuple)): + result = type(o)([convert(i) for i in o]) + elif isinstance(o, dict): + if '()' in o: + result = self.configure_custom(o) + else: + result = {} + for k in o: + result[k] = convert(o[k]) + else: + result = self.convert(o) + return result + + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + args = config.pop('[]', ()) + if args: + args = tuple([convert(o) for o in args]) + items = [(k, convert(config[k])) for k in config if valid_ident(k)] + kwargs = dict(items) + result = c(*args, **kwargs) + if props: + for n, v in props.items(): + setattr(result, n, convert(v)) + return result + + def __getitem__(self, key): + result = self.config[key] + if isinstance(result, dict) and '()' in result: + self.config[key] = result = self.configure_custom(result) + return result + + def inc_convert(self, value): + """Default converter for the inc:// protocol.""" + if not os.path.isabs(value): + value = os.path.join(self.base, value) + with codecs.open(value, 'r', encoding='utf-8') as f: + result = json.load(f) + return result + + +class SubprocessMixin(object): + """ + Mixin for running subprocesses and capturing their output + """ + def __init__(self, verbose=False, progress=None): + self.verbose = verbose + self.progress = progress + + def reader(self, stream, context): + """ + Read lines from a subprocess' output stream and either pass to a progress + callable (if specified) or write progress information to sys.stderr. + """ + progress = self.progress + verbose = self.verbose + while True: + s = stream.readline() + if not s: + break + if progress is not None: + progress(s, context) + else: + if not verbose: + sys.stderr.write('.') + else: + sys.stderr.write(s.decode('utf-8')) + sys.stderr.flush() + stream.close() + + def run_command(self, cmd, **kwargs): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, **kwargs) + t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) + t1.start() + t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) + t2.start() + p.wait() + t1.join() + t2.join() + if self.progress is not None: + self.progress('done.', 'main') + elif self.verbose: + sys.stderr.write('done.\n') + return p + + +def normalize_name(name): + """Normalize a python package name a la PEP 503""" + # https://www.python.org/dev/peps/pep-0503/#normalized-names + return re.sub('[-_.]+', '-', name).lower() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/version.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/version.py new file mode 100644 index 0000000..3eebe18 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/version.py @@ -0,0 +1,736 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Implementation of a flexible versioning scheme providing support for PEP-440, +setuptools-compatible and semantic versioning. +""" + +import logging +import re + +from .compat import string_types +from .util import parse_requirement + +__all__ = ['NormalizedVersion', 'NormalizedMatcher', + 'LegacyVersion', 'LegacyMatcher', + 'SemanticVersion', 'SemanticMatcher', + 'UnsupportedVersionError', 'get_scheme'] + +logger = logging.getLogger(__name__) + + +class UnsupportedVersionError(ValueError): + """This is an unsupported version.""" + pass + + +class Version(object): + def __init__(self, s): + self._string = s = s.strip() + self._parts = parts = self.parse(s) + assert isinstance(parts, tuple) + assert len(parts) > 0 + + def parse(self, s): + raise NotImplementedError('please implement in a subclass') + + def _check_compatible(self, other): + if type(self) != type(other): + raise TypeError('cannot compare %r and %r' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + self._check_compatible(other) + return self._parts < other._parts + + def __gt__(self, other): + return not (self.__lt__(other) or self.__eq__(other)) + + def __le__(self, other): + return self.__lt__(other) or self.__eq__(other) + + def __ge__(self, other): + return self.__gt__(other) or self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self._parts) + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + @property + def is_prerelease(self): + raise NotImplementedError('Please implement in subclasses.') + + +class Matcher(object): + version_class = None + + # value is either a callable or the name of a method + _operators = { + '<': lambda v, c, p: v < c, + '>': lambda v, c, p: v > c, + '<=': lambda v, c, p: v == c or v < c, + '>=': lambda v, c, p: v == c or v > c, + '==': lambda v, c, p: v == c, + '===': lambda v, c, p: v == c, + # by default, compatible => >=. + '~=': lambda v, c, p: v == c or v > c, + '!=': lambda v, c, p: v != c, + } + + # this is a method only to support alternative implementations + # via overriding + def parse_requirement(self, s): + return parse_requirement(s) + + def __init__(self, s): + if self.version_class is None: + raise ValueError('Please specify a version class') + self._string = s = s.strip() + r = self.parse_requirement(s) + if not r: + raise ValueError('Not valid: %r' % s) + self.name = r.name + self.key = self.name.lower() # for case-insensitive comparisons + clist = [] + if r.constraints: + # import pdb; pdb.set_trace() + for op, s in r.constraints: + if s.endswith('.*'): + if op not in ('==', '!='): + raise ValueError('\'.*\' not allowed for ' + '%r constraints' % op) + # Could be a partial version (e.g. for '2.*') which + # won't parse as a version, so keep it as a string + vn, prefix = s[:-2], True + # Just to check that vn is a valid version + self.version_class(vn) + else: + # Should parse as a version, so we can create an + # instance for the comparison + vn, prefix = self.version_class(s), False + clist.append((op, vn, prefix)) + self._parts = tuple(clist) + + def match(self, version): + """ + Check if the provided version matches the constraints. + + :param version: The version to match against this instance. + :type version: String or :class:`Version` instance. + """ + if isinstance(version, string_types): + version = self.version_class(version) + for operator, constraint, prefix in self._parts: + f = self._operators.get(operator) + if isinstance(f, string_types): + f = getattr(self, f) + if not f: + msg = ('%r not implemented ' + 'for %s' % (operator, self.__class__.__name__)) + raise NotImplementedError(msg) + if not f(version, constraint, prefix): + return False + return True + + @property + def exact_version(self): + result = None + if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): + result = self._parts[0][1] + return result + + def _check_compatible(self, other): + if type(self) != type(other) or self.name != other.name: + raise TypeError('cannot compare %s and %s' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self.key == other.key and self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self.key) + hash(self._parts) + + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + +PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' + r'(\.(post)(\d+))?(\.(dev)(\d+))?' + r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') + + +def _pep_440_key(s): + s = s.strip() + m = PEP440_VERSION_RE.match(s) + if not m: + raise UnsupportedVersionError('Not a valid version: %s' % s) + groups = m.groups() + nums = tuple(int(v) for v in groups[1].split('.')) + while len(nums) > 1 and nums[-1] == 0: + nums = nums[:-1] + + if not groups[0]: + epoch = 0 + else: + epoch = int(groups[0]) + pre = groups[4:6] + post = groups[7:9] + dev = groups[10:12] + local = groups[13] + if pre == (None, None): + pre = () + else: + pre = pre[0], int(pre[1]) + if post == (None, None): + post = () + else: + post = post[0], int(post[1]) + if dev == (None, None): + dev = () + else: + dev = dev[0], int(dev[1]) + if local is None: + local = () + else: + parts = [] + for part in local.split('.'): + # to ensure that numeric compares as > lexicographic, avoid + # comparing them directly, but encode a tuple which ensures + # correct sorting + if part.isdigit(): + part = (1, int(part)) + else: + part = (0, part) + parts.append(part) + local = tuple(parts) + if not pre: + # either before pre-release, or final release and after + if not post and dev: + # before pre-release + pre = ('a', -1) # to sort before a0 + else: + pre = ('z',) # to sort after all pre-releases + # now look at the state of post and dev. + if not post: + post = ('_',) # sort before 'a' + if not dev: + dev = ('final',) + + #print('%s -> %s' % (s, m.groups())) + return epoch, nums, pre, post, dev, local + + +_normalized_key = _pep_440_key + + +class NormalizedVersion(Version): + """A rational version. + + Good: + 1.2 # equivalent to "1.2.0" + 1.2.0 + 1.2a1 + 1.2.3a2 + 1.2.3b1 + 1.2.3c1 + 1.2.3.4 + TODO: fill this out + + Bad: + 1 # minimum two numbers + 1.2a # release level must have a release serial + 1.2.3b + """ + def parse(self, s): + result = _normalized_key(s) + # _normalized_key loses trailing zeroes in the release + # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 + # However, PEP 440 prefix matching needs it: for example, + # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). + m = PEP440_VERSION_RE.match(s) # must succeed + groups = m.groups() + self._release_clause = tuple(int(v) for v in groups[1].split('.')) + return result + + PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) + + @property + def is_prerelease(self): + return any(t[0] in self.PREREL_TAGS for t in self._parts if t) + + +def _match_prefix(x, y): + x = str(x) + y = str(y) + if x == y: + return True + if not x.startswith(y): + return False + n = len(y) + return x[n] == '.' + + +class NormalizedMatcher(Matcher): + version_class = NormalizedVersion + + # value is either a callable or the name of a method + _operators = { + '~=': '_match_compatible', + '<': '_match_lt', + '>': '_match_gt', + '<=': '_match_le', + '>=': '_match_ge', + '==': '_match_eq', + '===': '_match_arbitrary', + '!=': '_match_ne', + } + + def _adjust_local(self, version, constraint, prefix): + if prefix: + strip_local = '+' not in constraint and version._parts[-1] + else: + # both constraint and version are + # NormalizedVersion instances. + # If constraint does not have a local component, + # ensure the version doesn't, either. + strip_local = not constraint._parts[-1] and version._parts[-1] + if strip_local: + s = version._string.split('+', 1)[0] + version = self.version_class(s) + return version, constraint + + def _match_lt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version >= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_gt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version <= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_le(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version <= constraint + + def _match_ge(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version >= constraint + + def _match_eq(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version == constraint) + else: + result = _match_prefix(version, constraint) + return result + + def _match_arbitrary(self, version, constraint, prefix): + return str(version) == str(constraint) + + def _match_ne(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version != constraint) + else: + result = not _match_prefix(version, constraint) + return result + + def _match_compatible(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version == constraint: + return True + if version < constraint: + return False +# if not prefix: +# return True + release_clause = constraint._release_clause + if len(release_clause) > 1: + release_clause = release_clause[:-1] + pfx = '.'.join([str(i) for i in release_clause]) + return _match_prefix(version, pfx) + +_REPLACEMENTS = ( + (re.compile('[.+-]$'), ''), # remove trailing puncts + (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start + (re.compile('^[.-]'), ''), # remove leading puncts + (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses + (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha + (re.compile(r'\b(pre-alpha|prealpha)\b'), + 'pre.alpha'), # standardise + (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses +) + +_SUFFIX_REPLACEMENTS = ( + (re.compile('^[:~._+-]+'), ''), # remove leading puncts + (re.compile('[,*")([\\]]'), ''), # remove unwanted chars + (re.compile('[~:+_ -]'), '.'), # replace illegal chars + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\.$'), ''), # trailing '.' +) + +_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') + + +def _suggest_semantic_version(s): + """ + Try to suggest a semantic form for a version for which + _suggest_normalized_version couldn't come up with anything. + """ + result = s.strip().lower() + for pat, repl in _REPLACEMENTS: + result = pat.sub(repl, result) + if not result: + result = '0.0.0' + + # Now look for numeric prefix, and separate it out from + # the rest. + #import pdb; pdb.set_trace() + m = _NUMERIC_PREFIX.match(result) + if not m: + prefix = '0.0.0' + suffix = result + else: + prefix = m.groups()[0].split('.') + prefix = [int(i) for i in prefix] + while len(prefix) < 3: + prefix.append(0) + if len(prefix) == 3: + suffix = result[m.end():] + else: + suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] + prefix = prefix[:3] + prefix = '.'.join([str(i) for i in prefix]) + suffix = suffix.strip() + if suffix: + #import pdb; pdb.set_trace() + # massage the suffix. + for pat, repl in _SUFFIX_REPLACEMENTS: + suffix = pat.sub(repl, suffix) + + if not suffix: + result = prefix + else: + sep = '-' if 'dev' in suffix else '+' + result = prefix + sep + suffix + if not is_semver(result): + result = None + return result + + +def _suggest_normalized_version(s): + """Suggest a normalized version close to the given version string. + + If you have a version string that isn't rational (i.e. NormalizedVersion + doesn't like it) then you might be able to get an equivalent (or close) + rational version from this function. + + This does a number of simple normalizations to the given string, based + on observation of versions currently in use on PyPI. Given a dump of + those version during PyCon 2009, 4287 of them: + - 2312 (53.93%) match NormalizedVersion without change + with the automatic suggestion + - 3474 (81.04%) match when using this suggestion method + + @param s {str} An irrational version string. + @returns A rational version string, or None, if couldn't determine one. + """ + try: + _normalized_key(s) + return s # already rational + except UnsupportedVersionError: + pass + + rs = s.lower() + + # part of this could use maketrans + for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), + ('beta', 'b'), ('rc', 'c'), ('-final', ''), + ('-pre', 'c'), + ('-release', ''), ('.release', ''), ('-stable', ''), + ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), + ('final', '')): + rs = rs.replace(orig, repl) + + # if something ends with dev or pre, we add a 0 + rs = re.sub(r"pre$", r"pre0", rs) + rs = re.sub(r"dev$", r"dev0", rs) + + # if we have something like "b-2" or "a.2" at the end of the + # version, that is probably beta, alpha, etc + # let's remove the dash or dot + rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) + + # 1.0-dev-r371 -> 1.0.dev371 + # 0.1-dev-r79 -> 0.1.dev79 + rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) + + # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 + rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) + + # Clean: v0.3, v1.0 + if rs.startswith('v'): + rs = rs[1:] + + # Clean leading '0's on numbers. + #TODO: unintended side-effect on, e.g., "2003.05.09" + # PyPI stats: 77 (~2%) better + rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) + + # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers + # zero. + # PyPI stats: 245 (7.56%) better + rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) + + # the 'dev-rNNN' tag is a dev tag + rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) + + # clean the - when used as a pre delimiter + rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) + + # a terminal "dev" or "devel" can be changed into ".dev0" + rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) + + # a terminal "dev" can be changed into ".dev0" + rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) + + # a terminal "final" or "stable" can be removed + rs = re.sub(r"(final|stable)$", "", rs) + + # The 'r' and the '-' tags are post release tags + # 0.4a1.r10 -> 0.4a1.post10 + # 0.9.33-17222 -> 0.9.33.post17222 + # 0.9.33-r17222 -> 0.9.33.post17222 + rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) + + # Clean 'r' instead of 'dev' usage: + # 0.9.33+r17222 -> 0.9.33.dev17222 + # 1.0dev123 -> 1.0.dev123 + # 1.0.git123 -> 1.0.dev123 + # 1.0.bzr123 -> 1.0.dev123 + # 0.1a0dev.123 -> 0.1a0.dev123 + # PyPI stats: ~150 (~4%) better + rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) + + # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: + # 0.2.pre1 -> 0.2c1 + # 0.2-c1 -> 0.2c1 + # 1.0preview123 -> 1.0c123 + # PyPI stats: ~21 (0.62%) better + rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) + + # Tcl/Tk uses "px" for their post release markers + rs = re.sub(r"p(\d+)$", r".post\1", rs) + + try: + _normalized_key(rs) + except UnsupportedVersionError: + rs = None + return rs + +# +# Legacy version processing (distribute-compatible) +# + +_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) +_VERSION_REPLACE = { + 'pre': 'c', + 'preview': 'c', + '-': 'final-', + 'rc': 'c', + 'dev': '@', + '': None, + '.': None, +} + + +def _legacy_key(s): + def get_parts(s): + result = [] + for p in _VERSION_PART.split(s.lower()): + p = _VERSION_REPLACE.get(p, p) + if p: + if '0' <= p[:1] <= '9': + p = p.zfill(8) + else: + p = '*' + p + result.append(p) + result.append('*final') + return result + + result = [] + for p in get_parts(s): + if p.startswith('*'): + if p < '*final': + while result and result[-1] == '*final-': + result.pop() + while result and result[-1] == '00000000': + result.pop() + result.append(p) + return tuple(result) + + +class LegacyVersion(Version): + def parse(self, s): + return _legacy_key(s) + + @property + def is_prerelease(self): + result = False + for x in self._parts: + if (isinstance(x, string_types) and x.startswith('*') and + x < '*final'): + result = True + break + return result + + +class LegacyMatcher(Matcher): + version_class = LegacyVersion + + _operators = dict(Matcher._operators) + _operators['~='] = '_match_compatible' + + numeric_re = re.compile(r'^(\d+(\.\d+)*)') + + def _match_compatible(self, version, constraint, prefix): + if version < constraint: + return False + m = self.numeric_re.match(str(constraint)) + if not m: + logger.warning('Cannot compute compatible match for version %s ' + ' and constraint %s', version, constraint) + return True + s = m.groups()[0] + if '.' in s: + s = s.rsplit('.', 1)[0] + return _match_prefix(version, s) + +# +# Semantic versioning +# + +_SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' + r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' + r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) + + +def is_semver(s): + return _SEMVER_RE.match(s) + + +def _semantic_key(s): + def make_tuple(s, absent): + if s is None: + result = (absent,) + else: + parts = s[1:].split('.') + # We can't compare ints and strings on Python 3, so fudge it + # by zero-filling numeric values so simulate a numeric comparison + result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) + return result + + m = is_semver(s) + if not m: + raise UnsupportedVersionError(s) + groups = m.groups() + major, minor, patch = [int(i) for i in groups[:3]] + # choose the '|' and '*' so that versions sort correctly + pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') + return (major, minor, patch), pre, build + + +class SemanticVersion(Version): + def parse(self, s): + return _semantic_key(s) + + @property + def is_prerelease(self): + return self._parts[1][0] != '|' + + +class SemanticMatcher(Matcher): + version_class = SemanticVersion + + +class VersionScheme(object): + def __init__(self, key, matcher, suggester=None): + self.key = key + self.matcher = matcher + self.suggester = suggester + + def is_valid_version(self, s): + try: + self.matcher.version_class(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_matcher(self, s): + try: + self.matcher(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_constraint_list(self, s): + """ + Used for processing some metadata fields + """ + return self.is_valid_matcher('dummy_name (%s)' % s) + + def suggest(self, s): + if self.suggester is None: + result = None + else: + result = self.suggester(s) + return result + +_SCHEMES = { + 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, + _suggest_normalized_version), + 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), + 'semantic': VersionScheme(_semantic_key, SemanticMatcher, + _suggest_semantic_version), +} + +_SCHEMES['default'] = _SCHEMES['normalized'] + + +def get_scheme(name): + if name not in _SCHEMES: + raise ValueError('unknown scheme name: %r' % name) + return _SCHEMES[name] diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w32.exe b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w32.exe new file mode 100644 index 0000000..732215a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w32.exe differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w64.exe b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w64.exe new file mode 100644 index 0000000..c41bd0a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/w64.exe differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/wheel.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/wheel.py new file mode 100644 index 0000000..7737223 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distlib/wheel.py @@ -0,0 +1,984 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import base64 +import codecs +import datetime +import distutils.util +from email import message_from_file +import hashlib +import imp +import json +import logging +import os +import posixpath +import re +import shutil +import sys +import tempfile +import zipfile + +from . import __version__, DistlibException +from .compat import sysconfig, ZipFile, fsdecode, text_type, filter +from .database import InstalledDistribution +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, + cached_property, get_cache_base, read_exports, tempdir) +from .version import NormalizedVersion, UnsupportedVersionError + +logger = logging.getLogger(__name__) + +cache = None # created when needed + +if hasattr(sys, 'pypy_version_info'): # pragma: no cover + IMP_PREFIX = 'pp' +elif sys.platform.startswith('java'): # pragma: no cover + IMP_PREFIX = 'jy' +elif sys.platform == 'cli': # pragma: no cover + IMP_PREFIX = 'ip' +else: + IMP_PREFIX = 'cp' + +VER_SUFFIX = sysconfig.get_config_var('py_version_nodot') +if not VER_SUFFIX: # pragma: no cover + VER_SUFFIX = '%s%s' % sys.version_info[:2] +PYVER = 'py' + VER_SUFFIX +IMPVER = IMP_PREFIX + VER_SUFFIX + +ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_') + +ABI = sysconfig.get_config_var('SOABI') +if ABI and ABI.startswith('cpython-'): + ABI = ABI.replace('cpython-', 'cp') +else: + def _derive_abi(): + parts = ['cp', VER_SUFFIX] + if sysconfig.get_config_var('Py_DEBUG'): + parts.append('d') + if sysconfig.get_config_var('WITH_PYMALLOC'): + parts.append('m') + if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: + parts.append('u') + return ''.join(parts) + ABI = _derive_abi() + del _derive_abi + +FILENAME_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))? +-(?P<py>\w+\d+(\.\w+\d+)*) +-(?P<bi>\w+) +-(?P<ar>\w+(\.\w+)*) +\.whl$ +''', re.IGNORECASE | re.VERBOSE) + +NAME_VERSION_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))?$ +''', re.IGNORECASE | re.VERBOSE) + +SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') +SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') +SHEBANG_PYTHON = b'#!python' +SHEBANG_PYTHONW = b'#!pythonw' + +if os.sep == '/': + to_posix = lambda o: o +else: + to_posix = lambda o: o.replace(os.sep, '/') + + +class Mounter(object): + def __init__(self): + self.impure_wheels = {} + self.libs = {} + + def add(self, pathname, extensions): + self.impure_wheels[pathname] = extensions + self.libs.update(extensions) + + def remove(self, pathname): + extensions = self.impure_wheels.pop(pathname) + for k, v in extensions: + if k in self.libs: + del self.libs[k] + + def find_module(self, fullname, path=None): + if fullname in self.libs: + result = self + else: + result = None + return result + + def load_module(self, fullname): + if fullname in sys.modules: + result = sys.modules[fullname] + else: + if fullname not in self.libs: + raise ImportError('unable to find extension for %s' % fullname) + result = imp.load_dynamic(fullname, self.libs[fullname]) + result.__loader__ = self + parts = fullname.rsplit('.', 1) + if len(parts) > 1: + result.__package__ = parts[0] + return result + +_hook = Mounter() + + +class Wheel(object): + """ + Class to build and install from Wheel files (PEP 427). + """ + + wheel_version = (1, 1) + hash_kind = 'sha256' + + def __init__(self, filename=None, sign=False, verify=False): + """ + Initialise an instance using a (valid) filename. + """ + self.sign = sign + self.should_verify = verify + self.buildver = '' + self.pyver = [PYVER] + self.abi = ['none'] + self.arch = ['any'] + self.dirname = os.getcwd() + if filename is None: + self.name = 'dummy' + self.version = '0.1' + self._filename = self.filename + else: + m = NAME_VERSION_RE.match(filename) + if m: + info = m.groupdict('') + self.name = info['nm'] + # Reinstate the local version separator + self.version = info['vn'].replace('_', '-') + self.buildver = info['bn'] + self._filename = self.filename + else: + dirname, filename = os.path.split(filename) + m = FILENAME_RE.match(filename) + if not m: + raise DistlibException('Invalid name or ' + 'filename: %r' % filename) + if dirname: + self.dirname = os.path.abspath(dirname) + self._filename = filename + info = m.groupdict('') + self.name = info['nm'] + self.version = info['vn'] + self.buildver = info['bn'] + self.pyver = info['py'].split('.') + self.abi = info['bi'].split('.') + self.arch = info['ar'].split('.') + + @property + def filename(self): + """ + Build and return a filename from the various components. + """ + if self.buildver: + buildver = '-' + self.buildver + else: + buildver = '' + pyver = '.'.join(self.pyver) + abi = '.'.join(self.abi) + arch = '.'.join(self.arch) + # replace - with _ as a local version separator + version = self.version.replace('-', '_') + return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, + pyver, abi, arch) + + @property + def exists(self): + path = os.path.join(self.dirname, self.filename) + return os.path.isfile(path) + + @property + def tags(self): + for pyver in self.pyver: + for abi in self.abi: + for arch in self.arch: + yield pyver, abi, arch + + @cached_property + def metadata(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + wrapper = codecs.getreader('utf-8') + with ZipFile(pathname, 'r') as zf: + wheel_metadata = self.get_wheel_metadata(zf) + wv = wheel_metadata['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if file_version < (1, 1): + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, 'METADATA'] + else: + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] + result = None + for fn in fns: + try: + metadata_filename = posixpath.join(info_dir, fn) + with zf.open(metadata_filename) as bf: + wf = wrapper(bf) + result = Metadata(fileobj=wf) + if result: + break + except KeyError: + pass + if not result: + raise ValueError('Invalid wheel, because metadata is ' + 'missing: looked in %s' % ', '.join(fns)) + return result + + def get_wheel_metadata(self, zf): + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + metadata_filename = posixpath.join(info_dir, 'WHEEL') + with zf.open(metadata_filename) as bf: + wf = codecs.getreader('utf-8')(bf) + message = message_from_file(wf) + return dict(message) + + @cached_property + def info(self): + pathname = os.path.join(self.dirname, self.filename) + with ZipFile(pathname, 'r') as zf: + result = self.get_wheel_metadata(zf) + return result + + def process_shebang(self, data): + m = SHEBANG_RE.match(data) + if m: + end = m.end() + shebang, data_after_shebang = data[:end], data[end:] + # Preserve any arguments after the interpreter + if b'pythonw' in shebang.lower(): + shebang_python = SHEBANG_PYTHONW + else: + shebang_python = SHEBANG_PYTHON + m = SHEBANG_DETAIL_RE.match(shebang) + if m: + args = b' ' + m.groups()[-1] + else: + args = b'' + shebang = shebang_python + args + data = shebang + data_after_shebang + else: + cr = data.find(b'\r') + lf = data.find(b'\n') + if cr < 0 or cr > lf: + term = b'\n' + else: + if data[cr:cr + 2] == b'\r\n': + term = b'\r\n' + else: + term = b'\r' + data = SHEBANG_PYTHON + term + data + return data + + def get_hash(self, data, hash_kind=None): + if hash_kind is None: + hash_kind = self.hash_kind + try: + hasher = getattr(hashlib, hash_kind) + except AttributeError: + raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) + result = hasher(data).digest() + result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') + return hash_kind, result + + def write_record(self, records, record_path, base): + records = list(records) # make a copy for sorting + p = to_posix(os.path.relpath(record_path, base)) + records.append((p, '', '')) + records.sort() + with CSVWriter(record_path) as writer: + for row in records: + writer.writerow(row) + + def write_records(self, info, libdir, archive_paths): + records = [] + distinfo, info_dir = info + hasher = getattr(hashlib, self.hash_kind) + for ap, p in archive_paths: + with open(p, 'rb') as f: + data = f.read() + digest = '%s=%s' % self.get_hash(data) + size = os.path.getsize(p) + records.append((ap, digest, size)) + + p = os.path.join(distinfo, 'RECORD') + self.write_record(records, p, libdir) + ap = to_posix(os.path.join(info_dir, 'RECORD')) + archive_paths.append((ap, p)) + + def build_zip(self, pathname, archive_paths): + with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: + for ap, p in archive_paths: + logger.debug('Wrote %s to %s in wheel', p, ap) + zf.write(p, ap) + + def build(self, paths, tags=None, wheel_version=None): + """ + Build a wheel from files in specified paths, and use any specified tags + when determining the name of the wheel. + """ + if tags is None: + tags = {} + + libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] + if libkey == 'platlib': + is_pure = 'false' + default_pyver = [IMPVER] + default_abi = [ABI] + default_arch = [ARCH] + else: + is_pure = 'true' + default_pyver = [PYVER] + default_abi = ['none'] + default_arch = ['any'] + + self.pyver = tags.get('pyver', default_pyver) + self.abi = tags.get('abi', default_abi) + self.arch = tags.get('arch', default_arch) + + libdir = paths[libkey] + + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + archive_paths = [] + + # First, stuff which is not in site-packages + for key in ('data', 'headers', 'scripts'): + if key not in paths: + continue + path = paths[key] + if os.path.isdir(path): + for root, dirs, files in os.walk(path): + for fn in files: + p = fsdecode(os.path.join(root, fn)) + rp = os.path.relpath(p, path) + ap = to_posix(os.path.join(data_dir, key, rp)) + archive_paths.append((ap, p)) + if key == 'scripts' and not p.endswith('.exe'): + with open(p, 'rb') as f: + data = f.read() + data = self.process_shebang(data) + with open(p, 'wb') as f: + f.write(data) + + # Now, stuff which is in site-packages, other than the + # distinfo stuff. + path = libdir + distinfo = None + for root, dirs, files in os.walk(path): + if root == path: + # At the top level only, save distinfo for later + # and skip it for now + for i, dn in enumerate(dirs): + dn = fsdecode(dn) + if dn.endswith('.dist-info'): + distinfo = os.path.join(root, dn) + del dirs[i] + break + assert distinfo, '.dist-info directory expected, not found' + + for fn in files: + # comment out next suite to leave .pyc files in + if fsdecode(fn).endswith(('.pyc', '.pyo')): + continue + p = os.path.join(root, fn) + rp = to_posix(os.path.relpath(p, path)) + archive_paths.append((rp, p)) + + # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. + files = os.listdir(distinfo) + for fn in files: + if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): + p = fsdecode(os.path.join(distinfo, fn)) + ap = to_posix(os.path.join(info_dir, fn)) + archive_paths.append((ap, p)) + + wheel_metadata = [ + 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), + 'Generator: distlib %s' % __version__, + 'Root-Is-Purelib: %s' % is_pure, + ] + for pyver, abi, arch in self.tags: + wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) + p = os.path.join(distinfo, 'WHEEL') + with open(p, 'w') as f: + f.write('\n'.join(wheel_metadata)) + ap = to_posix(os.path.join(info_dir, 'WHEEL')) + archive_paths.append((ap, p)) + + # Now, at last, RECORD. + # Paths in here are archive paths - nothing else makes sense. + self.write_records((distinfo, info_dir), libdir, archive_paths) + # Now, ready to build the zip file + pathname = os.path.join(self.dirname, self.filename) + self.build_zip(pathname, archive_paths) + return pathname + + def install(self, paths, maker, **kwargs): + """ + Install a wheel to the specified paths. If kwarg ``warner`` is + specified, it should be a callable, which will be called with two + tuples indicating the wheel version of this software and the wheel + version in the file, if there is a discrepancy in the versions. + This can be used to issue any warnings to raise any exceptions. + If kwarg ``lib_only`` is True, only the purelib/platlib files are + installed, and the headers, scripts, data and dist-info metadata are + not written. + + The return value is a :class:`InstalledDistribution` instance unless + ``options.lib_only`` is True, in which case the return value is ``None``. + """ + + dry_run = maker.dry_run + warner = kwargs.get('warner') + lib_only = kwargs.get('lib_only', False) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if (file_version != self.wheel_version) and warner: + warner(self.wheel_version, file_version) + + if message['Root-Is-Purelib'] == 'true': + libdir = paths['purelib'] + else: + libdir = paths['platlib'] + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + data_pfx = posixpath.join(data_dir, '') + info_pfx = posixpath.join(info_dir, '') + script_pfx = posixpath.join(data_dir, 'scripts', '') + + # make a new instance rather than a copy of maker's, + # as we mutate it + fileop = FileOperator(dry_run=dry_run) + fileop.record = True # so we can rollback if needed + + bc = not sys.dont_write_bytecode # Double negatives. Lovely! + + outfiles = [] # for RECORD writing + + # for script copying/shebang processing + workdir = tempfile.mkdtemp() + # set target dir later + # we default add_launchers to False, as the + # Python Launcher should be used instead + maker.source_dir = workdir + maker.target_dir = None + try: + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + if lib_only and u_arcname.startswith((info_pfx, data_pfx)): + logger.debug('lib_only: skipping %s', u_arcname) + continue + is_script = (u_arcname.startswith(script_pfx) + and not u_arcname.endswith('.exe')) + + if u_arcname.startswith(data_pfx): + _, where, rp = u_arcname.split('/', 2) + outfile = os.path.join(paths[where], convert_path(rp)) + else: + # meant for site-packages. + if u_arcname in (wheel_metadata_name, record_name): + continue + outfile = os.path.join(libdir, convert_path(u_arcname)) + if not is_script: + with zf.open(arcname) as bf: + fileop.copy_stream(bf, outfile) + outfiles.append(outfile) + # Double check the digest of the written file + if not dry_run and row[1]: + with open(outfile, 'rb') as bf: + data = bf.read() + _, newdigest = self.get_hash(data, kind) + if newdigest != digest: + raise DistlibException('digest mismatch ' + 'on write for ' + '%s' % outfile) + if bc and outfile.endswith('.py'): + try: + pyc = fileop.byte_compile(outfile) + outfiles.append(pyc) + except Exception: + # Don't give up if byte-compilation fails, + # but log it and perhaps warn the user + logger.warning('Byte-compilation failed', + exc_info=True) + else: + fn = os.path.basename(convert_path(arcname)) + workname = os.path.join(workdir, fn) + with zf.open(arcname) as bf: + fileop.copy_stream(bf, workname) + + dn, fn = os.path.split(outfile) + maker.target_dir = dn + filenames = maker.make(fn) + fileop.set_executable_mode(filenames) + outfiles.extend(filenames) + + if lib_only: + logger.debug('lib_only: returning None') + dist = None + else: + # Generate scripts + + # Try to get pydist.json so we can see if there are + # any commands to generate. If this fails (e.g. because + # of a legacy wheel), log a warning but don't give up. + commands = None + file_version = self.info['Wheel-Version'] + if file_version == '1.0': + # Use legacy info + ep = posixpath.join(info_dir, 'entry_points.txt') + try: + with zf.open(ep) as bwf: + epdata = read_exports(bwf) + commands = {} + for key in ('console', 'gui'): + k = '%s_scripts' % key + if k in epdata: + commands['wrap_%s' % key] = d = {} + for v in epdata[k].values(): + s = '%s:%s' % (v.prefix, v.suffix) + if v.flags: + s += ' %s' % v.flags + d[v.name] = s + except Exception: + logger.warning('Unable to read legacy script ' + 'metadata, so cannot generate ' + 'scripts') + else: + try: + with zf.open(metadata_name) as bwf: + wf = wrapper(bwf) + commands = json.load(wf).get('extensions') + if commands: + commands = commands.get('python.commands') + except Exception: + logger.warning('Unable to read JSON metadata, so ' + 'cannot generate scripts') + if commands: + console_scripts = commands.get('wrap_console', {}) + gui_scripts = commands.get('wrap_gui', {}) + if console_scripts or gui_scripts: + script_dir = paths.get('scripts', '') + if not os.path.isdir(script_dir): + raise ValueError('Valid script path not ' + 'specified') + maker.target_dir = script_dir + for k, v in console_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script) + fileop.set_executable_mode(filenames) + + if gui_scripts: + options = {'gui': True } + for k, v in gui_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script, options) + fileop.set_executable_mode(filenames) + + p = os.path.join(libdir, info_dir) + dist = InstalledDistribution(p) + + # Write SHARED + paths = dict(paths) # don't change passed in dict + del paths['purelib'] + del paths['platlib'] + paths['lib'] = libdir + p = dist.write_shared_locations(paths, dry_run) + if p: + outfiles.append(p) + + # Write RECORD + dist.write_installed_files(outfiles, paths['prefix'], + dry_run) + return dist + except Exception: # pragma: no cover + logger.exception('installation failed.') + fileop.rollback() + raise + finally: + shutil.rmtree(workdir) + + def _get_dylib_cache(self): + global cache + if cache is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('dylib-cache'), + sys.version[:3]) + cache = Cache(base) + return cache + + def _get_extensions(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + arcname = posixpath.join(info_dir, 'EXTENSIONS') + wrapper = codecs.getreader('utf-8') + result = [] + with ZipFile(pathname, 'r') as zf: + try: + with zf.open(arcname) as bf: + wf = wrapper(bf) + extensions = json.load(wf) + cache = self._get_dylib_cache() + prefix = cache.prefix_to_dir(pathname) + cache_base = os.path.join(cache.base, prefix) + if not os.path.isdir(cache_base): + os.makedirs(cache_base) + for name, relpath in extensions.items(): + dest = os.path.join(cache_base, convert_path(relpath)) + if not os.path.exists(dest): + extract = True + else: + file_time = os.stat(dest).st_mtime + file_time = datetime.datetime.fromtimestamp(file_time) + info = zf.getinfo(relpath) + wheel_time = datetime.datetime(*info.date_time) + extract = wheel_time > file_time + if extract: + zf.extract(relpath, cache_base) + result.append((name, dest)) + except KeyError: + pass + return result + + def is_compatible(self): + """ + Determine if a wheel is compatible with the running system. + """ + return is_compatible(self) + + def is_mountable(self): + """ + Determine if a wheel is asserted as mountable by its metadata. + """ + return True # for now - metadata details TBD + + def mount(self, append=False): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if not self.is_compatible(): + msg = 'Wheel %s not compatible with this Python.' % pathname + raise DistlibException(msg) + if not self.is_mountable(): + msg = 'Wheel %s is marked as not mountable.' % pathname + raise DistlibException(msg) + if pathname in sys.path: + logger.debug('%s already in path', pathname) + else: + if append: + sys.path.append(pathname) + else: + sys.path.insert(0, pathname) + extensions = self._get_extensions() + if extensions: + if _hook not in sys.meta_path: + sys.meta_path.append(_hook) + _hook.add(pathname, extensions) + + def unmount(self): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if pathname not in sys.path: + logger.debug('%s not in path', pathname) + else: + sys.path.remove(pathname) + if pathname in _hook.impure_wheels: + _hook.remove(pathname) + if not _hook.impure_wheels: + if _hook in sys.meta_path: + sys.meta_path.remove(_hook) + + def verify(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + # TODO version verification + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + def update(self, modifier, dest_dir=None, **kwargs): + """ + Update the contents of a wheel in a generic way. The modifier should + be a callable which expects a dictionary argument: its keys are + archive-entry paths, and its values are absolute filesystem paths + where the contents the corresponding archive entries can be found. The + modifier is free to change the contents of the files pointed to, add + new entries and remove entries, before returning. This method will + extract the entire contents of the wheel to a temporary location, call + the modifier, and then use the passed (and possibly updated) + dictionary to write a new wheel. If ``dest_dir`` is specified, the new + wheel is written there -- otherwise, the original wheel is overwritten. + + The modifier should return True if it updated the wheel, else False. + This method returns the same value the modifier returns. + """ + + def get_version(path_map, info_dir): + version = path = None + key = '%s/%s' % (info_dir, METADATA_FILENAME) + if key not in path_map: + key = '%s/PKG-INFO' % info_dir + if key in path_map: + path = path_map[key] + version = Metadata(path=path).version + return version, path + + def update_version(version, path): + updated = None + try: + v = NormalizedVersion(version) + i = version.find('-') + if i < 0: + updated = '%s+1' % version + else: + parts = [int(s) for s in version[i + 1:].split('.')] + parts[-1] += 1 + updated = '%s+%s' % (version[:i], + '.'.join(str(i) for i in parts)) + except UnsupportedVersionError: + logger.debug('Cannot update non-compliant (PEP-440) ' + 'version %r', version) + if updated: + md = Metadata(path=path) + md.version = updated + legacy = not path.endswith(METADATA_FILENAME) + md.write(path=path, legacy=legacy) + logger.debug('Version updated from %r to %r', version, + updated) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + record_name = posixpath.join(info_dir, 'RECORD') + with tempdir() as workdir: + with ZipFile(pathname, 'r') as zf: + path_map = {} + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if u_arcname == record_name: + continue + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + zf.extract(zinfo, workdir) + path = os.path.join(workdir, convert_path(u_arcname)) + path_map[u_arcname] = path + + # Remember the version. + original_version, _ = get_version(path_map, info_dir) + # Files extracted. Call the modifier. + modified = modifier(path_map, **kwargs) + if modified: + # Something changed - need to build a new wheel. + current_version, path = get_version(path_map, info_dir) + if current_version and (current_version == original_version): + # Add or update local version to signify changes. + update_version(current_version, path) + # Decide where the new wheel goes. + if dest_dir is None: + fd, newpath = tempfile.mkstemp(suffix='.whl', + prefix='wheel-update-', + dir=workdir) + os.close(fd) + else: + if not os.path.isdir(dest_dir): + raise DistlibException('Not a directory: %r' % dest_dir) + newpath = os.path.join(dest_dir, self.filename) + archive_paths = list(path_map.items()) + distinfo = os.path.join(workdir, info_dir) + info = distinfo, info_dir + self.write_records(info, workdir, archive_paths) + self.build_zip(newpath, archive_paths) + if dest_dir is None: + shutil.copyfile(newpath, pathname) + return modified + +def compatible_tags(): + """ + Return (pyver, abi, arch) tuples compatible with this Python. + """ + versions = [VER_SUFFIX] + major = VER_SUFFIX[0] + for minor in range(sys.version_info[1] - 1, - 1, -1): + versions.append(''.join([major, str(minor)])) + + abis = [] + for suffix, _, _ in imp.get_suffixes(): + if suffix.startswith('.abi'): + abis.append(suffix.split('.', 2)[1]) + abis.sort() + if ABI != 'none': + abis.insert(0, ABI) + abis.append('none') + result = [] + + arches = [ARCH] + if sys.platform == 'darwin': + m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) + if m: + name, major, minor, arch = m.groups() + minor = int(minor) + matches = [arch] + if arch in ('i386', 'ppc'): + matches.append('fat') + if arch in ('i386', 'ppc', 'x86_64'): + matches.append('fat3') + if arch in ('ppc64', 'x86_64'): + matches.append('fat64') + if arch in ('i386', 'x86_64'): + matches.append('intel') + if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): + matches.append('universal') + while minor >= 0: + for match in matches: + s = '%s_%s_%s_%s' % (name, major, minor, match) + if s != ARCH: # already there + arches.append(s) + minor -= 1 + + # Most specific - our Python version, ABI and arch + for abi in abis: + for arch in arches: + result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) + + # where no ABI / arch dependency, but IMP_PREFIX dependency + for i, version in enumerate(versions): + result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) + if i == 0: + result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) + + # no IMP_PREFIX, ABI or arch dependency + for i, version in enumerate(versions): + result.append((''.join(('py', version)), 'none', 'any')) + if i == 0: + result.append((''.join(('py', version[0])), 'none', 'any')) + return set(result) + + +COMPATIBLE_TAGS = compatible_tags() + +del compatible_tags + + +def is_compatible(wheel, tags=None): + if not isinstance(wheel, Wheel): + wheel = Wheel(wheel) # assume it's a filename + result = False + if tags is None: + tags = COMPATIBLE_TAGS + for ver, abi, arch in tags: + if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: + result = True + break + return result diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distro.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distro.py new file mode 100644 index 0000000..39bfce7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/distro.py @@ -0,0 +1,1104 @@ +# Copyright 2015,2016 Nir Cohen +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +The ``distro`` package (``distro`` stands for Linux Distribution) provides +information about the Linux distribution it runs on, such as a reliable +machine-readable distro ID, or version information. + +It is a renewed alternative implementation for Python's original +:py:func:`platform.linux_distribution` function, but it provides much more +functionality. An alternative implementation became necessary because Python +3.5 deprecated this function, and Python 3.7 is expected to remove it +altogether. Its predecessor function :py:func:`platform.dist` was already +deprecated since Python 2.6 and is also expected to be removed in Python 3.7. +Still, there are many cases in which access to Linux distribution information +is needed. See `Python issue 1322 <https://bugs.python.org/issue1322>`_ for +more information. +""" + +import os +import re +import sys +import json +import shlex +import logging +import argparse +import subprocess + + +_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') +_OS_RELEASE_BASENAME = 'os-release' + +#: Translation table for normalizing the "ID" attribute defined in os-release +#: files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as defined in the os-release file, translated to lower case, +#: with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_OS_ID = {} + +#: Translation table for normalizing the "Distributor ID" attribute returned by +#: the lsb_release command, for use by the :func:`distro.id` method. +#: +#: * Key: Value as returned by the lsb_release command, translated to lower +#: case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_LSB_ID = { + 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux + 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation + 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server +} + +#: Translation table for normalizing the distro ID derived from the file name +#: of distro release files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as derived from the file name of a distro release file, +#: translated to lower case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_DISTRO_ID = { + 'redhat': 'rhel', # RHEL 6.x, 7.x +} + +# Pattern for content of distro release file (reversed) +_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( + r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') + +# Pattern for base file name of distro release file +_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( + r'(\w+)[-_](release|version)$') + +# Base file names to be ignored when searching for distro release file +_DISTRO_RELEASE_IGNORE_BASENAMES = ( + 'debian_version', + 'lsb-release', + 'oem-release', + _OS_RELEASE_BASENAME, + 'system-release' +) + + +def linux_distribution(full_distribution_name=True): + """ + Return information about the current Linux distribution as a tuple + ``(id_name, version, codename)`` with items as follows: + + * ``id_name``: If *full_distribution_name* is false, the result of + :func:`distro.id`. Otherwise, the result of :func:`distro.name`. + + * ``version``: The result of :func:`distro.version`. + + * ``codename``: The result of :func:`distro.codename`. + + The interface of this function is compatible with the original + :py:func:`platform.linux_distribution` function, supporting a subset of + its parameters. + + The data it returns may not exactly be the same, because it uses more data + sources than the original function, and that may lead to different data if + the Linux distribution is not consistent across multiple data sources it + provides (there are indeed such distributions ...). + + Another reason for differences is the fact that the :func:`distro.id` + method normalizes the distro ID string to a reliable machine-readable value + for a number of popular Linux distributions. + """ + return _distro.linux_distribution(full_distribution_name) + + +def id(): + """ + Return the distro ID of the current Linux distribution, as a + machine-readable string. + + For a number of Linux distributions, the returned distro ID value is + *reliable*, in the sense that it is documented and that it does not change + across releases of the distribution. + + This package maintains the following reliable distro ID values: + + ============== ========================================= + Distro ID Distribution + ============== ========================================= + "ubuntu" Ubuntu + "debian" Debian + "rhel" RedHat Enterprise Linux + "centos" CentOS + "fedora" Fedora + "sles" SUSE Linux Enterprise Server + "opensuse" openSUSE + "amazon" Amazon Linux + "arch" Arch Linux + "cloudlinux" CloudLinux OS + "exherbo" Exherbo Linux + "gentoo" GenToo Linux + "ibm_powerkvm" IBM PowerKVM + "kvmibm" KVM for IBM z Systems + "linuxmint" Linux Mint + "mageia" Mageia + "mandriva" Mandriva Linux + "parallels" Parallels + "pidora" Pidora + "raspbian" Raspbian + "oracle" Oracle Linux (and Oracle Enterprise Linux) + "scientific" Scientific Linux + "slackware" Slackware + "xenserver" XenServer + ============== ========================================= + + If you have a need to get distros for reliable IDs added into this set, + or if you find that the :func:`distro.id` function returns a different + distro ID for one of the listed distros, please create an issue in the + `distro issue tracker`_. + + **Lookup hierarchy and transformations:** + + First, the ID is obtained from the following sources, in the specified + order. The first available and non-empty value is used: + + * the value of the "ID" attribute of the os-release file, + + * the value of the "Distributor ID" attribute returned by the lsb_release + command, + + * the first part of the file name of the distro release file, + + The so determined ID value then passes the following transformations, + before it is returned by this method: + + * it is translated to lower case, + + * blanks (which should not be there anyway) are translated to underscores, + + * a normalization of the ID is performed, based upon + `normalization tables`_. The purpose of this normalization is to ensure + that the ID is as reliable as possible, even across incompatible changes + in the Linux distributions. A common reason for an incompatible change is + the addition of an os-release file, or the addition of the lsb_release + command, with ID values that differ from what was previously determined + from the distro release file name. + """ + return _distro.id() + + +def name(pretty=False): + """ + Return the name of the current Linux distribution, as a human-readable + string. + + If *pretty* is false, the name is returned without version or codename. + (e.g. "CentOS Linux") + + If *pretty* is true, the version and codename are appended. + (e.g. "CentOS Linux 7.1.1503 (Core)") + + **Lookup hierarchy:** + + The name is obtained from the following sources, in the specified order. + The first available and non-empty value is used: + + * If *pretty* is false: + + - the value of the "NAME" attribute of the os-release file, + + - the value of the "Distributor ID" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file. + + * If *pretty* is true: + + - the value of the "PRETTY_NAME" attribute of the os-release file, + + - the value of the "Description" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file, appended + with the value of the pretty version ("<version_id>" and "<codename>" + fields) of the distro release file, if available. + """ + return _distro.name(pretty) + + +def version(pretty=False, best=False): + """ + Return the version of the current Linux distribution, as a human-readable + string. + + If *pretty* is false, the version is returned without codename (e.g. + "7.0"). + + If *pretty* is true, the codename in parenthesis is appended, if the + codename is non-empty (e.g. "7.0 (Maipo)"). + + Some distributions provide version numbers with different precisions in + the different sources of distribution information. Examining the different + sources in a fixed priority order does not always yield the most precise + version (e.g. for Debian 8.2, or CentOS 7.1). + + The *best* parameter can be used to control the approach for the returned + version: + + If *best* is false, the first non-empty version number in priority order of + the examined sources is returned. + + If *best* is true, the most precise version number out of all examined + sources is returned. + + **Lookup hierarchy:** + + In all cases, the version number is obtained from the following sources. + If *best* is false, this order represents the priority order: + + * the value of the "VERSION_ID" attribute of the os-release file, + * the value of the "Release" attribute returned by the lsb_release + command, + * the version number parsed from the "<version_id>" field of the first line + of the distro release file, + * the version number parsed from the "PRETTY_NAME" attribute of the + os-release file, if it follows the format of the distro release files. + * the version number parsed from the "Description" attribute returned by + the lsb_release command, if it follows the format of the distro release + files. + """ + return _distro.version(pretty, best) + + +def version_parts(best=False): + """ + Return the version of the current Linux distribution as a tuple + ``(major, minor, build_number)`` with items as follows: + + * ``major``: The result of :func:`distro.major_version`. + + * ``minor``: The result of :func:`distro.minor_version`. + + * ``build_number``: The result of :func:`distro.build_number`. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.version_parts(best) + + +def major_version(best=False): + """ + Return the major version of the current Linux distribution, as a string, + if provided. + Otherwise, the empty string is returned. The major version is the first + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.major_version(best) + + +def minor_version(best=False): + """ + Return the minor version of the current Linux distribution, as a string, + if provided. + Otherwise, the empty string is returned. The minor version is the second + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.minor_version(best) + + +def build_number(best=False): + """ + Return the build number of the current Linux distribution, as a string, + if provided. + Otherwise, the empty string is returned. The build number is the third part + of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.build_number(best) + + +def like(): + """ + Return a space-separated list of distro IDs of distributions that are + closely related to the current Linux distribution in regards to packaging + and programming interfaces, for example distributions the current + distribution is a derivative from. + + **Lookup hierarchy:** + + This information item is only provided by the os-release file. + For details, see the description of the "ID_LIKE" attribute in the + `os-release man page + <http://www.freedesktop.org/software/systemd/man/os-release.html>`_. + """ + return _distro.like() + + +def codename(): + """ + Return the codename for the release of the current Linux distribution, + as a string. + + If the distribution does not have a codename, an empty string is returned. + + Note that the returned codename is not always really a codename. For + example, openSUSE returns "x86_64". This function does not handle such + cases in any special way and just returns the string it finds, if any. + + **Lookup hierarchy:** + + * the codename within the "VERSION" attribute of the os-release file, if + provided, + + * the value of the "Codename" attribute returned by the lsb_release + command, + + * the value of the "<codename>" field of the distro release file. + """ + return _distro.codename() + + +def info(pretty=False, best=False): + """ + Return certain machine-readable information items about the current Linux + distribution in a dictionary, as shown in the following example: + + .. sourcecode:: python + + { + 'id': 'rhel', + 'version': '7.0', + 'version_parts': { + 'major': '7', + 'minor': '0', + 'build_number': '' + }, + 'like': 'fedora', + 'codename': 'Maipo' + } + + The dictionary structure and keys are always the same, regardless of which + information items are available in the underlying data sources. The values + for the various keys are as follows: + + * ``id``: The result of :func:`distro.id`. + + * ``version``: The result of :func:`distro.version`. + + * ``version_parts -> major``: The result of :func:`distro.major_version`. + + * ``version_parts -> minor``: The result of :func:`distro.minor_version`. + + * ``version_parts -> build_number``: The result of + :func:`distro.build_number`. + + * ``like``: The result of :func:`distro.like`. + + * ``codename``: The result of :func:`distro.codename`. + + For a description of the *pretty* and *best* parameters, see the + :func:`distro.version` method. + """ + return _distro.info(pretty, best) + + +def os_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the os-release file data source of the current Linux distribution. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_info() + + +def lsb_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the lsb_release command data source of the current Linux distribution. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_info() + + +def distro_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current Linux distribution. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_info() + + +def os_release_attr(attribute): + """ + Return a single named information item from the os-release file data source + of the current Linux distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_attr(attribute) + + +def lsb_release_attr(attribute): + """ + Return a single named information item from the lsb_release command output + data source of the current Linux distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_attr(attribute) + + +def distro_release_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current Linux distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_attr(attribute) + + +class cached_property(object): + """A version of @property which caches the value. On access, it calls the + underlying function and sets the value in `__dict__` so future accesses + will not re-call the property. + """ + def __init__(self, f): + self._fname = f.__name__ + self._f = f + + def __get__(self, obj, owner): + assert obj is not None, 'call {} on an instance'.format(self._fname) + ret = obj.__dict__[self._fname] = self._f(obj) + return ret + + +class LinuxDistribution(object): + """ + Provides information about a Linux distribution. + + This package creates a private module-global instance of this class with + default initialization arguments, that is used by the + `consolidated accessor functions`_ and `single source accessor functions`_. + By using default initialization arguments, that module-global instance + returns data about the current Linux distribution (i.e. the distro this + package runs on). + + Normally, it is not necessary to create additional instances of this class. + However, in situations where control is needed over the exact data sources + that are used, instances of this class can be created with a specific + distro release file, or a specific os-release file, or without invoking the + lsb_release command. + """ + + def __init__(self, + include_lsb=True, + os_release_file='', + distro_release_file=''): + """ + The initialization method of this class gathers information from the + available data sources, and stores that in private instance attributes. + Subsequent access to the information items uses these private instance + attributes, so that the data sources are read only once. + + Parameters: + + * ``include_lsb`` (bool): Controls whether the + `lsb_release command output`_ is included as a data source. + + If the lsb_release command is not available in the program execution + path, the data source for the lsb_release command will be empty. + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is to be used as a data source. + + An empty string (the default) will cause the default path name to + be used (see `os-release file`_ for details). + + If the specified or defaulted os-release file does not exist, the + data source for the os-release file will be empty. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is to be used as a data source. + + An empty string (the default) will cause a default search algorithm + to be used (see `distro release file`_ for details). + + If the specified distro release file does not exist, or if no default + distro release file can be found, the data source for the distro + release file will be empty. + + Public instance attributes: + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. + This controls whether the lsb information will be loaded. + + Raises: + + * :py:exc:`IOError`: Some I/O issue with an os-release file or distro + release file. + + * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had + some issue (other than not being available in the program execution + path). + + * :py:exc:`UnicodeError`: A data source has unexpected characters or + uses an unexpected encoding. + """ + self.os_release_file = os_release_file or \ + os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) + self.distro_release_file = distro_release_file or '' # updated later + self.include_lsb = include_lsb + + def __repr__(self): + """Return repr of all info + """ + return \ + "LinuxDistribution(" \ + "os_release_file={self.os_release_file!r}, " \ + "distro_release_file={self.distro_release_file!r}, " \ + "include_lsb={self.include_lsb!r}, " \ + "_os_release_info={self._os_release_info!r}, " \ + "_lsb_release_info={self._lsb_release_info!r}, " \ + "_distro_release_info={self._distro_release_info!r})".format( + self=self) + + def linux_distribution(self, full_distribution_name=True): + """ + Return information about the Linux distribution that is compatible + with Python's :func:`platform.linux_distribution`, supporting a subset + of its parameters. + + For details, see :func:`distro.linux_distribution`. + """ + return ( + self.name() if full_distribution_name else self.id(), + self.version(), + self.codename() + ) + + def id(self): + """Return the distro ID of the Linux distribution, as a string. + + For details, see :func:`distro.id`. + """ + def normalize(distro_id, table): + distro_id = distro_id.lower().replace(' ', '_') + return table.get(distro_id, distro_id) + + distro_id = self.os_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_OS_ID) + + distro_id = self.lsb_release_attr('distributor_id') + if distro_id: + return normalize(distro_id, NORMALIZED_LSB_ID) + + distro_id = self.distro_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + return '' + + def name(self, pretty=False): + """ + Return the name of the Linux distribution, as a string. + + For details, see :func:`distro.name`. + """ + name = self.os_release_attr('name') \ + or self.lsb_release_attr('distributor_id') \ + or self.distro_release_attr('name') + if pretty: + name = self.os_release_attr('pretty_name') \ + or self.lsb_release_attr('description') + if not name: + name = self.distro_release_attr('name') + version = self.version(pretty=True) + if version: + name = name + ' ' + version + return name or '' + + def version(self, pretty=False, best=False): + """ + Return the version of the Linux distribution, as a string. + + For details, see :func:`distro.version`. + """ + versions = [ + self.os_release_attr('version_id'), + self.lsb_release_attr('release'), + self.distro_release_attr('version_id'), + self._parse_distro_release_content( + self.os_release_attr('pretty_name')).get('version_id', ''), + self._parse_distro_release_content( + self.lsb_release_attr('description')).get('version_id', '') + ] + version = '' + if best: + # This algorithm uses the last version in priority order that has + # the best precision. If the versions are not in conflict, that + # does not matter; otherwise, using the last one instead of the + # first one might be considered a surprise. + for v in versions: + if v.count(".") > version.count(".") or version == '': + version = v + else: + for v in versions: + if v != '': + version = v + break + if pretty and version and self.codename(): + version = u'{0} ({1})'.format(version, self.codename()) + return version + + def version_parts(self, best=False): + """ + Return the version of the Linux distribution, as a tuple of version + numbers. + + For details, see :func:`distro.version_parts`. + """ + version_str = self.version(best=best) + if version_str: + version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') + matches = version_regex.match(version_str) + if matches: + major, minor, build_number = matches.groups() + return major, minor or '', build_number or '' + return '', '', '' + + def major_version(self, best=False): + """ + Return the major version number of the current distribution. + + For details, see :func:`distro.major_version`. + """ + return self.version_parts(best)[0] + + def minor_version(self, best=False): + """ + Return the minor version number of the Linux distribution. + + For details, see :func:`distro.minor_version`. + """ + return self.version_parts(best)[1] + + def build_number(self, best=False): + """ + Return the build number of the Linux distribution. + + For details, see :func:`distro.build_number`. + """ + return self.version_parts(best)[2] + + def like(self): + """ + Return the IDs of distributions that are like the Linux distribution. + + For details, see :func:`distro.like`. + """ + return self.os_release_attr('id_like') or '' + + def codename(self): + """ + Return the codename of the Linux distribution. + + For details, see :func:`distro.codename`. + """ + return self.os_release_attr('codename') \ + or self.lsb_release_attr('codename') \ + or self.distro_release_attr('codename') \ + or '' + + def info(self, pretty=False, best=False): + """ + Return certain machine-readable information about the Linux + distribution. + + For details, see :func:`distro.info`. + """ + return dict( + id=self.id(), + version=self.version(pretty, best), + version_parts=dict( + major=self.major_version(best), + minor=self.minor_version(best), + build_number=self.build_number(best) + ), + like=self.like(), + codename=self.codename(), + ) + + def os_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the os-release file data source of the Linux distribution. + + For details, see :func:`distro.os_release_info`. + """ + return self._os_release_info + + def lsb_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the lsb_release command data source of the Linux + distribution. + + For details, see :func:`distro.lsb_release_info`. + """ + return self._lsb_release_info + + def distro_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the distro release file data source of the Linux + distribution. + + For details, see :func:`distro.distro_release_info`. + """ + return self._distro_release_info + + def os_release_attr(self, attribute): + """ + Return a single named information item from the os-release file data + source of the Linux distribution. + + For details, see :func:`distro.os_release_attr`. + """ + return self._os_release_info.get(attribute, '') + + def lsb_release_attr(self, attribute): + """ + Return a single named information item from the lsb_release command + output data source of the Linux distribution. + + For details, see :func:`distro.lsb_release_attr`. + """ + return self._lsb_release_info.get(attribute, '') + + def distro_release_attr(self, attribute): + """ + Return a single named information item from the distro release file + data source of the Linux distribution. + + For details, see :func:`distro.distro_release_attr`. + """ + return self._distro_release_info.get(attribute, '') + + @cached_property + def _os_release_info(self): + """ + Get the information items from the specified os-release file. + + Returns: + A dictionary containing all information items. + """ + if os.path.isfile(self.os_release_file): + with open(self.os_release_file) as release_file: + return self._parse_os_release_content(release_file) + return {} + + @staticmethod + def _parse_os_release_content(lines): + """ + Parse the lines of an os-release file. + + Parameters: + + * lines: Iterable through the lines in the os-release file. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + lexer = shlex.shlex(lines, posix=True) + lexer.whitespace_split = True + + # The shlex module defines its `wordchars` variable using literals, + # making it dependent on the encoding of the Python source file. + # In Python 2.6 and 2.7, the shlex source file is encoded in + # 'iso-8859-1', and the `wordchars` variable is defined as a byte + # string. This causes a UnicodeDecodeError to be raised when the + # parsed content is a unicode object. The following fix resolves that + # (... but it should be fixed in shlex...): + if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): + lexer.wordchars = lexer.wordchars.decode('iso-8859-1') + + tokens = list(lexer) + for token in tokens: + # At this point, all shell-like parsing has been done (i.e. + # comments processed, quotes and backslash escape sequences + # processed, multi-line values assembled, trailing newlines + # stripped, etc.), so the tokens are now either: + # * variable assignments: var=value + # * commands or their arguments (not allowed in os-release) + if '=' in token: + k, v = token.split('=', 1) + if isinstance(v, bytes): + v = v.decode('utf-8') + props[k.lower()] = v + if k == 'VERSION': + # this handles cases in which the codename is in + # the `(CODENAME)` (rhel, centos, fedora) format + # or in the `, CODENAME` format (Ubuntu). + codename = re.search(r'(\(\D+\))|,(\s+)?\D+', v) + if codename: + codename = codename.group() + codename = codename.strip('()') + codename = codename.strip(',') + codename = codename.strip() + # codename appears within paranthese. + props['codename'] = codename + else: + props['codename'] = '' + else: + # Ignore any tokens that are not variable assignments + pass + return props + + @cached_property + def _lsb_release_info(self): + """ + Get the information items from the lsb_release command output. + + Returns: + A dictionary containing all information items. + """ + if not self.include_lsb: + return {} + with open(os.devnull, 'w') as devnull: + try: + cmd = ('lsb_release', '-a') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: # Command not found + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_lsb_release_content(content) + + @staticmethod + def _parse_lsb_release_content(lines): + """ + Parse the output of the lsb_release command. + + Parameters: + + * lines: Iterable through the lines of the lsb_release output. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + for line in lines: + kv = line.strip('\n').split(':', 1) + if len(kv) != 2: + # Ignore lines without colon. + continue + k, v = kv + props.update({k.replace(' ', '_').lower(): v.strip()}) + return props + + @cached_property + def _distro_release_info(self): + """ + Get the information items from the specified distro release file. + + Returns: + A dictionary containing all information items. + """ + if self.distro_release_file: + # If it was specified, we use it and parse what we can, even if + # its file name or content does not match the expected pattern. + distro_info = self._parse_distro_release_file( + self.distro_release_file) + basename = os.path.basename(self.distro_release_file) + # The file name pattern for user-specified distro release files + # is somewhat more tolerant (compared to when searching for the + # file), because we want to use what was specified as best as + # possible. + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + distro_info['id'] = match.group(1) + return distro_info + else: + try: + basenames = os.listdir(_UNIXCONFDIR) + # We sort for repeatability in cases where there are multiple + # distro specific files; e.g. CentOS, Oracle, Enterprise all + # containing `redhat-release` on top of their own. + basenames.sort() + except OSError: + # This may occur when /etc is not readable but we can't be + # sure about the *-release files. Check common entries of + # /etc for information. If they turn out to not be there the + # error is handled in `_parse_distro_release_file()`. + basenames = ['SuSE-release', + 'arch-release', + 'base-release', + 'centos-release', + 'fedora-release', + 'gentoo-release', + 'mageia-release', + 'mandrake-release', + 'mandriva-release', + 'mandrivalinux-release', + 'manjaro-release', + 'oracle-release', + 'redhat-release', + 'sl-release', + 'slackware-version'] + for basename in basenames: + if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: + continue + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + filepath = os.path.join(_UNIXCONFDIR, basename) + distro_info = self._parse_distro_release_file(filepath) + if 'name' in distro_info: + # The name is always present if the pattern matches + self.distro_release_file = filepath + distro_info['id'] = match.group(1) + return distro_info + return {} + + def _parse_distro_release_file(self, filepath): + """ + Parse a distro release file. + + Parameters: + + * filepath: Path name of the distro release file. + + Returns: + A dictionary containing all information items. + """ + try: + with open(filepath) as fp: + # Only parse the first line. For instance, on SLES there + # are multiple lines. We don't want them... + return self._parse_distro_release_content(fp.readline()) + except (OSError, IOError): + # Ignore not being able to read a specific, seemingly version + # related file. + # See https://github.com/nir0s/distro/issues/162 + return {} + + @staticmethod + def _parse_distro_release_content(line): + """ + Parse a line from a distro release file. + + Parameters: + * line: Line from the distro release file. Must be a unicode string + or a UTF-8 encoded byte string. + + Returns: + A dictionary containing all information items. + """ + if isinstance(line, bytes): + line = line.decode('utf-8') + matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( + line.strip()[::-1]) + distro_info = {} + if matches: + # regexp ensures non-None + distro_info['name'] = matches.group(3)[::-1] + if matches.group(2): + distro_info['version_id'] = matches.group(2)[::-1] + if matches.group(1): + distro_info['codename'] = matches.group(1)[::-1] + elif line: + distro_info['name'] = line.strip() + return distro_info + + +_distro = LinuxDistribution() + + +def main(): + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler(sys.stdout)) + + parser = argparse.ArgumentParser(description="Linux distro info tool") + parser.add_argument( + '--json', + '-j', + help="Output in machine readable format", + action="store_true") + args = parser.parse_args() + + if args.json: + logger.info(json.dumps(info(), indent=4, sort_keys=True)) + else: + logger.info('Name: %s', name(pretty=True)) + distribution_version = version(pretty=True) + logger.info('Version: %s', distribution_version) + distribution_codename = codename() + logger.info('Codename: %s', distribution_codename) + + +if __name__ == '__main__': + main() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__init__.py new file mode 100644 index 0000000..0491234 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__init__.py @@ -0,0 +1,35 @@ +""" +HTML parsing library based on the `WHATWG HTML specification +<https://whatwg.org/html>`_. The parser is designed to be compatible with +existing HTML found in the wild and implements well-defined error recovery that +is largely compatible with modern desktop web browsers. + +Example usage:: + + from pip._vendor import html5lib + with open("my_document.html", "rb") as f: + tree = html5lib.parse(f) + +For convenience, this module re-exports the following names: + +* :func:`~.html5parser.parse` +* :func:`~.html5parser.parseFragment` +* :class:`~.html5parser.HTMLParser` +* :func:`~.treebuilders.getTreeBuilder` +* :func:`~.treewalkers.getTreeWalker` +* :func:`~.serializer.serialize` +""" + +from __future__ import absolute_import, division, unicode_literals + +from .html5parser import HTMLParser, parse, parseFragment +from .treebuilders import getTreeBuilder +from .treewalkers import getTreeWalker +from .serializer import serialize + +__all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", + "getTreeWalker", "serialize"] + +# this has to be at the top level, see how setup.py parses this +#: Distribution version number. +__version__ = "1.0.1" diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..618d9f5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc new file mode 100644 index 0000000..d599685 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc new file mode 100644 index 0000000..2f058d7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc new file mode 100644 index 0000000..7c5b9c1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc new file mode 100644 index 0000000..7064b04 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc new file mode 100644 index 0000000..3dc7015 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc new file mode 100644 index 0000000..caf4150 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc new file mode 100644 index 0000000..04d44a2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py new file mode 100644 index 0000000..4c77717 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_ihatexml.py @@ -0,0 +1,288 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +import warnings + +from .constants import DataLossWarning + +baseChar = """ +[#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | +[#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | +[#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | +[#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | +[#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | +[#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | +[#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | +[#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | +[#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | +[#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | +[#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | +[#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | +[#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | +[#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | +[#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | +[#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | +[#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | +[#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | +[#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | +[#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | +[#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | +[#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | +[#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | +[#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | +[#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | +[#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | +[#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | +[#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | +[#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | +[#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | +#x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | +#x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | +#x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | +[#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | +[#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | +#x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | +[#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | +[#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | +[#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | +[#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | +[#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | +#x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | +[#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | +[#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | +[#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | +[#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" + +ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" + +combiningCharacter = """ +[#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | +[#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | +[#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | +[#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | +#x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | +[#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | +[#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | +#x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | +[#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | +[#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | +#x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | +[#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | +[#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | +[#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | +[#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | +[#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | +#x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | +[#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | +#x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | +[#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | +[#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | +#x3099 | #x309A""" + +digit = """ +[#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | +[#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | +[#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | +[#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" + +extender = """ +#x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | +#[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" + +letter = " | ".join([baseChar, ideographic]) + +# Without the +name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, + extender]) +nameFirst = " | ".join([letter, "_"]) + +reChar = re.compile(r"#x([\d|A-F]{4,4})") +reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") + + +def charStringToList(chars): + charRanges = [item.strip() for item in chars.split(" | ")] + rv = [] + for item in charRanges: + foundMatch = False + for regexp in (reChar, reCharRange): + match = regexp.match(item) + if match is not None: + rv.append([hexToInt(item) for item in match.groups()]) + if len(rv[-1]) == 1: + rv[-1] = rv[-1] * 2 + foundMatch = True + break + if not foundMatch: + assert len(item) == 1 + + rv.append([ord(item)] * 2) + rv = normaliseCharList(rv) + return rv + + +def normaliseCharList(charList): + charList = sorted(charList) + for item in charList: + assert item[1] >= item[0] + rv = [] + i = 0 + while i < len(charList): + j = 1 + rv.append(charList[i]) + while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: + rv[-1][1] = charList[i + j][1] + j += 1 + i += j + return rv + +# We don't really support characters above the BMP :( +max_unicode = int("FFFF", 16) + + +def missingRanges(charList): + rv = [] + if charList[0] != 0: + rv.append([0, charList[0][0] - 1]) + for i, item in enumerate(charList[:-1]): + rv.append([item[1] + 1, charList[i + 1][0] - 1]) + if charList[-1][1] != max_unicode: + rv.append([charList[-1][1] + 1, max_unicode]) + return rv + + +def listToRegexpStr(charList): + rv = [] + for item in charList: + if item[0] == item[1]: + rv.append(escapeRegexp(chr(item[0]))) + else: + rv.append(escapeRegexp(chr(item[0])) + "-" + + escapeRegexp(chr(item[1]))) + return "[%s]" % "".join(rv) + + +def hexToInt(hex_str): + return int(hex_str, 16) + + +def escapeRegexp(string): + specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", + "[", "]", "|", "(", ")", "-") + for char in specialCharacters: + string = string.replace(char, "\\" + char) + + return string + +# output from the above +nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +# Simpler things +nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") + + +class InfosetFilter(object): + replacementRegexp = re.compile(r"U[\dA-F]{5,5}") + + def __init__(self, + dropXmlnsLocalName=False, + dropXmlnsAttrNs=False, + preventDoubleDashComments=False, + preventDashAtCommentEnd=False, + replaceFormFeedCharacters=True, + preventSingleQuotePubid=False): + + self.dropXmlnsLocalName = dropXmlnsLocalName + self.dropXmlnsAttrNs = dropXmlnsAttrNs + + self.preventDoubleDashComments = preventDoubleDashComments + self.preventDashAtCommentEnd = preventDashAtCommentEnd + + self.replaceFormFeedCharacters = replaceFormFeedCharacters + + self.preventSingleQuotePubid = preventSingleQuotePubid + + self.replaceCache = {} + + def coerceAttribute(self, name, namespace=None): + if self.dropXmlnsLocalName and name.startswith("xmlns:"): + warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) + return None + elif (self.dropXmlnsAttrNs and + namespace == "http://www.w3.org/2000/xmlns/"): + warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) + return None + else: + return self.toXmlName(name) + + def coerceElement(self, name): + return self.toXmlName(name) + + def coerceComment(self, data): + if self.preventDoubleDashComments: + while "--" in data: + warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) + data = data.replace("--", "- -") + if data.endswith("-"): + warnings.warn("Comments cannot end in a dash", DataLossWarning) + data += " " + return data + + def coerceCharacters(self, data): + if self.replaceFormFeedCharacters: + for _ in range(data.count("\x0C")): + warnings.warn("Text cannot contain U+000C", DataLossWarning) + data = data.replace("\x0C", " ") + # Other non-xml characters + return data + + def coercePubid(self, data): + dataOutput = data + for char in nonPubidCharRegexp.findall(data): + warnings.warn("Coercing non-XML pubid", DataLossWarning) + replacement = self.getReplacementCharacter(char) + dataOutput = dataOutput.replace(char, replacement) + if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: + warnings.warn("Pubid cannot contain single quote", DataLossWarning) + dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) + return dataOutput + + def toXmlName(self, name): + nameFirst = name[0] + nameRest = name[1:] + m = nonXmlNameFirstBMPRegexp.match(nameFirst) + if m: + warnings.warn("Coercing non-XML name", DataLossWarning) + nameFirstOutput = self.getReplacementCharacter(nameFirst) + else: + nameFirstOutput = nameFirst + + nameRestOutput = nameRest + replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) + for char in replaceChars: + warnings.warn("Coercing non-XML name", DataLossWarning) + replacement = self.getReplacementCharacter(char) + nameRestOutput = nameRestOutput.replace(char, replacement) + return nameFirstOutput + nameRestOutput + + def getReplacementCharacter(self, char): + if char in self.replaceCache: + replacement = self.replaceCache[char] + else: + replacement = self.escapeChar(char) + return replacement + + def fromXmlName(self, name): + for item in set(self.replacementRegexp.findall(name)): + name = name.replace(item, self.unescapeChar(item)) + return name + + def escapeChar(self, char): + replacement = "U%05X" % ord(char) + self.replaceCache[char] = replacement + return replacement + + def unescapeChar(self, charcode): + return chr(int(charcode[1:], 16)) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_inputstream.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_inputstream.py new file mode 100644 index 0000000..a65e55f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_inputstream.py @@ -0,0 +1,923 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type, binary_type +from pip._vendor.six.moves import http_client, urllib + +import codecs +import re + +from pip._vendor import webencodings + +from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase +from .constants import _ReparseException +from . import _utils + +from io import StringIO + +try: + from io import BytesIO +except ImportError: + BytesIO = StringIO + +# Non-unicode versions of constants for use in the pre-parser +spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) +asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) +asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) +spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) + + +invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa + +if _utils.supports_lone_surrogates: + # Use one extra step of indirection and create surrogates with + # eval. Not using this indirection would introduce an illegal + # unicode literal on platforms not supporting such lone + # surrogates. + assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + + eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used + "]") +else: + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) + +non_bmp_invalid_codepoints = set([0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, + 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, + 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, + 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, + 0x10FFFE, 0x10FFFF]) + +ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") + +# Cache for charsUntil() +charsUntilRegEx = {} + + +class BufferedStream(object): + """Buffering for streams that do not have buffering of their own + + The buffer is implemented as a list of chunks on the assumption that + joining many strings will be slow since it is O(n**2) + """ + + def __init__(self, stream): + self.stream = stream + self.buffer = [] + self.position = [-1, 0] # chunk number, offset + + def tell(self): + pos = 0 + for chunk in self.buffer[:self.position[0]]: + pos += len(chunk) + pos += self.position[1] + return pos + + def seek(self, pos): + assert pos <= self._bufferedBytes() + offset = pos + i = 0 + while len(self.buffer[i]) < offset: + offset -= len(self.buffer[i]) + i += 1 + self.position = [i, offset] + + def read(self, bytes): + if not self.buffer: + return self._readStream(bytes) + elif (self.position[0] == len(self.buffer) and + self.position[1] == len(self.buffer[-1])): + return self._readStream(bytes) + else: + return self._readFromBuffer(bytes) + + def _bufferedBytes(self): + return sum([len(item) for item in self.buffer]) + + def _readStream(self, bytes): + data = self.stream.read(bytes) + self.buffer.append(data) + self.position[0] += 1 + self.position[1] = len(data) + return data + + def _readFromBuffer(self, bytes): + remainingBytes = bytes + rv = [] + bufferIndex = self.position[0] + bufferOffset = self.position[1] + while bufferIndex < len(self.buffer) and remainingBytes != 0: + assert remainingBytes > 0 + bufferedData = self.buffer[bufferIndex] + + if remainingBytes <= len(bufferedData) - bufferOffset: + bytesToRead = remainingBytes + self.position = [bufferIndex, bufferOffset + bytesToRead] + else: + bytesToRead = len(bufferedData) - bufferOffset + self.position = [bufferIndex, len(bufferedData)] + bufferIndex += 1 + rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) + remainingBytes -= bytesToRead + + bufferOffset = 0 + + if remainingBytes: + rv.append(self._readStream(remainingBytes)) + + return b"".join(rv) + + +def HTMLInputStream(source, **kwargs): + # Work around Python bug #20007: read(0) closes the connection. + # http://bugs.python.org/issue20007 + if (isinstance(source, http_client.HTTPResponse) or + # Also check for addinfourl wrapping HTTPResponse + (isinstance(source, urllib.response.addbase) and + isinstance(source.fp, http_client.HTTPResponse))): + isUnicode = False + elif hasattr(source, "read"): + isUnicode = isinstance(source.read(0), text_type) + else: + isUnicode = isinstance(source, text_type) + + if isUnicode: + encodings = [x for x in kwargs if x.endswith("_encoding")] + if encodings: + raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) + + return HTMLUnicodeInputStream(source, **kwargs) + else: + return HTMLBinaryInputStream(source, **kwargs) + + +class HTMLUnicodeInputStream(object): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + _defaultChunkSize = 10240 + + def __init__(self, source): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + + if not _utils.supports_lone_surrogates: + # Such platforms will have already checked for such + # surrogate errors, so no need to do this checking. + self.reportCharacterErrors = None + elif len("\U0010FFFF") == 1: + self.reportCharacterErrors = self.characterErrorsUCS4 + else: + self.reportCharacterErrors = self.characterErrorsUCS2 + + # List of where new lines occur + self.newLines = [0] + + self.charEncoding = (lookupEncoding("utf-8"), "certain") + self.dataStream = self.openStream(source) + + self.reset() + + def reset(self): + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + self.errors = [] + + # number of (complete) lines in previous chunks + self.prevNumLines = 0 + # number of columns in the last line of the previous chunk + self.prevNumCols = 0 + + # Deal with CR LF and surrogates split over chunk boundaries + self._bufferedCharacter = None + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = StringIO(source) + + return stream + + def _position(self, offset): + chunk = self.chunk + nLines = chunk.count('\n', 0, offset) + positionLine = self.prevNumLines + nLines + lastLinePos = chunk.rfind('\n', 0, offset) + if lastLinePos == -1: + positionColumn = self.prevNumCols + offset + else: + positionColumn = offset - (lastLinePos + 1) + return (positionLine, positionColumn) + + def position(self): + """Returns (line, col) of the current position in the stream.""" + line, col = self._position(self.chunkOffset) + return (line + 1, col) + + def char(self): + """ Read one character from the stream or queue if available. Return + EOF when EOF is reached. + """ + # Read a new chunk from the input stream if necessary + if self.chunkOffset >= self.chunkSize: + if not self.readChunk(): + return EOF + + chunkOffset = self.chunkOffset + char = self.chunk[chunkOffset] + self.chunkOffset = chunkOffset + 1 + + return char + + def readChunk(self, chunkSize=None): + if chunkSize is None: + chunkSize = self._defaultChunkSize + + self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) + + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + + data = self.dataStream.read(chunkSize) + + # Deal with CR LF and surrogates broken across chunks + if self._bufferedCharacter: + data = self._bufferedCharacter + data + self._bufferedCharacter = None + elif not data: + # We have no more data, bye-bye stream + return False + + if len(data) > 1: + lastv = ord(data[-1]) + if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: + self._bufferedCharacter = data[-1] + data = data[:-1] + + if self.reportCharacterErrors: + self.reportCharacterErrors(data) + + # Replace invalid characters + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + + self.chunk = data + self.chunkSize = len(data) + + return True + + def characterErrorsUCS4(self, data): + for _ in range(len(invalid_unicode_re.findall(data))): + self.errors.append("invalid-codepoint") + + def characterErrorsUCS2(self, data): + # Someone picked the wrong compile option + # You lose + skip = False + for match in invalid_unicode_re.finditer(data): + if skip: + continue + codepoint = ord(match.group()) + pos = match.start() + # Pretty sure there should be endianness issues here + if _utils.isSurrogatePair(data[pos:pos + 2]): + # We have a surrogate pair! + char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) + if char_val in non_bmp_invalid_codepoints: + self.errors.append("invalid-codepoint") + skip = True + elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and + pos == len(data) - 1): + self.errors.append("invalid-codepoint") + else: + skip = False + self.errors.append("invalid-codepoint") + + def charsUntil(self, characters, opposite=False): + """ Returns a string of characters from the stream up to but not + including any character in 'characters' or EOF. 'characters' must be + a container that supports the 'in' method and iteration over its + characters. + """ + + # Use a cache of regexps to find the required characters + try: + chars = charsUntilRegEx[(characters, opposite)] + except KeyError: + if __debug__: + for c in characters: + assert(ord(c) < 128) + regex = "".join(["\\x%02x" % ord(c) for c in characters]) + if not opposite: + regex = "^%s" % regex + chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) + + rv = [] + + while True: + # Find the longest matching prefix + m = chars.match(self.chunk, self.chunkOffset) + if m is None: + # If nothing matched, and it wasn't because we ran out of chunk, + # then stop + if self.chunkOffset != self.chunkSize: + break + else: + end = m.end() + # If not the whole chunk matched, return everything + # up to the part that didn't match + if end != self.chunkSize: + rv.append(self.chunk[self.chunkOffset:end]) + self.chunkOffset = end + break + # If the whole remainder of the chunk matched, + # use it all and read the next chunk + rv.append(self.chunk[self.chunkOffset:]) + if not self.readChunk(): + # Reached EOF + break + + r = "".join(rv) + return r + + def unget(self, char): + # Only one character is allowed to be ungotten at once - it must + # be consumed again before any further call to unget + if char is not None: + if self.chunkOffset == 0: + # unget is called quite rarely, so it's a good idea to do + # more work here if it saves a bit of work in the frequently + # called char and charsUntil. + # So, just prepend the ungotten character onto the current + # chunk: + self.chunk = char + self.chunk + self.chunkSize += 1 + else: + self.chunkOffset -= 1 + assert self.chunk[self.chunkOffset] == char + + +class HTMLBinaryInputStream(HTMLUnicodeInputStream): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + def __init__(self, source, override_encoding=None, transport_encoding=None, + same_origin_parent_encoding=None, likely_encoding=None, + default_encoding="windows-1252", useChardet=True): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + # Raw Stream - for unicode objects this will encode to utf-8 and set + # self.charEncoding as appropriate + self.rawStream = self.openStream(source) + + HTMLUnicodeInputStream.__init__(self, self.rawStream) + + # Encoding Information + # Number of bytes to use when looking for a meta element with + # encoding information + self.numBytesMeta = 1024 + # Number of bytes to use when using detecting encoding using chardet + self.numBytesChardet = 100 + # Things from args + self.override_encoding = override_encoding + self.transport_encoding = transport_encoding + self.same_origin_parent_encoding = same_origin_parent_encoding + self.likely_encoding = likely_encoding + self.default_encoding = default_encoding + + # Determine encoding + self.charEncoding = self.determineEncoding(useChardet) + assert self.charEncoding[0] is not None + + # Call superclass + self.reset() + + def reset(self): + self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') + HTMLUnicodeInputStream.reset(self) + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = BytesIO(source) + + try: + stream.seek(stream.tell()) + except: # pylint:disable=bare-except + stream = BufferedStream(stream) + + return stream + + def determineEncoding(self, chardet=True): + # BOMs take precedence over everything + # This will also read past the BOM if present + charEncoding = self.detectBOM(), "certain" + if charEncoding[0] is not None: + return charEncoding + + # If we've been overriden, we've been overriden + charEncoding = lookupEncoding(self.override_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Now check the transport layer + charEncoding = lookupEncoding(self.transport_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Look for meta elements with encoding information + charEncoding = self.detectEncodingMeta(), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Parent document encoding + charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" + if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): + return charEncoding + + # "likely" encoding + charEncoding = lookupEncoding(self.likely_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Guess with chardet, if available + if chardet: + try: + from pip._vendor.chardet.universaldetector import UniversalDetector + except ImportError: + pass + else: + buffers = [] + detector = UniversalDetector() + while not detector.done: + buffer = self.rawStream.read(self.numBytesChardet) + assert isinstance(buffer, bytes) + if not buffer: + break + buffers.append(buffer) + detector.feed(buffer) + detector.close() + encoding = lookupEncoding(detector.result['encoding']) + self.rawStream.seek(0) + if encoding is not None: + return encoding, "tentative" + + # Try the default encoding + charEncoding = lookupEncoding(self.default_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Fallback to html5lib's default if even that hasn't worked + return lookupEncoding("windows-1252"), "tentative" + + def changeEncoding(self, newEncoding): + assert self.charEncoding[1] != "certain" + newEncoding = lookupEncoding(newEncoding) + if newEncoding is None: + return + if newEncoding.name in ("utf-16be", "utf-16le"): + newEncoding = lookupEncoding("utf-8") + assert newEncoding is not None + elif newEncoding == self.charEncoding[0]: + self.charEncoding = (self.charEncoding[0], "certain") + else: + self.rawStream.seek(0) + self.charEncoding = (newEncoding, "certain") + self.reset() + raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) + + def detectBOM(self): + """Attempts to detect at BOM at the start of the stream. If + an encoding can be determined from the BOM return the name of the + encoding otherwise return None""" + bomDict = { + codecs.BOM_UTF8: 'utf-8', + codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', + codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' + } + + # Go to beginning of file and read in 4 bytes + string = self.rawStream.read(4) + assert isinstance(string, bytes) + + # Try detecting the BOM using bytes from the string + encoding = bomDict.get(string[:3]) # UTF-8 + seek = 3 + if not encoding: + # Need to detect UTF-32 before UTF-16 + encoding = bomDict.get(string) # UTF-32 + seek = 4 + if not encoding: + encoding = bomDict.get(string[:2]) # UTF-16 + seek = 2 + + # Set the read position past the BOM if one was found, otherwise + # set it to the start of the stream + if encoding: + self.rawStream.seek(seek) + return lookupEncoding(encoding) + else: + self.rawStream.seek(0) + return None + + def detectEncodingMeta(self): + """Report the encoding declared by the meta element + """ + buffer = self.rawStream.read(self.numBytesMeta) + assert isinstance(buffer, bytes) + parser = EncodingParser(buffer) + self.rawStream.seek(0) + encoding = parser.getEncoding() + + if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): + encoding = lookupEncoding("utf-8") + + return encoding + + +class EncodingBytes(bytes): + """String-like object with an associated position and various extra methods + If the position is ever greater than the string length then an exception is + raised""" + def __new__(self, value): + assert isinstance(value, bytes) + return bytes.__new__(self, value.lower()) + + def __init__(self, value): + # pylint:disable=unused-argument + self._position = -1 + + def __iter__(self): + return self + + def __next__(self): + p = self._position = self._position + 1 + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + return self[p:p + 1] + + def next(self): + # Py2 compat + return self.__next__() + + def previous(self): + p = self._position + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + self._position = p = p - 1 + return self[p:p + 1] + + def setPosition(self, position): + if self._position >= len(self): + raise StopIteration + self._position = position + + def getPosition(self): + if self._position >= len(self): + raise StopIteration + if self._position >= 0: + return self._position + else: + return None + + position = property(getPosition, setPosition) + + def getCurrentByte(self): + return self[self.position:self.position + 1] + + currentByte = property(getCurrentByte) + + def skip(self, chars=spaceCharactersBytes): + """Skip past a list of characters""" + p = self.position # use property for the error-checking + while p < len(self): + c = self[p:p + 1] + if c not in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def skipUntil(self, chars): + p = self.position + while p < len(self): + c = self[p:p + 1] + if c in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def matchBytes(self, bytes): + """Look for a sequence of bytes at the start of a string. If the bytes + are found return True and advance the position to the byte after the + match. Otherwise return False and leave the position alone""" + p = self.position + data = self[p:p + len(bytes)] + rv = data.startswith(bytes) + if rv: + self.position += len(bytes) + return rv + + def jumpTo(self, bytes): + """Look for the next sequence of bytes matching a given sequence. If + a match is found advance the position to the last byte of the match""" + newPosition = self[self.position:].find(bytes) + if newPosition > -1: + # XXX: This is ugly, but I can't see a nicer way to fix this. + if self._position == -1: + self._position = 0 + self._position += (newPosition + len(bytes) - 1) + return True + else: + raise StopIteration + + +class EncodingParser(object): + """Mini parser for detecting character encoding from meta elements""" + + def __init__(self, data): + """string - the data to work on for encoding detection""" + self.data = EncodingBytes(data) + self.encoding = None + + def getEncoding(self): + methodDispatch = ( + (b"<!--", self.handleComment), + (b"<meta", self.handleMeta), + (b"</", self.handlePossibleEndTag), + (b"<!", self.handleOther), + (b"<?", self.handleOther), + (b"<", self.handlePossibleStartTag)) + for _ in self.data: + keepParsing = True + for key, method in methodDispatch: + if self.data.matchBytes(key): + try: + keepParsing = method() + break + except StopIteration: + keepParsing = False + break + if not keepParsing: + break + + return self.encoding + + def handleComment(self): + """Skip over comments""" + return self.data.jumpTo(b"-->") + + def handleMeta(self): + if self.data.currentByte not in spaceCharactersBytes: + # if we have <meta not followed by a space so just keep going + return True + # We have a valid meta element we want to search for attributes + hasPragma = False + pendingEncoding = None + while True: + # Try to find the next attribute after the current position + attr = self.getAttribute() + if attr is None: + return True + else: + if attr[0] == b"http-equiv": + hasPragma = attr[1] == b"content-type" + if hasPragma and pendingEncoding is not None: + self.encoding = pendingEncoding + return False + elif attr[0] == b"charset": + tentativeEncoding = attr[1] + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + self.encoding = codec + return False + elif attr[0] == b"content": + contentParser = ContentAttrParser(EncodingBytes(attr[1])) + tentativeEncoding = contentParser.parse() + if tentativeEncoding is not None: + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + if hasPragma: + self.encoding = codec + return False + else: + pendingEncoding = codec + + def handlePossibleStartTag(self): + return self.handlePossibleTag(False) + + def handlePossibleEndTag(self): + next(self.data) + return self.handlePossibleTag(True) + + def handlePossibleTag(self, endTag): + data = self.data + if data.currentByte not in asciiLettersBytes: + # If the next byte is not an ascii letter either ignore this + # fragment (possible start tag case) or treat it according to + # handleOther + if endTag: + data.previous() + self.handleOther() + return True + + c = data.skipUntil(spacesAngleBrackets) + if c == b"<": + # return to the first step in the overall "two step" algorithm + # reprocessing the < byte + data.previous() + else: + # Read all attributes + attr = self.getAttribute() + while attr is not None: + attr = self.getAttribute() + return True + + def handleOther(self): + return self.data.jumpTo(b">") + + def getAttribute(self): + """Return a name,value pair for the next attribute in the stream, + if one is found, or None""" + data = self.data + # Step 1 (skip chars) + c = data.skip(spaceCharactersBytes | frozenset([b"/"])) + assert c is None or len(c) == 1 + # Step 2 + if c in (b">", None): + return None + # Step 3 + attrName = [] + attrValue = [] + # Step 4 attribute name + while True: + if c == b"=" and attrName: + break + elif c in spaceCharactersBytes: + # Step 6! + c = data.skip() + break + elif c in (b"/", b">"): + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrName.append(c.lower()) + elif c is None: + return None + else: + attrName.append(c) + # Step 5 + c = next(data) + # Step 7 + if c != b"=": + data.previous() + return b"".join(attrName), b"" + # Step 8 + next(data) + # Step 9 + c = data.skip() + # Step 10 + if c in (b"'", b'"'): + # 10.1 + quoteChar = c + while True: + # 10.2 + c = next(data) + # 10.3 + if c == quoteChar: + next(data) + return b"".join(attrName), b"".join(attrValue) + # 10.4 + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + # 10.5 + else: + attrValue.append(c) + elif c == b">": + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + # Step 11 + while True: + c = next(data) + if c in spacesAngleBrackets: + return b"".join(attrName), b"".join(attrValue) + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + + +class ContentAttrParser(object): + def __init__(self, data): + assert isinstance(data, bytes) + self.data = data + + def parse(self): + try: + # Check if the attr name is charset + # otherwise return + self.data.jumpTo(b"charset") + self.data.position += 1 + self.data.skip() + if not self.data.currentByte == b"=": + # If there is no = sign keep looking for attrs + return None + self.data.position += 1 + self.data.skip() + # Look for an encoding between matching quote marks + if self.data.currentByte in (b'"', b"'"): + quoteMark = self.data.currentByte + self.data.position += 1 + oldPosition = self.data.position + if self.data.jumpTo(quoteMark): + return self.data[oldPosition:self.data.position] + else: + return None + else: + # Unquoted value + oldPosition = self.data.position + try: + self.data.skipUntil(spaceCharactersBytes) + return self.data[oldPosition:self.data.position] + except StopIteration: + # Return the whole remaining value + return self.data[oldPosition:] + except StopIteration: + return None + + +def lookupEncoding(encoding): + """Return the python codec name corresponding to an encoding or None if the + string doesn't correspond to a valid encoding.""" + if isinstance(encoding, binary_type): + try: + encoding = encoding.decode("ascii") + except UnicodeDecodeError: + return None + + if encoding is not None: + try: + return webencodings.lookup(encoding) + except AttributeError: + return None + else: + return None diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py new file mode 100644 index 0000000..178f6e7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_tokenizer.py @@ -0,0 +1,1721 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import unichr as chr + +from collections import deque + +from .constants import spaceCharacters +from .constants import entities +from .constants import asciiLetters, asciiUpper2Lower +from .constants import digits, hexDigits, EOF +from .constants import tokenTypes, tagTokenTypes +from .constants import replacementCharacters + +from ._inputstream import HTMLInputStream + +from ._trie import Trie + +entitiesTrie = Trie(entities) + + +class HTMLTokenizer(object): + """ This class takes care of tokenizing HTML. + + * self.currentToken + Holds the token that is currently being processed. + + * self.state + Holds a reference to the method to be invoked... XXX + + * self.stream + Points to HTMLInputStream object. + """ + + def __init__(self, stream, parser=None, **kwargs): + + self.stream = HTMLInputStream(stream, **kwargs) + self.parser = parser + + # Setup the initial tokenizer state + self.escapeFlag = False + self.lastFourChars = [] + self.state = self.dataState + self.escape = False + + # The current token being created + self.currentToken = None + super(HTMLTokenizer, self).__init__() + + def __iter__(self): + """ This is where the magic happens. + + We do our usually processing through the states and when we have a token + to return we yield the token which pauses processing until the next token + is requested. + """ + self.tokenQueue = deque([]) + # Start processing. When EOF is reached self.state will return False + # instead of True and the loop will terminate. + while self.state(): + while self.stream.errors: + yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} + while self.tokenQueue: + yield self.tokenQueue.popleft() + + def consumeNumberEntity(self, isHex): + """This function returns either U+FFFD or the character based on the + decimal or hexadecimal representation. It also discards ";" if present. + If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. + """ + + allowed = digits + radix = 10 + if isHex: + allowed = hexDigits + radix = 16 + + charStack = [] + + # Consume all the characters that are in range while making sure we + # don't hit an EOF. + c = self.stream.char() + while c in allowed and c is not EOF: + charStack.append(c) + c = self.stream.char() + + # Convert the set of characters consumed to an int. + charAsInt = int("".join(charStack), radix) + + # Certain characters get replaced with others + if charAsInt in replacementCharacters: + char = replacementCharacters[charAsInt] + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + elif ((0xD800 <= charAsInt <= 0xDFFF) or + (charAsInt > 0x10FFFF)): + char = "\uFFFD" + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + else: + # Should speed up this check somehow (e.g. move the set to a constant) + if ((0x0001 <= charAsInt <= 0x0008) or + (0x000E <= charAsInt <= 0x001F) or + (0x007F <= charAsInt <= 0x009F) or + (0xFDD0 <= charAsInt <= 0xFDEF) or + charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, + 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, + 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, + 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, + 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, + 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, + 0xFFFFF, 0x10FFFE, 0x10FFFF])): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + try: + # Try/except needed as UCS-2 Python builds' unichar only works + # within the BMP. + char = chr(charAsInt) + except ValueError: + v = charAsInt - 0x10000 + char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) + + # Discard the ; if present. Otherwise, put it back on the queue and + # invoke parseError on parser. + if c != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "numeric-entity-without-semicolon"}) + self.stream.unget(c) + + return char + + def consumeEntity(self, allowedChar=None, fromAttribute=False): + # Initialise to the default output for when no entity is matched + output = "&" + + charStack = [self.stream.char()] + if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or + (allowedChar is not None and allowedChar == charStack[0])): + self.stream.unget(charStack[0]) + + elif charStack[0] == "#": + # Read the next character to see if it's hex or decimal + hex = False + charStack.append(self.stream.char()) + if charStack[-1] in ("x", "X"): + hex = True + charStack.append(self.stream.char()) + + # charStack[-1] should be the first digit + if (hex and charStack[-1] in hexDigits) \ + or (not hex and charStack[-1] in digits): + # At least one digit found, so consume the whole number + self.stream.unget(charStack[-1]) + output = self.consumeNumberEntity(hex) + else: + # No digits found + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "expected-numeric-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + else: + # At this point in the process might have named entity. Entities + # are stored in the global variable "entities". + # + # Consume characters and compare to these to a substring of the + # entity names in the list until the substring no longer matches. + while (charStack[-1] is not EOF): + if not entitiesTrie.has_keys_with_prefix("".join(charStack)): + break + charStack.append(self.stream.char()) + + # At this point we have a string that starts with some characters + # that may match an entity + # Try to find the longest entity the string will match to take care + # of ¬i for instance. + try: + entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) + entityLength = len(entityName) + except KeyError: + entityName = None + + if entityName is not None: + if entityName[-1] != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "named-entity-without-semicolon"}) + if (entityName[-1] != ";" and fromAttribute and + (charStack[entityLength] in asciiLetters or + charStack[entityLength] in digits or + charStack[entityLength] == "=")): + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + else: + output = entities[entityName] + self.stream.unget(charStack.pop()) + output += "".join(charStack[entityLength:]) + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-named-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + if fromAttribute: + self.currentToken["data"][-1][1] += output + else: + if output in spaceCharacters: + tokenType = "SpaceCharacters" + else: + tokenType = "Characters" + self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) + + def processEntityInAttribute(self, allowedChar): + """This method replaces the need for "entityInAttributeValueState". + """ + self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) + + def emitCurrentToken(self): + """This method is a generic handler for emitting the tags. It also sets + the state to "data" because that's what's needed after a token has been + emitted. + """ + token = self.currentToken + # Add token to the queue to be yielded + if (token["type"] in tagTokenTypes): + token["name"] = token["name"].translate(asciiUpper2Lower) + if token["type"] == tokenTypes["EndTag"]: + if token["data"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "attributes-in-end-tag"}) + if token["selfClosing"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "self-closing-flag-on-end-tag"}) + self.tokenQueue.append(token) + self.state = self.dataState + + # Below are the various tokenizer states worked out. + def dataState(self): + data = self.stream.char() + if data == "&": + self.state = self.entityDataState + elif data == "<": + self.state = self.tagOpenState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\u0000"}) + elif data is EOF: + # Tokenization ends. + return False + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def entityDataState(self): + self.consumeEntity() + self.state = self.dataState + return True + + def rcdataState(self): + data = self.stream.char() + if data == "&": + self.state = self.characterReferenceInRcdata + elif data == "<": + self.state = self.rcdataLessThanSignState + elif data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def characterReferenceInRcdata(self): + self.consumeEntity() + self.state = self.rcdataState + return True + + def rawtextState(self): + data = self.stream.char() + if data == "<": + self.state = self.rawtextLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataState(self): + data = self.stream.char() + if data == "<": + self.state = self.scriptDataLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def plaintextState(self): + data = self.stream.char() + if data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + self.stream.charsUntil("\u0000")}) + return True + + def tagOpenState(self): + data = self.stream.char() + if data == "!": + self.state = self.markupDeclarationOpenState + elif data == "/": + self.state = self.closeTagOpenState + elif data in asciiLetters: + self.currentToken = {"type": tokenTypes["StartTag"], + "name": data, "data": [], + "selfClosing": False, + "selfClosingAcknowledged": False} + self.state = self.tagNameState + elif data == ">": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-right-bracket"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) + self.state = self.dataState + elif data == "?": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-question-mark"}) + self.stream.unget(data) + self.state = self.bogusCommentState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.dataState + return True + + def closeTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.currentToken = {"type": tokenTypes["EndTag"], "name": data, + "data": [], "selfClosing": False} + self.state = self.tagNameState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-right-bracket"}) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-eof"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.state = self.dataState + else: + # XXX data can be _'_... + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-char", + "datavars": {"data": data}}) + self.stream.unget(data) + self.state = self.bogusCommentState + return True + + def tagNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-tag-name"}) + self.state = self.dataState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + else: + self.currentToken["name"] += data + # (Don't use charsUntil here, because tag names are + # very short and it's faster to not do anything fancy) + return True + + def rcdataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rcdataEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rcdataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rawtextLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rawtextEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rawtextEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def scriptDataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEndTagOpenState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<!"}) + self.state = self.scriptDataEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.scriptDataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapeStartDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.state = self.dataState + else: + chars = self.stream.charsUntil(("<", "-", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEscapedEndTagOpenState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) + self.temporaryBuffer = data + self.state = self.scriptDataDoubleEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer = data + self.state = self.scriptDataEscapedEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapeStartState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataDoubleEscapedState + else: + self.state = self.scriptDataEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + return True + + def scriptDataDoubleEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) + self.temporaryBuffer = "" + self.state = self.scriptDataDoubleEscapeEndState + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapeEndState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataEscapedState + else: + self.state = self.scriptDataDoubleEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def beforeAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data in ("'", '"', "=", "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-name-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def attributeNameState(self): + data = self.stream.char() + leavingThisState = True + emitToken = False + if data == "=": + self.state = self.beforeAttributeValueState + elif data in asciiLetters: + self.currentToken["data"][-1][0] += data +\ + self.stream.charsUntil(asciiLetters, True) + leavingThisState = False + elif data == ">": + # XXX If we emit here the attributes are converted to a dict + # without being checked and when the code below runs we error + # because data is a dict not a list + emitToken = True + elif data in spaceCharacters: + self.state = self.afterAttributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][0] += "\uFFFD" + leavingThisState = False + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"][-1][0] += data + leavingThisState = False + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-attribute-name"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][0] += data + leavingThisState = False + + if leavingThisState: + # Attributes are not dropped at this stage. That happens when the + # start tag token is emitted so values can still be safely appended + # to attributes, but we do want to report the parse error in time. + self.currentToken["data"][-1][0] = ( + self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) + for name, _ in self.currentToken["data"][:-1]: + if self.currentToken["data"][-1][0] == name: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "duplicate-attribute"}) + break + # XXX Fix for above XXX + if emitToken: + self.emitCurrentToken() + return True + + def afterAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "=": + self.state = self.beforeAttributeValueState + elif data == ">": + self.emitCurrentToken() + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-after-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-end-of-tag-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def beforeAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "\"": + self.state = self.attributeValueDoubleQuotedState + elif data == "&": + self.state = self.attributeValueUnQuotedState + self.stream.unget(data) + elif data == "'": + self.state = self.attributeValueSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-right-bracket"}) + self.emitCurrentToken() + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + self.state = self.attributeValueUnQuotedState + elif data in ("=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "equals-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + return True + + def attributeValueDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute('"') + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-double-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("\"", "&", "\u0000")) + return True + + def attributeValueSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute("'") + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-single-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("'", "&", "\u0000")) + return True + + def attributeValueUnQuotedState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == "&": + self.processEntityInAttribute(">") + elif data == ">": + self.emitCurrentToken() + elif data in ('"', "'", "=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-no-quotes"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.stream.charsUntil( + frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) + return True + + def afterAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-EOF-after-attribute-value"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-attribute-value"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def selfClosingStartTagState(self): + data = self.stream.char() + if data == ">": + self.currentToken["selfClosing"] = True + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "unexpected-EOF-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def bogusCommentState(self): + # Make a new comment token and give it as value all the characters + # until the first > or EOF (charsUntil checks for EOF automatically) + # and emit it. + data = self.stream.charsUntil(">") + data = data.replace("\u0000", "\uFFFD") + self.tokenQueue.append( + {"type": tokenTypes["Comment"], "data": data}) + + # Eat the character directly after the bogus comment which is either a + # ">" or an EOF. + self.stream.char() + self.state = self.dataState + return True + + def markupDeclarationOpenState(self): + charStack = [self.stream.char()] + if charStack[-1] == "-": + charStack.append(self.stream.char()) + if charStack[-1] == "-": + self.currentToken = {"type": tokenTypes["Comment"], "data": ""} + self.state = self.commentStartState + return True + elif charStack[-1] in ('d', 'D'): + matched = True + for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), + ('y', 'Y'), ('p', 'P'), ('e', 'E')): + charStack.append(self.stream.char()) + if charStack[-1] not in expected: + matched = False + break + if matched: + self.currentToken = {"type": tokenTypes["Doctype"], + "name": "", + "publicId": None, "systemId": None, + "correct": True} + self.state = self.doctypeState + return True + elif (charStack[-1] == "[" and + self.parser is not None and + self.parser.tree.openElements and + self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): + matched = True + for expected in ["C", "D", "A", "T", "A", "["]: + charStack.append(self.stream.char()) + if charStack[-1] != expected: + matched = False + break + if matched: + self.state = self.cdataSectionState + return True + + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-dashes-or-doctype"}) + + while charStack: + self.stream.unget(charStack.pop()) + self.state = self.bogusCommentState + return True + + def commentStartState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentStartDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + self.state = self.commentState + return True + + def commentStartDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + \ + self.stream.charsUntil(("-", "\u0000")) + return True + + def commentEndDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentEndState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--\uFFFD" + self.state = self.commentState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-bang-after-double-dash-in-comment"}) + self.state = self.commentEndBangState + elif data == "-": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-dash-after-double-dash-in-comment"}) + self.currentToken["data"] += data + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-double-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-comment"}) + self.currentToken["data"] += "--" + data + self.state = self.commentState + return True + + def commentEndBangState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "-": + self.currentToken["data"] += "--!" + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--!\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-bang-state"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "--!" + data + self.state = self.commentState + return True + + def doctypeState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "need-space-after-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeNameState + return True + + def beforeDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-right-bracket"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] = "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] = data + self.state = self.doctypeNameState + return True + + def doctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.state = self.afterDoctypeNameState + elif data == ">": + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype-name"}) + self.currentToken["correct"] = False + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] += data + return True + + def afterDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.currentToken["correct"] = False + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + if data in ("p", "P"): + matched = True + for expected in (("u", "U"), ("b", "B"), ("l", "L"), + ("i", "I"), ("c", "C")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypePublicKeywordState + return True + elif data in ("s", "S"): + matched = True + for expected in (("y", "Y"), ("s", "S"), ("t", "T"), + ("e", "E"), ("m", "M")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypeSystemKeywordState + return True + + # All the characters read before the current 'data' will be + # [a-zA-Z], so they're garbage in the bogus doctype and can be + # discarded; only the latest character might be '>' or EOF + # and needs to be ungetted + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-space-or-right-bracket-in-doctype", "datavars": + {"data": data}}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + + return True + + def afterDoctypePublicKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypePublicIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + return True + + def beforeDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypePublicIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def doctypePublicIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def afterDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.betweenDoctypePublicAndSystemIdentifiersState + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def betweenDoctypePublicAndSystemIdentifiersState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def afterDoctypeSystemKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeSystemIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + return True + + def beforeDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypeSystemIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def doctypeSystemIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def afterDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.state = self.bogusDoctypeState + return True + + def bogusDoctypeState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + # XXX EMIT + self.stream.unget(data) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + pass + return True + + def cdataSectionState(self): + data = [] + while True: + data.append(self.stream.charsUntil("]")) + data.append(self.stream.charsUntil(">")) + char = self.stream.char() + if char == EOF: + break + else: + assert char == ">" + if data[-1][-2:] == "]]": + data[-1] = data[-1][:-2] + break + else: + data.append(char) + + data = "".join(data) # pylint:disable=redefined-variable-type + # Deal with null here rather than in the parser + nullCount = data.count("\u0000") + if nullCount > 0: + for _ in range(nullCount): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + data = data.replace("\u0000", "\uFFFD") + if data: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": data}) + self.state = self.dataState + return True diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py new file mode 100644 index 0000000..a5ba4bf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__init__.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import, division, unicode_literals + +from .py import Trie as PyTrie + +Trie = PyTrie + +# pylint:disable=wrong-import-position +try: + from .datrie import Trie as DATrie +except ImportError: + pass +else: + Trie = DATrie +# pylint:enable=wrong-import-position diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..61c157c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc new file mode 100644 index 0000000..320288f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc new file mode 100644 index 0000000..8b92e35 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc new file mode 100644 index 0000000..a71e886 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py new file mode 100644 index 0000000..a1158bb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/_base.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import Mapping + + +class Trie(Mapping): + """Abstract base class for tries""" + + def keys(self, prefix=None): + # pylint:disable=arguments-differ + keys = super(Trie, self).keys() + + if prefix is None: + return set(keys) + + return {x for x in keys if x.startswith(prefix)} + + def has_keys_with_prefix(self, prefix): + for key in self.keys(): + if key.startswith(prefix): + return True + + return False + + def longest_prefix(self, prefix): + if prefix in self: + return prefix + + for i in range(1, len(prefix) + 1): + if prefix[:-i] in self: + return prefix[:-i] + + raise KeyError(prefix) + + def longest_prefix_item(self, prefix): + lprefix = self.longest_prefix(prefix) + return (lprefix, self[lprefix]) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py new file mode 100644 index 0000000..e2e5f86 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/datrie.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import, division, unicode_literals + +from datrie import Trie as DATrie +from pip._vendor.six import text_type + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + chars = set() + for key in data.keys(): + if not isinstance(key, text_type): + raise TypeError("All keys must be strings") + for char in key: + chars.add(char) + + self._data = DATrie("".join(chars)) + for key, value in data.items(): + self._data[key] = value + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + raise NotImplementedError() + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + return self._data.keys(prefix) + + def has_keys_with_prefix(self, prefix): + return self._data.has_keys_with_prefix(prefix) + + def longest_prefix(self, prefix): + return self._data.longest_prefix(prefix) + + def longest_prefix_item(self, prefix): + return self._data.longest_prefix_item(prefix) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/py.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/py.py new file mode 100644 index 0000000..c178b21 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_trie/py.py @@ -0,0 +1,67 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from bisect import bisect_left + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + if not all(isinstance(x, text_type) for x in data.keys()): + raise TypeError("All keys must be strings") + + self._data = data + self._keys = sorted(data.keys()) + self._cachestr = "" + self._cachepoints = (0, len(data)) + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + return iter(self._data) + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + if prefix is None or prefix == "" or not self._keys: + return set(self._keys) + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + start = i = bisect_left(self._keys, prefix, lo, hi) + else: + start = i = bisect_left(self._keys, prefix) + + keys = set() + if start == len(self._keys): + return keys + + while self._keys[i].startswith(prefix): + keys.add(self._keys[i]) + i += 1 + + self._cachestr = prefix + self._cachepoints = (start, i) + + return keys + + def has_keys_with_prefix(self, prefix): + if prefix in self._data: + return True + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + i = bisect_left(self._keys, prefix, lo, hi) + else: + i = bisect_left(self._keys, prefix) + + if i == len(self._keys): + return False + + return self._keys[i].startswith(prefix) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_utils.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_utils.py new file mode 100644 index 0000000..0703afb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/_utils.py @@ -0,0 +1,124 @@ +from __future__ import absolute_import, division, unicode_literals + +from types import ModuleType + +from pip._vendor.six import text_type + +try: + import xml.etree.cElementTree as default_etree +except ImportError: + import xml.etree.ElementTree as default_etree + + +__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", + "surrogatePairToCodepoint", "moduleFactoryFactory", + "supports_lone_surrogates"] + + +# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be +# caught by the below test. In general this would be any platform +# using UTF-16 as its encoding of unicode strings, such as +# Jython. This is because UTF-16 itself is based on the use of such +# surrogates, and there is no mechanism to further escape such +# escapes. +try: + _x = eval('"\\uD800"') # pylint:disable=eval-used + if not isinstance(_x, text_type): + # We need this with u"" because of http://bugs.jython.org/issue2039 + _x = eval('u"\\uD800"') # pylint:disable=eval-used + assert isinstance(_x, text_type) +except: # pylint:disable=bare-except + supports_lone_surrogates = False +else: + supports_lone_surrogates = True + + +class MethodDispatcher(dict): + """Dict with 2 special properties: + + On initiation, keys that are lists, sets or tuples are converted to + multiple keys so accessing any one of the items in the original + list-like object returns the matching value + + md = MethodDispatcher({("foo", "bar"):"baz"}) + md["foo"] == "baz" + + A default value which can be set through the default attribute. + """ + + def __init__(self, items=()): + # Using _dictEntries instead of directly assigning to self is about + # twice as fast. Please do careful performance testing before changing + # anything here. + _dictEntries = [] + for name, value in items: + if isinstance(name, (list, tuple, frozenset, set)): + for item in name: + _dictEntries.append((item, value)) + else: + _dictEntries.append((name, value)) + dict.__init__(self, _dictEntries) + assert len(self) == len(_dictEntries) + self.default = None + + def __getitem__(self, key): + return dict.get(self, key, self.default) + + +# Some utility functions to deal with weirdness around UCS2 vs UCS4 +# python builds + +def isSurrogatePair(data): + return (len(data) == 2 and + ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and + ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) + + +def surrogatePairToCodepoint(data): + char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + + (ord(data[1]) - 0xDC00)) + return char_val + +# Module Factory Factory (no, this isn't Java, I know) +# Here to stop this being duplicated all over the place. + + +def moduleFactoryFactory(factory): + moduleCache = {} + + def moduleFactory(baseModule, *args, **kwargs): + if isinstance(ModuleType.__name__, type("")): + name = "_%s_factory" % baseModule.__name__ + else: + name = b"_%s_factory" % baseModule.__name__ + + kwargs_tuple = tuple(kwargs.items()) + + try: + return moduleCache[name][args][kwargs_tuple] + except KeyError: + mod = ModuleType(name) + objs = factory(baseModule, *args, **kwargs) + mod.__dict__.update(objs) + if "name" not in moduleCache: + moduleCache[name] = {} + if "args" not in moduleCache[name]: + moduleCache[name][args] = {} + if "kwargs" not in moduleCache[name][args]: + moduleCache[name][args][kwargs_tuple] = {} + moduleCache[name][args][kwargs_tuple] = mod + return mod + + return moduleFactory + + +def memoize(func): + cache = {} + + def wrapped(*args, **kwargs): + key = (tuple(args), tuple(kwargs.items())) + if key not in cache: + cache[key] = func(*args, **kwargs) + return cache[key] + + return wrapped diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/constants.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/constants.py new file mode 100644 index 0000000..1ff8041 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/constants.py @@ -0,0 +1,2947 @@ +from __future__ import absolute_import, division, unicode_literals + +import string + +EOF = None + +E = { + "null-character": + "Null character in input stream, replaced with U+FFFD.", + "invalid-codepoint": + "Invalid codepoint in stream.", + "incorrectly-placed-solidus": + "Solidus (/) incorrectly placed in tag.", + "incorrect-cr-newline-entity": + "Incorrect CR newline entity, replaced with LF.", + "illegal-windows-1252-entity": + "Entity used with illegal number (windows-1252 reference).", + "cant-convert-numeric-entity": + "Numeric entity couldn't be converted to character " + "(codepoint U+%(charAsInt)08x).", + "illegal-codepoint-for-numeric-entity": + "Numeric entity represents an illegal codepoint: " + "U+%(charAsInt)08x.", + "numeric-entity-without-semicolon": + "Numeric entity didn't end with ';'.", + "expected-numeric-entity-but-got-eof": + "Numeric entity expected. Got end of file instead.", + "expected-numeric-entity": + "Numeric entity expected but none found.", + "named-entity-without-semicolon": + "Named entity didn't end with ';'.", + "expected-named-entity": + "Named entity expected. Got none.", + "attributes-in-end-tag": + "End tag contains unexpected attributes.", + 'self-closing-flag-on-end-tag': + "End tag contains unexpected self-closing flag.", + "expected-tag-name-but-got-right-bracket": + "Expected tag name. Got '>' instead.", + "expected-tag-name-but-got-question-mark": + "Expected tag name. Got '?' instead. (HTML doesn't " + "support processing instructions.)", + "expected-tag-name": + "Expected tag name. Got something else instead", + "expected-closing-tag-but-got-right-bracket": + "Expected closing tag. Got '>' instead. Ignoring '</>'.", + "expected-closing-tag-but-got-eof": + "Expected closing tag. Unexpected end of file.", + "expected-closing-tag-but-got-char": + "Expected closing tag. Unexpected character '%(data)s' found.", + "eof-in-tag-name": + "Unexpected end of file in the tag name.", + "expected-attribute-name-but-got-eof": + "Unexpected end of file. Expected attribute name instead.", + "eof-in-attribute-name": + "Unexpected end of file in attribute name.", + "invalid-character-in-attribute-name": + "Invalid character in attribute name", + "duplicate-attribute": + "Dropped duplicate attribute on tag.", + "expected-end-of-tag-name-but-got-eof": + "Unexpected end of file. Expected = or end of tag.", + "expected-attribute-value-but-got-eof": + "Unexpected end of file. Expected attribute value.", + "expected-attribute-value-but-got-right-bracket": + "Expected attribute value. Got '>' instead.", + 'equals-in-unquoted-attribute-value': + "Unexpected = in unquoted attribute", + 'unexpected-character-in-unquoted-attribute-value': + "Unexpected character in unquoted attribute", + "invalid-character-after-attribute-name": + "Unexpected character after attribute name.", + "unexpected-character-after-attribute-value": + "Unexpected character after attribute value.", + "eof-in-attribute-value-double-quote": + "Unexpected end of file in attribute value (\").", + "eof-in-attribute-value-single-quote": + "Unexpected end of file in attribute value (').", + "eof-in-attribute-value-no-quotes": + "Unexpected end of file in attribute value.", + "unexpected-EOF-after-solidus-in-tag": + "Unexpected end of file in tag. Expected >", + "unexpected-character-after-solidus-in-tag": + "Unexpected character after / in tag. Expected >", + "expected-dashes-or-doctype": + "Expected '--' or 'DOCTYPE'. Not found.", + "unexpected-bang-after-double-dash-in-comment": + "Unexpected ! after -- in comment", + "unexpected-space-after-double-dash-in-comment": + "Unexpected space after -- in comment", + "incorrect-comment": + "Incorrect comment.", + "eof-in-comment": + "Unexpected end of file in comment.", + "eof-in-comment-end-dash": + "Unexpected end of file in comment (-)", + "unexpected-dash-after-double-dash-in-comment": + "Unexpected '-' after '--' found in comment.", + "eof-in-comment-double-dash": + "Unexpected end of file in comment (--).", + "eof-in-comment-end-space-state": + "Unexpected end of file in comment.", + "eof-in-comment-end-bang-state": + "Unexpected end of file in comment.", + "unexpected-char-in-comment": + "Unexpected character in comment found.", + "need-space-after-doctype": + "No space after literal string 'DOCTYPE'.", + "expected-doctype-name-but-got-right-bracket": + "Unexpected > character. Expected DOCTYPE name.", + "expected-doctype-name-but-got-eof": + "Unexpected end of file. Expected DOCTYPE name.", + "eof-in-doctype-name": + "Unexpected end of file in DOCTYPE name.", + "eof-in-doctype": + "Unexpected end of file in DOCTYPE.", + "expected-space-or-right-bracket-in-doctype": + "Expected space or '>'. Got '%(data)s'", + "unexpected-end-of-doctype": + "Unexpected end of DOCTYPE.", + "unexpected-char-in-doctype": + "Unexpected character in DOCTYPE.", + "eof-in-innerhtml": + "XXX innerHTML EOF", + "unexpected-doctype": + "Unexpected DOCTYPE. Ignored.", + "non-html-root": + "html needs to be the first start tag.", + "expected-doctype-but-got-eof": + "Unexpected End of file. Expected DOCTYPE.", + "unknown-doctype": + "Erroneous DOCTYPE.", + "expected-doctype-but-got-chars": + "Unexpected non-space characters. Expected DOCTYPE.", + "expected-doctype-but-got-start-tag": + "Unexpected start tag (%(name)s). Expected DOCTYPE.", + "expected-doctype-but-got-end-tag": + "Unexpected end tag (%(name)s). Expected DOCTYPE.", + "end-tag-after-implied-root": + "Unexpected end tag (%(name)s) after the (implied) root element.", + "expected-named-closing-tag-but-got-eof": + "Unexpected end of file. Expected end tag (%(name)s).", + "two-heads-are-not-better-than-one": + "Unexpected start tag head in existing head. Ignored.", + "unexpected-end-tag": + "Unexpected end tag (%(name)s). Ignored.", + "unexpected-start-tag-out-of-my-head": + "Unexpected start tag (%(name)s) that can be in head. Moved.", + "unexpected-start-tag": + "Unexpected start tag (%(name)s).", + "missing-end-tag": + "Missing end tag (%(name)s).", + "missing-end-tags": + "Missing end tags (%(name)s).", + "unexpected-start-tag-implies-end-tag": + "Unexpected start tag (%(startName)s) " + "implies end tag (%(endName)s).", + "unexpected-start-tag-treated-as": + "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", + "deprecated-tag": + "Unexpected start tag %(name)s. Don't use it!", + "unexpected-start-tag-ignored": + "Unexpected start tag %(name)s. Ignored.", + "expected-one-end-tag-but-got-another": + "Unexpected end tag (%(gotName)s). " + "Missing end tag (%(expectedName)s).", + "end-tag-too-early": + "End tag (%(name)s) seen too early. Expected other end tag.", + "end-tag-too-early-named": + "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", + "end-tag-too-early-ignored": + "End tag (%(name)s) seen too early. Ignored.", + "adoption-agency-1.1": + "End tag (%(name)s) violates step 1, " + "paragraph 1 of the adoption agency algorithm.", + "adoption-agency-1.2": + "End tag (%(name)s) violates step 1, " + "paragraph 2 of the adoption agency algorithm.", + "adoption-agency-1.3": + "End tag (%(name)s) violates step 1, " + "paragraph 3 of the adoption agency algorithm.", + "adoption-agency-4.4": + "End tag (%(name)s) violates step 4, " + "paragraph 4 of the adoption agency algorithm.", + "unexpected-end-tag-treated-as": + "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", + "no-end-tag": + "This element (%(name)s) has no end tag.", + "unexpected-implied-end-tag-in-table": + "Unexpected implied end tag (%(name)s) in the table phase.", + "unexpected-implied-end-tag-in-table-body": + "Unexpected implied end tag (%(name)s) in the table body phase.", + "unexpected-char-implies-table-voodoo": + "Unexpected non-space characters in " + "table context caused voodoo mode.", + "unexpected-hidden-input-in-table": + "Unexpected input with type hidden in table context.", + "unexpected-form-in-table": + "Unexpected form in table context.", + "unexpected-start-tag-implies-table-voodoo": + "Unexpected start tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-end-tag-implies-table-voodoo": + "Unexpected end tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-cell-in-table-body": + "Unexpected table cell start tag (%(name)s) " + "in the table body phase.", + "unexpected-cell-end-tag": + "Got table cell end tag (%(name)s) " + "while required end tags are missing.", + "unexpected-end-tag-in-table-body": + "Unexpected end tag (%(name)s) in the table body phase. Ignored.", + "unexpected-implied-end-tag-in-table-row": + "Unexpected implied end tag (%(name)s) in the table row phase.", + "unexpected-end-tag-in-table-row": + "Unexpected end tag (%(name)s) in the table row phase. Ignored.", + "unexpected-select-in-select": + "Unexpected select start tag in the select phase " + "treated as select end tag.", + "unexpected-input-in-select": + "Unexpected input start tag in the select phase.", + "unexpected-start-tag-in-select": + "Unexpected start tag token (%(name)s in the select phase. " + "Ignored.", + "unexpected-end-tag-in-select": + "Unexpected end tag (%(name)s) in the select phase. Ignored.", + "unexpected-table-element-start-tag-in-select-in-table": + "Unexpected table element start tag (%(name)s) in the select in table phase.", + "unexpected-table-element-end-tag-in-select-in-table": + "Unexpected table element end tag (%(name)s) in the select in table phase.", + "unexpected-char-after-body": + "Unexpected non-space characters in the after body phase.", + "unexpected-start-tag-after-body": + "Unexpected start tag token (%(name)s)" + " in the after body phase.", + "unexpected-end-tag-after-body": + "Unexpected end tag token (%(name)s)" + " in the after body phase.", + "unexpected-char-in-frameset": + "Unexpected characters in the frameset phase. Characters ignored.", + "unexpected-start-tag-in-frameset": + "Unexpected start tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-frameset-in-frameset-innerhtml": + "Unexpected end tag token (frameset) " + "in the frameset phase (innerHTML).", + "unexpected-end-tag-in-frameset": + "Unexpected end tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-char-after-frameset": + "Unexpected non-space characters in the " + "after frameset phase. Ignored.", + "unexpected-start-tag-after-frameset": + "Unexpected start tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-frameset": + "Unexpected end tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-body-innerhtml": + "Unexpected end tag after body(innerHtml)", + "expected-eof-but-got-char": + "Unexpected non-space characters. Expected end of file.", + "expected-eof-but-got-start-tag": + "Unexpected start tag (%(name)s)" + ". Expected end of file.", + "expected-eof-but-got-end-tag": + "Unexpected end tag (%(name)s)" + ". Expected end of file.", + "eof-in-table": + "Unexpected end of file. Expected table content.", + "eof-in-select": + "Unexpected end of file. Expected select content.", + "eof-in-frameset": + "Unexpected end of file. Expected frameset content.", + "eof-in-script-in-script": + "Unexpected end of file. Expected script content.", + "eof-in-foreign-lands": + "Unexpected end of file. Expected foreign content", + "non-void-element-with-trailing-solidus": + "Trailing solidus not allowed on element %(name)s", + "unexpected-html-element-in-foreign-content": + "Element %(name)s not allowed in a non-html context", + "unexpected-end-tag-before-html": + "Unexpected end tag (%(name)s) before html.", + "unexpected-inhead-noscript-tag": + "Element %(name)s not allowed in a inhead-noscript context", + "eof-in-head-noscript": + "Unexpected end of file. Expected inhead-noscript content", + "char-in-head-noscript": + "Unexpected non-space character. Expected inhead-noscript content", + "XXX-undefined-error": + "Undefined error (this sucks and should be fixed)", +} + +namespaces = { + "html": "http://www.w3.org/1999/xhtml", + "mathml": "http://www.w3.org/1998/Math/MathML", + "svg": "http://www.w3.org/2000/svg", + "xlink": "http://www.w3.org/1999/xlink", + "xml": "http://www.w3.org/XML/1998/namespace", + "xmlns": "http://www.w3.org/2000/xmlns/" +} + +scopingElements = frozenset([ + (namespaces["html"], "applet"), + (namespaces["html"], "caption"), + (namespaces["html"], "html"), + (namespaces["html"], "marquee"), + (namespaces["html"], "object"), + (namespaces["html"], "table"), + (namespaces["html"], "td"), + (namespaces["html"], "th"), + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext"), + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title"), +]) + +formattingElements = frozenset([ + (namespaces["html"], "a"), + (namespaces["html"], "b"), + (namespaces["html"], "big"), + (namespaces["html"], "code"), + (namespaces["html"], "em"), + (namespaces["html"], "font"), + (namespaces["html"], "i"), + (namespaces["html"], "nobr"), + (namespaces["html"], "s"), + (namespaces["html"], "small"), + (namespaces["html"], "strike"), + (namespaces["html"], "strong"), + (namespaces["html"], "tt"), + (namespaces["html"], "u") +]) + +specialElements = frozenset([ + (namespaces["html"], "address"), + (namespaces["html"], "applet"), + (namespaces["html"], "area"), + (namespaces["html"], "article"), + (namespaces["html"], "aside"), + (namespaces["html"], "base"), + (namespaces["html"], "basefont"), + (namespaces["html"], "bgsound"), + (namespaces["html"], "blockquote"), + (namespaces["html"], "body"), + (namespaces["html"], "br"), + (namespaces["html"], "button"), + (namespaces["html"], "caption"), + (namespaces["html"], "center"), + (namespaces["html"], "col"), + (namespaces["html"], "colgroup"), + (namespaces["html"], "command"), + (namespaces["html"], "dd"), + (namespaces["html"], "details"), + (namespaces["html"], "dir"), + (namespaces["html"], "div"), + (namespaces["html"], "dl"), + (namespaces["html"], "dt"), + (namespaces["html"], "embed"), + (namespaces["html"], "fieldset"), + (namespaces["html"], "figure"), + (namespaces["html"], "footer"), + (namespaces["html"], "form"), + (namespaces["html"], "frame"), + (namespaces["html"], "frameset"), + (namespaces["html"], "h1"), + (namespaces["html"], "h2"), + (namespaces["html"], "h3"), + (namespaces["html"], "h4"), + (namespaces["html"], "h5"), + (namespaces["html"], "h6"), + (namespaces["html"], "head"), + (namespaces["html"], "header"), + (namespaces["html"], "hr"), + (namespaces["html"], "html"), + (namespaces["html"], "iframe"), + # Note that image is commented out in the spec as "this isn't an + # element that can end up on the stack, so it doesn't matter," + (namespaces["html"], "image"), + (namespaces["html"], "img"), + (namespaces["html"], "input"), + (namespaces["html"], "isindex"), + (namespaces["html"], "li"), + (namespaces["html"], "link"), + (namespaces["html"], "listing"), + (namespaces["html"], "marquee"), + (namespaces["html"], "menu"), + (namespaces["html"], "meta"), + (namespaces["html"], "nav"), + (namespaces["html"], "noembed"), + (namespaces["html"], "noframes"), + (namespaces["html"], "noscript"), + (namespaces["html"], "object"), + (namespaces["html"], "ol"), + (namespaces["html"], "p"), + (namespaces["html"], "param"), + (namespaces["html"], "plaintext"), + (namespaces["html"], "pre"), + (namespaces["html"], "script"), + (namespaces["html"], "section"), + (namespaces["html"], "select"), + (namespaces["html"], "style"), + (namespaces["html"], "table"), + (namespaces["html"], "tbody"), + (namespaces["html"], "td"), + (namespaces["html"], "textarea"), + (namespaces["html"], "tfoot"), + (namespaces["html"], "th"), + (namespaces["html"], "thead"), + (namespaces["html"], "title"), + (namespaces["html"], "tr"), + (namespaces["html"], "ul"), + (namespaces["html"], "wbr"), + (namespaces["html"], "xmp"), + (namespaces["svg"], "foreignObject") +]) + +htmlIntegrationPointElements = frozenset([ + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title") +]) + +mathmlTextIntegrationPointElements = frozenset([ + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext") +]) + +adjustSVGAttributes = { + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan" +} + +adjustMathMLAttributes = {"definitionurl": "definitionURL"} + +adjustForeignAttributes = { + "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), + "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), + "xlink:href": ("xlink", "href", namespaces["xlink"]), + "xlink:role": ("xlink", "role", namespaces["xlink"]), + "xlink:show": ("xlink", "show", namespaces["xlink"]), + "xlink:title": ("xlink", "title", namespaces["xlink"]), + "xlink:type": ("xlink", "type", namespaces["xlink"]), + "xml:base": ("xml", "base", namespaces["xml"]), + "xml:lang": ("xml", "lang", namespaces["xml"]), + "xml:space": ("xml", "space", namespaces["xml"]), + "xmlns": (None, "xmlns", namespaces["xmlns"]), + "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) +} + +unadjustForeignAttributes = dict([((ns, local), qname) for qname, (prefix, local, ns) in + adjustForeignAttributes.items()]) + +spaceCharacters = frozenset([ + "\t", + "\n", + "\u000C", + " ", + "\r" +]) + +tableInsertModeElements = frozenset([ + "table", + "tbody", + "tfoot", + "thead", + "tr" +]) + +asciiLowercase = frozenset(string.ascii_lowercase) +asciiUppercase = frozenset(string.ascii_uppercase) +asciiLetters = frozenset(string.ascii_letters) +digits = frozenset(string.digits) +hexDigits = frozenset(string.hexdigits) + +asciiUpper2Lower = dict([(ord(c), ord(c.lower())) + for c in string.ascii_uppercase]) + +# Heading elements need to be ordered +headingElements = ( + "h1", + "h2", + "h3", + "h4", + "h5", + "h6" +) + +voidElements = frozenset([ + "base", + "command", + "event-source", + "link", + "meta", + "hr", + "br", + "img", + "embed", + "param", + "area", + "col", + "input", + "source", + "track" +]) + +cdataElements = frozenset(['title', 'textarea']) + +rcdataElements = frozenset([ + 'style', + 'script', + 'xmp', + 'iframe', + 'noembed', + 'noframes', + 'noscript' +]) + +booleanAttributes = { + "": frozenset(["irrelevant", "itemscope"]), + "style": frozenset(["scoped"]), + "img": frozenset(["ismap"]), + "audio": frozenset(["autoplay", "controls"]), + "video": frozenset(["autoplay", "controls"]), + "script": frozenset(["defer", "async"]), + "details": frozenset(["open"]), + "datagrid": frozenset(["multiple", "disabled"]), + "command": frozenset(["hidden", "disabled", "checked", "default"]), + "hr": frozenset(["noshade"]), + "menu": frozenset(["autosubmit"]), + "fieldset": frozenset(["disabled", "readonly"]), + "option": frozenset(["disabled", "readonly", "selected"]), + "optgroup": frozenset(["disabled", "readonly"]), + "button": frozenset(["disabled", "autofocus"]), + "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), + "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), + "output": frozenset(["disabled", "readonly"]), + "iframe": frozenset(["seamless"]), +} + +# entitiesWindows1252 has to be _ordered_ and needs to have an index. It +# therefore can't be a frozenset. +entitiesWindows1252 = ( + 8364, # 0x80 0x20AC EURO SIGN + 65533, # 0x81 UNDEFINED + 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK + 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK + 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK + 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS + 8224, # 0x86 0x2020 DAGGER + 8225, # 0x87 0x2021 DOUBLE DAGGER + 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT + 8240, # 0x89 0x2030 PER MILLE SIGN + 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON + 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE + 65533, # 0x8D UNDEFINED + 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON + 65533, # 0x8F UNDEFINED + 65533, # 0x90 UNDEFINED + 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK + 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK + 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK + 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK + 8226, # 0x95 0x2022 BULLET + 8211, # 0x96 0x2013 EN DASH + 8212, # 0x97 0x2014 EM DASH + 732, # 0x98 0x02DC SMALL TILDE + 8482, # 0x99 0x2122 TRADE MARK SIGN + 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON + 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE + 65533, # 0x9D UNDEFINED + 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON + 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +) + +xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) + +entities = { + "AElig": "\xc6", + "AElig;": "\xc6", + "AMP": "&", + "AMP;": "&", + "Aacute": "\xc1", + "Aacute;": "\xc1", + "Abreve;": "\u0102", + "Acirc": "\xc2", + "Acirc;": "\xc2", + "Acy;": "\u0410", + "Afr;": "\U0001d504", + "Agrave": "\xc0", + "Agrave;": "\xc0", + "Alpha;": "\u0391", + "Amacr;": "\u0100", + "And;": "\u2a53", + "Aogon;": "\u0104", + "Aopf;": "\U0001d538", + "ApplyFunction;": "\u2061", + "Aring": "\xc5", + "Aring;": "\xc5", + "Ascr;": "\U0001d49c", + "Assign;": "\u2254", + "Atilde": "\xc3", + "Atilde;": "\xc3", + "Auml": "\xc4", + "Auml;": "\xc4", + "Backslash;": "\u2216", + "Barv;": "\u2ae7", + "Barwed;": "\u2306", + "Bcy;": "\u0411", + "Because;": "\u2235", + "Bernoullis;": "\u212c", + "Beta;": "\u0392", + "Bfr;": "\U0001d505", + "Bopf;": "\U0001d539", + "Breve;": "\u02d8", + "Bscr;": "\u212c", + "Bumpeq;": "\u224e", + "CHcy;": "\u0427", + "COPY": "\xa9", + "COPY;": "\xa9", + "Cacute;": "\u0106", + "Cap;": "\u22d2", + "CapitalDifferentialD;": "\u2145", + "Cayleys;": "\u212d", + "Ccaron;": "\u010c", + "Ccedil": "\xc7", + "Ccedil;": "\xc7", + "Ccirc;": "\u0108", + "Cconint;": "\u2230", + "Cdot;": "\u010a", + "Cedilla;": "\xb8", + "CenterDot;": "\xb7", + "Cfr;": "\u212d", + "Chi;": "\u03a7", + "CircleDot;": "\u2299", + "CircleMinus;": "\u2296", + "CirclePlus;": "\u2295", + "CircleTimes;": "\u2297", + "ClockwiseContourIntegral;": "\u2232", + "CloseCurlyDoubleQuote;": "\u201d", + "CloseCurlyQuote;": "\u2019", + "Colon;": "\u2237", + "Colone;": "\u2a74", + "Congruent;": "\u2261", + "Conint;": "\u222f", + "ContourIntegral;": "\u222e", + "Copf;": "\u2102", + "Coproduct;": "\u2210", + "CounterClockwiseContourIntegral;": "\u2233", + "Cross;": "\u2a2f", + "Cscr;": "\U0001d49e", + "Cup;": "\u22d3", + "CupCap;": "\u224d", + "DD;": "\u2145", + "DDotrahd;": "\u2911", + "DJcy;": "\u0402", + "DScy;": "\u0405", + "DZcy;": "\u040f", + "Dagger;": "\u2021", + "Darr;": "\u21a1", + "Dashv;": "\u2ae4", + "Dcaron;": "\u010e", + "Dcy;": "\u0414", + "Del;": "\u2207", + "Delta;": "\u0394", + "Dfr;": "\U0001d507", + "DiacriticalAcute;": "\xb4", + "DiacriticalDot;": "\u02d9", + "DiacriticalDoubleAcute;": "\u02dd", + "DiacriticalGrave;": "`", + "DiacriticalTilde;": "\u02dc", + "Diamond;": "\u22c4", + "DifferentialD;": "\u2146", + "Dopf;": "\U0001d53b", + "Dot;": "\xa8", + "DotDot;": "\u20dc", + "DotEqual;": "\u2250", + "DoubleContourIntegral;": "\u222f", + "DoubleDot;": "\xa8", + "DoubleDownArrow;": "\u21d3", + "DoubleLeftArrow;": "\u21d0", + "DoubleLeftRightArrow;": "\u21d4", + "DoubleLeftTee;": "\u2ae4", + "DoubleLongLeftArrow;": "\u27f8", + "DoubleLongLeftRightArrow;": "\u27fa", + "DoubleLongRightArrow;": "\u27f9", + "DoubleRightArrow;": "\u21d2", + "DoubleRightTee;": "\u22a8", + "DoubleUpArrow;": "\u21d1", + "DoubleUpDownArrow;": "\u21d5", + "DoubleVerticalBar;": "\u2225", + "DownArrow;": "\u2193", + "DownArrowBar;": "\u2913", + "DownArrowUpArrow;": "\u21f5", + "DownBreve;": "\u0311", + "DownLeftRightVector;": "\u2950", + "DownLeftTeeVector;": "\u295e", + "DownLeftVector;": "\u21bd", + "DownLeftVectorBar;": "\u2956", + "DownRightTeeVector;": "\u295f", + "DownRightVector;": "\u21c1", + "DownRightVectorBar;": "\u2957", + "DownTee;": "\u22a4", + "DownTeeArrow;": "\u21a7", + "Downarrow;": "\u21d3", + "Dscr;": "\U0001d49f", + "Dstrok;": "\u0110", + "ENG;": "\u014a", + "ETH": "\xd0", + "ETH;": "\xd0", + "Eacute": "\xc9", + "Eacute;": "\xc9", + "Ecaron;": "\u011a", + "Ecirc": "\xca", + "Ecirc;": "\xca", + "Ecy;": "\u042d", + "Edot;": "\u0116", + "Efr;": "\U0001d508", + "Egrave": "\xc8", + "Egrave;": "\xc8", + "Element;": "\u2208", + "Emacr;": "\u0112", + "EmptySmallSquare;": "\u25fb", + "EmptyVerySmallSquare;": "\u25ab", + "Eogon;": "\u0118", + "Eopf;": "\U0001d53c", + "Epsilon;": "\u0395", + "Equal;": "\u2a75", + "EqualTilde;": "\u2242", + "Equilibrium;": "\u21cc", + "Escr;": "\u2130", + "Esim;": "\u2a73", + "Eta;": "\u0397", + "Euml": "\xcb", + "Euml;": "\xcb", + "Exists;": "\u2203", + "ExponentialE;": "\u2147", + "Fcy;": "\u0424", + "Ffr;": "\U0001d509", + "FilledSmallSquare;": "\u25fc", + "FilledVerySmallSquare;": "\u25aa", + "Fopf;": "\U0001d53d", + "ForAll;": "\u2200", + "Fouriertrf;": "\u2131", + "Fscr;": "\u2131", + "GJcy;": "\u0403", + "GT": ">", + "GT;": ">", + "Gamma;": "\u0393", + "Gammad;": "\u03dc", + "Gbreve;": "\u011e", + "Gcedil;": "\u0122", + "Gcirc;": "\u011c", + "Gcy;": "\u0413", + "Gdot;": "\u0120", + "Gfr;": "\U0001d50a", + "Gg;": "\u22d9", + "Gopf;": "\U0001d53e", + "GreaterEqual;": "\u2265", + "GreaterEqualLess;": "\u22db", + "GreaterFullEqual;": "\u2267", + "GreaterGreater;": "\u2aa2", + "GreaterLess;": "\u2277", + "GreaterSlantEqual;": "\u2a7e", + "GreaterTilde;": "\u2273", + "Gscr;": "\U0001d4a2", + "Gt;": "\u226b", + "HARDcy;": "\u042a", + "Hacek;": "\u02c7", + "Hat;": "^", + "Hcirc;": "\u0124", + "Hfr;": "\u210c", + "HilbertSpace;": "\u210b", + "Hopf;": "\u210d", + "HorizontalLine;": "\u2500", + "Hscr;": "\u210b", + "Hstrok;": "\u0126", + "HumpDownHump;": "\u224e", + "HumpEqual;": "\u224f", + "IEcy;": "\u0415", + "IJlig;": "\u0132", + "IOcy;": "\u0401", + "Iacute": "\xcd", + "Iacute;": "\xcd", + "Icirc": "\xce", + "Icirc;": "\xce", + "Icy;": "\u0418", + "Idot;": "\u0130", + "Ifr;": "\u2111", + "Igrave": "\xcc", + "Igrave;": "\xcc", + "Im;": "\u2111", + "Imacr;": "\u012a", + "ImaginaryI;": "\u2148", + "Implies;": "\u21d2", + "Int;": "\u222c", + "Integral;": "\u222b", + "Intersection;": "\u22c2", + "InvisibleComma;": "\u2063", + "InvisibleTimes;": "\u2062", + "Iogon;": "\u012e", + "Iopf;": "\U0001d540", + "Iota;": "\u0399", + "Iscr;": "\u2110", + "Itilde;": "\u0128", + "Iukcy;": "\u0406", + "Iuml": "\xcf", + "Iuml;": "\xcf", + "Jcirc;": "\u0134", + "Jcy;": "\u0419", + "Jfr;": "\U0001d50d", + "Jopf;": "\U0001d541", + "Jscr;": "\U0001d4a5", + "Jsercy;": "\u0408", + "Jukcy;": "\u0404", + "KHcy;": "\u0425", + "KJcy;": "\u040c", + "Kappa;": "\u039a", + "Kcedil;": "\u0136", + "Kcy;": "\u041a", + "Kfr;": "\U0001d50e", + "Kopf;": "\U0001d542", + "Kscr;": "\U0001d4a6", + "LJcy;": "\u0409", + "LT": "<", + "LT;": "<", + "Lacute;": "\u0139", + "Lambda;": "\u039b", + "Lang;": "\u27ea", + "Laplacetrf;": "\u2112", + "Larr;": "\u219e", + "Lcaron;": "\u013d", + "Lcedil;": "\u013b", + "Lcy;": "\u041b", + "LeftAngleBracket;": "\u27e8", + "LeftArrow;": "\u2190", + "LeftArrowBar;": "\u21e4", + "LeftArrowRightArrow;": "\u21c6", + "LeftCeiling;": "\u2308", + "LeftDoubleBracket;": "\u27e6", + "LeftDownTeeVector;": "\u2961", + "LeftDownVector;": "\u21c3", + "LeftDownVectorBar;": "\u2959", + "LeftFloor;": "\u230a", + "LeftRightArrow;": "\u2194", + "LeftRightVector;": "\u294e", + "LeftTee;": "\u22a3", + "LeftTeeArrow;": "\u21a4", + "LeftTeeVector;": "\u295a", + "LeftTriangle;": "\u22b2", + "LeftTriangleBar;": "\u29cf", + "LeftTriangleEqual;": "\u22b4", + "LeftUpDownVector;": "\u2951", + "LeftUpTeeVector;": "\u2960", + "LeftUpVector;": "\u21bf", + "LeftUpVectorBar;": "\u2958", + "LeftVector;": "\u21bc", + "LeftVectorBar;": "\u2952", + "Leftarrow;": "\u21d0", + "Leftrightarrow;": "\u21d4", + "LessEqualGreater;": "\u22da", + "LessFullEqual;": "\u2266", + "LessGreater;": "\u2276", + "LessLess;": "\u2aa1", + "LessSlantEqual;": "\u2a7d", + "LessTilde;": "\u2272", + "Lfr;": "\U0001d50f", + "Ll;": "\u22d8", + "Lleftarrow;": "\u21da", + "Lmidot;": "\u013f", + "LongLeftArrow;": "\u27f5", + "LongLeftRightArrow;": "\u27f7", + "LongRightArrow;": "\u27f6", + "Longleftarrow;": "\u27f8", + "Longleftrightarrow;": "\u27fa", + "Longrightarrow;": "\u27f9", + "Lopf;": "\U0001d543", + "LowerLeftArrow;": "\u2199", + "LowerRightArrow;": "\u2198", + "Lscr;": "\u2112", + "Lsh;": "\u21b0", + "Lstrok;": "\u0141", + "Lt;": "\u226a", + "Map;": "\u2905", + "Mcy;": "\u041c", + "MediumSpace;": "\u205f", + "Mellintrf;": "\u2133", + "Mfr;": "\U0001d510", + "MinusPlus;": "\u2213", + "Mopf;": "\U0001d544", + "Mscr;": "\u2133", + "Mu;": "\u039c", + "NJcy;": "\u040a", + "Nacute;": "\u0143", + "Ncaron;": "\u0147", + "Ncedil;": "\u0145", + "Ncy;": "\u041d", + "NegativeMediumSpace;": "\u200b", + "NegativeThickSpace;": "\u200b", + "NegativeThinSpace;": "\u200b", + "NegativeVeryThinSpace;": "\u200b", + "NestedGreaterGreater;": "\u226b", + "NestedLessLess;": "\u226a", + "NewLine;": "\n", + "Nfr;": "\U0001d511", + "NoBreak;": "\u2060", + "NonBreakingSpace;": "\xa0", + "Nopf;": "\u2115", + "Not;": "\u2aec", + "NotCongruent;": "\u2262", + "NotCupCap;": "\u226d", + "NotDoubleVerticalBar;": "\u2226", + "NotElement;": "\u2209", + "NotEqual;": "\u2260", + "NotEqualTilde;": "\u2242\u0338", + "NotExists;": "\u2204", + "NotGreater;": "\u226f", + "NotGreaterEqual;": "\u2271", + "NotGreaterFullEqual;": "\u2267\u0338", + "NotGreaterGreater;": "\u226b\u0338", + "NotGreaterLess;": "\u2279", + "NotGreaterSlantEqual;": "\u2a7e\u0338", + "NotGreaterTilde;": "\u2275", + "NotHumpDownHump;": "\u224e\u0338", + "NotHumpEqual;": "\u224f\u0338", + "NotLeftTriangle;": "\u22ea", + "NotLeftTriangleBar;": "\u29cf\u0338", + "NotLeftTriangleEqual;": "\u22ec", + "NotLess;": "\u226e", + "NotLessEqual;": "\u2270", + "NotLessGreater;": "\u2278", + "NotLessLess;": "\u226a\u0338", + "NotLessSlantEqual;": "\u2a7d\u0338", + "NotLessTilde;": "\u2274", + "NotNestedGreaterGreater;": "\u2aa2\u0338", + "NotNestedLessLess;": "\u2aa1\u0338", + "NotPrecedes;": "\u2280", + "NotPrecedesEqual;": "\u2aaf\u0338", + "NotPrecedesSlantEqual;": "\u22e0", + "NotReverseElement;": "\u220c", + "NotRightTriangle;": "\u22eb", + "NotRightTriangleBar;": "\u29d0\u0338", + "NotRightTriangleEqual;": "\u22ed", + "NotSquareSubset;": "\u228f\u0338", + "NotSquareSubsetEqual;": "\u22e2", + "NotSquareSuperset;": "\u2290\u0338", + "NotSquareSupersetEqual;": "\u22e3", + "NotSubset;": "\u2282\u20d2", + "NotSubsetEqual;": "\u2288", + "NotSucceeds;": "\u2281", + "NotSucceedsEqual;": "\u2ab0\u0338", + "NotSucceedsSlantEqual;": "\u22e1", + "NotSucceedsTilde;": "\u227f\u0338", + "NotSuperset;": "\u2283\u20d2", + "NotSupersetEqual;": "\u2289", + "NotTilde;": "\u2241", + "NotTildeEqual;": "\u2244", + "NotTildeFullEqual;": "\u2247", + "NotTildeTilde;": "\u2249", + "NotVerticalBar;": "\u2224", + "Nscr;": "\U0001d4a9", + "Ntilde": "\xd1", + "Ntilde;": "\xd1", + "Nu;": "\u039d", + "OElig;": "\u0152", + "Oacute": "\xd3", + "Oacute;": "\xd3", + "Ocirc": "\xd4", + "Ocirc;": "\xd4", + "Ocy;": "\u041e", + "Odblac;": "\u0150", + "Ofr;": "\U0001d512", + "Ograve": "\xd2", + "Ograve;": "\xd2", + "Omacr;": "\u014c", + "Omega;": "\u03a9", + "Omicron;": "\u039f", + "Oopf;": "\U0001d546", + "OpenCurlyDoubleQuote;": "\u201c", + "OpenCurlyQuote;": "\u2018", + "Or;": "\u2a54", + "Oscr;": "\U0001d4aa", + "Oslash": "\xd8", + "Oslash;": "\xd8", + "Otilde": "\xd5", + "Otilde;": "\xd5", + "Otimes;": "\u2a37", + "Ouml": "\xd6", + "Ouml;": "\xd6", + "OverBar;": "\u203e", + "OverBrace;": "\u23de", + "OverBracket;": "\u23b4", + "OverParenthesis;": "\u23dc", + "PartialD;": "\u2202", + "Pcy;": "\u041f", + "Pfr;": "\U0001d513", + "Phi;": "\u03a6", + "Pi;": "\u03a0", + "PlusMinus;": "\xb1", + "Poincareplane;": "\u210c", + "Popf;": "\u2119", + "Pr;": "\u2abb", + "Precedes;": "\u227a", + "PrecedesEqual;": "\u2aaf", + "PrecedesSlantEqual;": "\u227c", + "PrecedesTilde;": "\u227e", + "Prime;": "\u2033", + "Product;": "\u220f", + "Proportion;": "\u2237", + "Proportional;": "\u221d", + "Pscr;": "\U0001d4ab", + "Psi;": "\u03a8", + "QUOT": "\"", + "QUOT;": "\"", + "Qfr;": "\U0001d514", + "Qopf;": "\u211a", + "Qscr;": "\U0001d4ac", + "RBarr;": "\u2910", + "REG": "\xae", + "REG;": "\xae", + "Racute;": "\u0154", + "Rang;": "\u27eb", + "Rarr;": "\u21a0", + "Rarrtl;": "\u2916", + "Rcaron;": "\u0158", + "Rcedil;": "\u0156", + "Rcy;": "\u0420", + "Re;": "\u211c", + "ReverseElement;": "\u220b", + "ReverseEquilibrium;": "\u21cb", + "ReverseUpEquilibrium;": "\u296f", + "Rfr;": "\u211c", + "Rho;": "\u03a1", + "RightAngleBracket;": "\u27e9", + "RightArrow;": "\u2192", + "RightArrowBar;": "\u21e5", + "RightArrowLeftArrow;": "\u21c4", + "RightCeiling;": "\u2309", + "RightDoubleBracket;": "\u27e7", + "RightDownTeeVector;": "\u295d", + "RightDownVector;": "\u21c2", + "RightDownVectorBar;": "\u2955", + "RightFloor;": "\u230b", + "RightTee;": "\u22a2", + "RightTeeArrow;": "\u21a6", + "RightTeeVector;": "\u295b", + "RightTriangle;": "\u22b3", + "RightTriangleBar;": "\u29d0", + "RightTriangleEqual;": "\u22b5", + "RightUpDownVector;": "\u294f", + "RightUpTeeVector;": "\u295c", + "RightUpVector;": "\u21be", + "RightUpVectorBar;": "\u2954", + "RightVector;": "\u21c0", + "RightVectorBar;": "\u2953", + "Rightarrow;": "\u21d2", + "Ropf;": "\u211d", + "RoundImplies;": "\u2970", + "Rrightarrow;": "\u21db", + "Rscr;": "\u211b", + "Rsh;": "\u21b1", + "RuleDelayed;": "\u29f4", + "SHCHcy;": "\u0429", + "SHcy;": "\u0428", + "SOFTcy;": "\u042c", + "Sacute;": "\u015a", + "Sc;": "\u2abc", + "Scaron;": "\u0160", + "Scedil;": "\u015e", + "Scirc;": "\u015c", + "Scy;": "\u0421", + "Sfr;": "\U0001d516", + "ShortDownArrow;": "\u2193", + "ShortLeftArrow;": "\u2190", + "ShortRightArrow;": "\u2192", + "ShortUpArrow;": "\u2191", + "Sigma;": "\u03a3", + "SmallCircle;": "\u2218", + "Sopf;": "\U0001d54a", + "Sqrt;": "\u221a", + "Square;": "\u25a1", + "SquareIntersection;": "\u2293", + "SquareSubset;": "\u228f", + "SquareSubsetEqual;": "\u2291", + "SquareSuperset;": "\u2290", + "SquareSupersetEqual;": "\u2292", + "SquareUnion;": "\u2294", + "Sscr;": "\U0001d4ae", + "Star;": "\u22c6", + "Sub;": "\u22d0", + "Subset;": "\u22d0", + "SubsetEqual;": "\u2286", + "Succeeds;": "\u227b", + "SucceedsEqual;": "\u2ab0", + "SucceedsSlantEqual;": "\u227d", + "SucceedsTilde;": "\u227f", + "SuchThat;": "\u220b", + "Sum;": "\u2211", + "Sup;": "\u22d1", + "Superset;": "\u2283", + "SupersetEqual;": "\u2287", + "Supset;": "\u22d1", + "THORN": "\xde", + "THORN;": "\xde", + "TRADE;": "\u2122", + "TSHcy;": "\u040b", + "TScy;": "\u0426", + "Tab;": "\t", + "Tau;": "\u03a4", + "Tcaron;": "\u0164", + "Tcedil;": "\u0162", + "Tcy;": "\u0422", + "Tfr;": "\U0001d517", + "Therefore;": "\u2234", + "Theta;": "\u0398", + "ThickSpace;": "\u205f\u200a", + "ThinSpace;": "\u2009", + "Tilde;": "\u223c", + "TildeEqual;": "\u2243", + "TildeFullEqual;": "\u2245", + "TildeTilde;": "\u2248", + "Topf;": "\U0001d54b", + "TripleDot;": "\u20db", + "Tscr;": "\U0001d4af", + "Tstrok;": "\u0166", + "Uacute": "\xda", + "Uacute;": "\xda", + "Uarr;": "\u219f", + "Uarrocir;": "\u2949", + "Ubrcy;": "\u040e", + "Ubreve;": "\u016c", + "Ucirc": "\xdb", + "Ucirc;": "\xdb", + "Ucy;": "\u0423", + "Udblac;": "\u0170", + "Ufr;": "\U0001d518", + "Ugrave": "\xd9", + "Ugrave;": "\xd9", + "Umacr;": "\u016a", + "UnderBar;": "_", + "UnderBrace;": "\u23df", + "UnderBracket;": "\u23b5", + "UnderParenthesis;": "\u23dd", + "Union;": "\u22c3", + "UnionPlus;": "\u228e", + "Uogon;": "\u0172", + "Uopf;": "\U0001d54c", + "UpArrow;": "\u2191", + "UpArrowBar;": "\u2912", + "UpArrowDownArrow;": "\u21c5", + "UpDownArrow;": "\u2195", + "UpEquilibrium;": "\u296e", + "UpTee;": "\u22a5", + "UpTeeArrow;": "\u21a5", + "Uparrow;": "\u21d1", + "Updownarrow;": "\u21d5", + "UpperLeftArrow;": "\u2196", + "UpperRightArrow;": "\u2197", + "Upsi;": "\u03d2", + "Upsilon;": "\u03a5", + "Uring;": "\u016e", + "Uscr;": "\U0001d4b0", + "Utilde;": "\u0168", + "Uuml": "\xdc", + "Uuml;": "\xdc", + "VDash;": "\u22ab", + "Vbar;": "\u2aeb", + "Vcy;": "\u0412", + "Vdash;": "\u22a9", + "Vdashl;": "\u2ae6", + "Vee;": "\u22c1", + "Verbar;": "\u2016", + "Vert;": "\u2016", + "VerticalBar;": "\u2223", + "VerticalLine;": "|", + "VerticalSeparator;": "\u2758", + "VerticalTilde;": "\u2240", + "VeryThinSpace;": "\u200a", + "Vfr;": "\U0001d519", + "Vopf;": "\U0001d54d", + "Vscr;": "\U0001d4b1", + "Vvdash;": "\u22aa", + "Wcirc;": "\u0174", + "Wedge;": "\u22c0", + "Wfr;": "\U0001d51a", + "Wopf;": "\U0001d54e", + "Wscr;": "\U0001d4b2", + "Xfr;": "\U0001d51b", + "Xi;": "\u039e", + "Xopf;": "\U0001d54f", + "Xscr;": "\U0001d4b3", + "YAcy;": "\u042f", + "YIcy;": "\u0407", + "YUcy;": "\u042e", + "Yacute": "\xdd", + "Yacute;": "\xdd", + "Ycirc;": "\u0176", + "Ycy;": "\u042b", + "Yfr;": "\U0001d51c", + "Yopf;": "\U0001d550", + "Yscr;": "\U0001d4b4", + "Yuml;": "\u0178", + "ZHcy;": "\u0416", + "Zacute;": "\u0179", + "Zcaron;": "\u017d", + "Zcy;": "\u0417", + "Zdot;": "\u017b", + "ZeroWidthSpace;": "\u200b", + "Zeta;": "\u0396", + "Zfr;": "\u2128", + "Zopf;": "\u2124", + "Zscr;": "\U0001d4b5", + "aacute": "\xe1", + "aacute;": "\xe1", + "abreve;": "\u0103", + "ac;": "\u223e", + "acE;": "\u223e\u0333", + "acd;": "\u223f", + "acirc": "\xe2", + "acirc;": "\xe2", + "acute": "\xb4", + "acute;": "\xb4", + "acy;": "\u0430", + "aelig": "\xe6", + "aelig;": "\xe6", + "af;": "\u2061", + "afr;": "\U0001d51e", + "agrave": "\xe0", + "agrave;": "\xe0", + "alefsym;": "\u2135", + "aleph;": "\u2135", + "alpha;": "\u03b1", + "amacr;": "\u0101", + "amalg;": "\u2a3f", + "amp": "&", + "amp;": "&", + "and;": "\u2227", + "andand;": "\u2a55", + "andd;": "\u2a5c", + "andslope;": "\u2a58", + "andv;": "\u2a5a", + "ang;": "\u2220", + "ange;": "\u29a4", + "angle;": "\u2220", + "angmsd;": "\u2221", + "angmsdaa;": "\u29a8", + "angmsdab;": "\u29a9", + "angmsdac;": "\u29aa", + "angmsdad;": "\u29ab", + "angmsdae;": "\u29ac", + "angmsdaf;": "\u29ad", + "angmsdag;": "\u29ae", + "angmsdah;": "\u29af", + "angrt;": "\u221f", + "angrtvb;": "\u22be", + "angrtvbd;": "\u299d", + "angsph;": "\u2222", + "angst;": "\xc5", + "angzarr;": "\u237c", + "aogon;": "\u0105", + "aopf;": "\U0001d552", + "ap;": "\u2248", + "apE;": "\u2a70", + "apacir;": "\u2a6f", + "ape;": "\u224a", + "apid;": "\u224b", + "apos;": "'", + "approx;": "\u2248", + "approxeq;": "\u224a", + "aring": "\xe5", + "aring;": "\xe5", + "ascr;": "\U0001d4b6", + "ast;": "*", + "asymp;": "\u2248", + "asympeq;": "\u224d", + "atilde": "\xe3", + "atilde;": "\xe3", + "auml": "\xe4", + "auml;": "\xe4", + "awconint;": "\u2233", + "awint;": "\u2a11", + "bNot;": "\u2aed", + "backcong;": "\u224c", + "backepsilon;": "\u03f6", + "backprime;": "\u2035", + "backsim;": "\u223d", + "backsimeq;": "\u22cd", + "barvee;": "\u22bd", + "barwed;": "\u2305", + "barwedge;": "\u2305", + "bbrk;": "\u23b5", + "bbrktbrk;": "\u23b6", + "bcong;": "\u224c", + "bcy;": "\u0431", + "bdquo;": "\u201e", + "becaus;": "\u2235", + "because;": "\u2235", + "bemptyv;": "\u29b0", + "bepsi;": "\u03f6", + "bernou;": "\u212c", + "beta;": "\u03b2", + "beth;": "\u2136", + "between;": "\u226c", + "bfr;": "\U0001d51f", + "bigcap;": "\u22c2", + "bigcirc;": "\u25ef", + "bigcup;": "\u22c3", + "bigodot;": "\u2a00", + "bigoplus;": "\u2a01", + "bigotimes;": "\u2a02", + "bigsqcup;": "\u2a06", + "bigstar;": "\u2605", + "bigtriangledown;": "\u25bd", + "bigtriangleup;": "\u25b3", + "biguplus;": "\u2a04", + "bigvee;": "\u22c1", + "bigwedge;": "\u22c0", + "bkarow;": "\u290d", + "blacklozenge;": "\u29eb", + "blacksquare;": "\u25aa", + "blacktriangle;": "\u25b4", + "blacktriangledown;": "\u25be", + "blacktriangleleft;": "\u25c2", + "blacktriangleright;": "\u25b8", + "blank;": "\u2423", + "blk12;": "\u2592", + "blk14;": "\u2591", + "blk34;": "\u2593", + "block;": "\u2588", + "bne;": "=\u20e5", + "bnequiv;": "\u2261\u20e5", + "bnot;": "\u2310", + "bopf;": "\U0001d553", + "bot;": "\u22a5", + "bottom;": "\u22a5", + "bowtie;": "\u22c8", + "boxDL;": "\u2557", + "boxDR;": "\u2554", + "boxDl;": "\u2556", + "boxDr;": "\u2553", + "boxH;": "\u2550", + "boxHD;": "\u2566", + "boxHU;": "\u2569", + "boxHd;": "\u2564", + "boxHu;": "\u2567", + "boxUL;": "\u255d", + "boxUR;": "\u255a", + "boxUl;": "\u255c", + "boxUr;": "\u2559", + "boxV;": "\u2551", + "boxVH;": "\u256c", + "boxVL;": "\u2563", + "boxVR;": "\u2560", + "boxVh;": "\u256b", + "boxVl;": "\u2562", + "boxVr;": "\u255f", + "boxbox;": "\u29c9", + "boxdL;": "\u2555", + "boxdR;": "\u2552", + "boxdl;": "\u2510", + "boxdr;": "\u250c", + "boxh;": "\u2500", + "boxhD;": "\u2565", + "boxhU;": "\u2568", + "boxhd;": "\u252c", + "boxhu;": "\u2534", + "boxminus;": "\u229f", + "boxplus;": "\u229e", + "boxtimes;": "\u22a0", + "boxuL;": "\u255b", + "boxuR;": "\u2558", + "boxul;": "\u2518", + "boxur;": "\u2514", + "boxv;": "\u2502", + "boxvH;": "\u256a", + "boxvL;": "\u2561", + "boxvR;": "\u255e", + "boxvh;": "\u253c", + "boxvl;": "\u2524", + "boxvr;": "\u251c", + "bprime;": "\u2035", + "breve;": "\u02d8", + "brvbar": "\xa6", + "brvbar;": "\xa6", + "bscr;": "\U0001d4b7", + "bsemi;": "\u204f", + "bsim;": "\u223d", + "bsime;": "\u22cd", + "bsol;": "\\", + "bsolb;": "\u29c5", + "bsolhsub;": "\u27c8", + "bull;": "\u2022", + "bullet;": "\u2022", + "bump;": "\u224e", + "bumpE;": "\u2aae", + "bumpe;": "\u224f", + "bumpeq;": "\u224f", + "cacute;": "\u0107", + "cap;": "\u2229", + "capand;": "\u2a44", + "capbrcup;": "\u2a49", + "capcap;": "\u2a4b", + "capcup;": "\u2a47", + "capdot;": "\u2a40", + "caps;": "\u2229\ufe00", + "caret;": "\u2041", + "caron;": "\u02c7", + "ccaps;": "\u2a4d", + "ccaron;": "\u010d", + "ccedil": "\xe7", + "ccedil;": "\xe7", + "ccirc;": "\u0109", + "ccups;": "\u2a4c", + "ccupssm;": "\u2a50", + "cdot;": "\u010b", + "cedil": "\xb8", + "cedil;": "\xb8", + "cemptyv;": "\u29b2", + "cent": "\xa2", + "cent;": "\xa2", + "centerdot;": "\xb7", + "cfr;": "\U0001d520", + "chcy;": "\u0447", + "check;": "\u2713", + "checkmark;": "\u2713", + "chi;": "\u03c7", + "cir;": "\u25cb", + "cirE;": "\u29c3", + "circ;": "\u02c6", + "circeq;": "\u2257", + "circlearrowleft;": "\u21ba", + "circlearrowright;": "\u21bb", + "circledR;": "\xae", + "circledS;": "\u24c8", + "circledast;": "\u229b", + "circledcirc;": "\u229a", + "circleddash;": "\u229d", + "cire;": "\u2257", + "cirfnint;": "\u2a10", + "cirmid;": "\u2aef", + "cirscir;": "\u29c2", + "clubs;": "\u2663", + "clubsuit;": "\u2663", + "colon;": ":", + "colone;": "\u2254", + "coloneq;": "\u2254", + "comma;": ",", + "commat;": "@", + "comp;": "\u2201", + "compfn;": "\u2218", + "complement;": "\u2201", + "complexes;": "\u2102", + "cong;": "\u2245", + "congdot;": "\u2a6d", + "conint;": "\u222e", + "copf;": "\U0001d554", + "coprod;": "\u2210", + "copy": "\xa9", + "copy;": "\xa9", + "copysr;": "\u2117", + "crarr;": "\u21b5", + "cross;": "\u2717", + "cscr;": "\U0001d4b8", + "csub;": "\u2acf", + "csube;": "\u2ad1", + "csup;": "\u2ad0", + "csupe;": "\u2ad2", + "ctdot;": "\u22ef", + "cudarrl;": "\u2938", + "cudarrr;": "\u2935", + "cuepr;": "\u22de", + "cuesc;": "\u22df", + "cularr;": "\u21b6", + "cularrp;": "\u293d", + "cup;": "\u222a", + "cupbrcap;": "\u2a48", + "cupcap;": "\u2a46", + "cupcup;": "\u2a4a", + "cupdot;": "\u228d", + "cupor;": "\u2a45", + "cups;": "\u222a\ufe00", + "curarr;": "\u21b7", + "curarrm;": "\u293c", + "curlyeqprec;": "\u22de", + "curlyeqsucc;": "\u22df", + "curlyvee;": "\u22ce", + "curlywedge;": "\u22cf", + "curren": "\xa4", + "curren;": "\xa4", + "curvearrowleft;": "\u21b6", + "curvearrowright;": "\u21b7", + "cuvee;": "\u22ce", + "cuwed;": "\u22cf", + "cwconint;": "\u2232", + "cwint;": "\u2231", + "cylcty;": "\u232d", + "dArr;": "\u21d3", + "dHar;": "\u2965", + "dagger;": "\u2020", + "daleth;": "\u2138", + "darr;": "\u2193", + "dash;": "\u2010", + "dashv;": "\u22a3", + "dbkarow;": "\u290f", + "dblac;": "\u02dd", + "dcaron;": "\u010f", + "dcy;": "\u0434", + "dd;": "\u2146", + "ddagger;": "\u2021", + "ddarr;": "\u21ca", + "ddotseq;": "\u2a77", + "deg": "\xb0", + "deg;": "\xb0", + "delta;": "\u03b4", + "demptyv;": "\u29b1", + "dfisht;": "\u297f", + "dfr;": "\U0001d521", + "dharl;": "\u21c3", + "dharr;": "\u21c2", + "diam;": "\u22c4", + "diamond;": "\u22c4", + "diamondsuit;": "\u2666", + "diams;": "\u2666", + "die;": "\xa8", + "digamma;": "\u03dd", + "disin;": "\u22f2", + "div;": "\xf7", + "divide": "\xf7", + "divide;": "\xf7", + "divideontimes;": "\u22c7", + "divonx;": "\u22c7", + "djcy;": "\u0452", + "dlcorn;": "\u231e", + "dlcrop;": "\u230d", + "dollar;": "$", + "dopf;": "\U0001d555", + "dot;": "\u02d9", + "doteq;": "\u2250", + "doteqdot;": "\u2251", + "dotminus;": "\u2238", + "dotplus;": "\u2214", + "dotsquare;": "\u22a1", + "doublebarwedge;": "\u2306", + "downarrow;": "\u2193", + "downdownarrows;": "\u21ca", + "downharpoonleft;": "\u21c3", + "downharpoonright;": "\u21c2", + "drbkarow;": "\u2910", + "drcorn;": "\u231f", + "drcrop;": "\u230c", + "dscr;": "\U0001d4b9", + "dscy;": "\u0455", + "dsol;": "\u29f6", + "dstrok;": "\u0111", + "dtdot;": "\u22f1", + "dtri;": "\u25bf", + "dtrif;": "\u25be", + "duarr;": "\u21f5", + "duhar;": "\u296f", + "dwangle;": "\u29a6", + "dzcy;": "\u045f", + "dzigrarr;": "\u27ff", + "eDDot;": "\u2a77", + "eDot;": "\u2251", + "eacute": "\xe9", + "eacute;": "\xe9", + "easter;": "\u2a6e", + "ecaron;": "\u011b", + "ecir;": "\u2256", + "ecirc": "\xea", + "ecirc;": "\xea", + "ecolon;": "\u2255", + "ecy;": "\u044d", + "edot;": "\u0117", + "ee;": "\u2147", + "efDot;": "\u2252", + "efr;": "\U0001d522", + "eg;": "\u2a9a", + "egrave": "\xe8", + "egrave;": "\xe8", + "egs;": "\u2a96", + "egsdot;": "\u2a98", + "el;": "\u2a99", + "elinters;": "\u23e7", + "ell;": "\u2113", + "els;": "\u2a95", + "elsdot;": "\u2a97", + "emacr;": "\u0113", + "empty;": "\u2205", + "emptyset;": "\u2205", + "emptyv;": "\u2205", + "emsp13;": "\u2004", + "emsp14;": "\u2005", + "emsp;": "\u2003", + "eng;": "\u014b", + "ensp;": "\u2002", + "eogon;": "\u0119", + "eopf;": "\U0001d556", + "epar;": "\u22d5", + "eparsl;": "\u29e3", + "eplus;": "\u2a71", + "epsi;": "\u03b5", + "epsilon;": "\u03b5", + "epsiv;": "\u03f5", + "eqcirc;": "\u2256", + "eqcolon;": "\u2255", + "eqsim;": "\u2242", + "eqslantgtr;": "\u2a96", + "eqslantless;": "\u2a95", + "equals;": "=", + "equest;": "\u225f", + "equiv;": "\u2261", + "equivDD;": "\u2a78", + "eqvparsl;": "\u29e5", + "erDot;": "\u2253", + "erarr;": "\u2971", + "escr;": "\u212f", + "esdot;": "\u2250", + "esim;": "\u2242", + "eta;": "\u03b7", + "eth": "\xf0", + "eth;": "\xf0", + "euml": "\xeb", + "euml;": "\xeb", + "euro;": "\u20ac", + "excl;": "!", + "exist;": "\u2203", + "expectation;": "\u2130", + "exponentiale;": "\u2147", + "fallingdotseq;": "\u2252", + "fcy;": "\u0444", + "female;": "\u2640", + "ffilig;": "\ufb03", + "fflig;": "\ufb00", + "ffllig;": "\ufb04", + "ffr;": "\U0001d523", + "filig;": "\ufb01", + "fjlig;": "fj", + "flat;": "\u266d", + "fllig;": "\ufb02", + "fltns;": "\u25b1", + "fnof;": "\u0192", + "fopf;": "\U0001d557", + "forall;": "\u2200", + "fork;": "\u22d4", + "forkv;": "\u2ad9", + "fpartint;": "\u2a0d", + "frac12": "\xbd", + "frac12;": "\xbd", + "frac13;": "\u2153", + "frac14": "\xbc", + "frac14;": "\xbc", + "frac15;": "\u2155", + "frac16;": "\u2159", + "frac18;": "\u215b", + "frac23;": "\u2154", + "frac25;": "\u2156", + "frac34": "\xbe", + "frac34;": "\xbe", + "frac35;": "\u2157", + "frac38;": "\u215c", + "frac45;": "\u2158", + "frac56;": "\u215a", + "frac58;": "\u215d", + "frac78;": "\u215e", + "frasl;": "\u2044", + "frown;": "\u2322", + "fscr;": "\U0001d4bb", + "gE;": "\u2267", + "gEl;": "\u2a8c", + "gacute;": "\u01f5", + "gamma;": "\u03b3", + "gammad;": "\u03dd", + "gap;": "\u2a86", + "gbreve;": "\u011f", + "gcirc;": "\u011d", + "gcy;": "\u0433", + "gdot;": "\u0121", + "ge;": "\u2265", + "gel;": "\u22db", + "geq;": "\u2265", + "geqq;": "\u2267", + "geqslant;": "\u2a7e", + "ges;": "\u2a7e", + "gescc;": "\u2aa9", + "gesdot;": "\u2a80", + "gesdoto;": "\u2a82", + "gesdotol;": "\u2a84", + "gesl;": "\u22db\ufe00", + "gesles;": "\u2a94", + "gfr;": "\U0001d524", + "gg;": "\u226b", + "ggg;": "\u22d9", + "gimel;": "\u2137", + "gjcy;": "\u0453", + "gl;": "\u2277", + "glE;": "\u2a92", + "gla;": "\u2aa5", + "glj;": "\u2aa4", + "gnE;": "\u2269", + "gnap;": "\u2a8a", + "gnapprox;": "\u2a8a", + "gne;": "\u2a88", + "gneq;": "\u2a88", + "gneqq;": "\u2269", + "gnsim;": "\u22e7", + "gopf;": "\U0001d558", + "grave;": "`", + "gscr;": "\u210a", + "gsim;": "\u2273", + "gsime;": "\u2a8e", + "gsiml;": "\u2a90", + "gt": ">", + "gt;": ">", + "gtcc;": "\u2aa7", + "gtcir;": "\u2a7a", + "gtdot;": "\u22d7", + "gtlPar;": "\u2995", + "gtquest;": "\u2a7c", + "gtrapprox;": "\u2a86", + "gtrarr;": "\u2978", + "gtrdot;": "\u22d7", + "gtreqless;": "\u22db", + "gtreqqless;": "\u2a8c", + "gtrless;": "\u2277", + "gtrsim;": "\u2273", + "gvertneqq;": "\u2269\ufe00", + "gvnE;": "\u2269\ufe00", + "hArr;": "\u21d4", + "hairsp;": "\u200a", + "half;": "\xbd", + "hamilt;": "\u210b", + "hardcy;": "\u044a", + "harr;": "\u2194", + "harrcir;": "\u2948", + "harrw;": "\u21ad", + "hbar;": "\u210f", + "hcirc;": "\u0125", + "hearts;": "\u2665", + "heartsuit;": "\u2665", + "hellip;": "\u2026", + "hercon;": "\u22b9", + "hfr;": "\U0001d525", + "hksearow;": "\u2925", + "hkswarow;": "\u2926", + "hoarr;": "\u21ff", + "homtht;": "\u223b", + "hookleftarrow;": "\u21a9", + "hookrightarrow;": "\u21aa", + "hopf;": "\U0001d559", + "horbar;": "\u2015", + "hscr;": "\U0001d4bd", + "hslash;": "\u210f", + "hstrok;": "\u0127", + "hybull;": "\u2043", + "hyphen;": "\u2010", + "iacute": "\xed", + "iacute;": "\xed", + "ic;": "\u2063", + "icirc": "\xee", + "icirc;": "\xee", + "icy;": "\u0438", + "iecy;": "\u0435", + "iexcl": "\xa1", + "iexcl;": "\xa1", + "iff;": "\u21d4", + "ifr;": "\U0001d526", + "igrave": "\xec", + "igrave;": "\xec", + "ii;": "\u2148", + "iiiint;": "\u2a0c", + "iiint;": "\u222d", + "iinfin;": "\u29dc", + "iiota;": "\u2129", + "ijlig;": "\u0133", + "imacr;": "\u012b", + "image;": "\u2111", + "imagline;": "\u2110", + "imagpart;": "\u2111", + "imath;": "\u0131", + "imof;": "\u22b7", + "imped;": "\u01b5", + "in;": "\u2208", + "incare;": "\u2105", + "infin;": "\u221e", + "infintie;": "\u29dd", + "inodot;": "\u0131", + "int;": "\u222b", + "intcal;": "\u22ba", + "integers;": "\u2124", + "intercal;": "\u22ba", + "intlarhk;": "\u2a17", + "intprod;": "\u2a3c", + "iocy;": "\u0451", + "iogon;": "\u012f", + "iopf;": "\U0001d55a", + "iota;": "\u03b9", + "iprod;": "\u2a3c", + "iquest": "\xbf", + "iquest;": "\xbf", + "iscr;": "\U0001d4be", + "isin;": "\u2208", + "isinE;": "\u22f9", + "isindot;": "\u22f5", + "isins;": "\u22f4", + "isinsv;": "\u22f3", + "isinv;": "\u2208", + "it;": "\u2062", + "itilde;": "\u0129", + "iukcy;": "\u0456", + "iuml": "\xef", + "iuml;": "\xef", + "jcirc;": "\u0135", + "jcy;": "\u0439", + "jfr;": "\U0001d527", + "jmath;": "\u0237", + "jopf;": "\U0001d55b", + "jscr;": "\U0001d4bf", + "jsercy;": "\u0458", + "jukcy;": "\u0454", + "kappa;": "\u03ba", + "kappav;": "\u03f0", + "kcedil;": "\u0137", + "kcy;": "\u043a", + "kfr;": "\U0001d528", + "kgreen;": "\u0138", + "khcy;": "\u0445", + "kjcy;": "\u045c", + "kopf;": "\U0001d55c", + "kscr;": "\U0001d4c0", + "lAarr;": "\u21da", + "lArr;": "\u21d0", + "lAtail;": "\u291b", + "lBarr;": "\u290e", + "lE;": "\u2266", + "lEg;": "\u2a8b", + "lHar;": "\u2962", + "lacute;": "\u013a", + "laemptyv;": "\u29b4", + "lagran;": "\u2112", + "lambda;": "\u03bb", + "lang;": "\u27e8", + "langd;": "\u2991", + "langle;": "\u27e8", + "lap;": "\u2a85", + "laquo": "\xab", + "laquo;": "\xab", + "larr;": "\u2190", + "larrb;": "\u21e4", + "larrbfs;": "\u291f", + "larrfs;": "\u291d", + "larrhk;": "\u21a9", + "larrlp;": "\u21ab", + "larrpl;": "\u2939", + "larrsim;": "\u2973", + "larrtl;": "\u21a2", + "lat;": "\u2aab", + "latail;": "\u2919", + "late;": "\u2aad", + "lates;": "\u2aad\ufe00", + "lbarr;": "\u290c", + "lbbrk;": "\u2772", + "lbrace;": "{", + "lbrack;": "[", + "lbrke;": "\u298b", + "lbrksld;": "\u298f", + "lbrkslu;": "\u298d", + "lcaron;": "\u013e", + "lcedil;": "\u013c", + "lceil;": "\u2308", + "lcub;": "{", + "lcy;": "\u043b", + "ldca;": "\u2936", + "ldquo;": "\u201c", + "ldquor;": "\u201e", + "ldrdhar;": "\u2967", + "ldrushar;": "\u294b", + "ldsh;": "\u21b2", + "le;": "\u2264", + "leftarrow;": "\u2190", + "leftarrowtail;": "\u21a2", + "leftharpoondown;": "\u21bd", + "leftharpoonup;": "\u21bc", + "leftleftarrows;": "\u21c7", + "leftrightarrow;": "\u2194", + "leftrightarrows;": "\u21c6", + "leftrightharpoons;": "\u21cb", + "leftrightsquigarrow;": "\u21ad", + "leftthreetimes;": "\u22cb", + "leg;": "\u22da", + "leq;": "\u2264", + "leqq;": "\u2266", + "leqslant;": "\u2a7d", + "les;": "\u2a7d", + "lescc;": "\u2aa8", + "lesdot;": "\u2a7f", + "lesdoto;": "\u2a81", + "lesdotor;": "\u2a83", + "lesg;": "\u22da\ufe00", + "lesges;": "\u2a93", + "lessapprox;": "\u2a85", + "lessdot;": "\u22d6", + "lesseqgtr;": "\u22da", + "lesseqqgtr;": "\u2a8b", + "lessgtr;": "\u2276", + "lesssim;": "\u2272", + "lfisht;": "\u297c", + "lfloor;": "\u230a", + "lfr;": "\U0001d529", + "lg;": "\u2276", + "lgE;": "\u2a91", + "lhard;": "\u21bd", + "lharu;": "\u21bc", + "lharul;": "\u296a", + "lhblk;": "\u2584", + "ljcy;": "\u0459", + "ll;": "\u226a", + "llarr;": "\u21c7", + "llcorner;": "\u231e", + "llhard;": "\u296b", + "lltri;": "\u25fa", + "lmidot;": "\u0140", + "lmoust;": "\u23b0", + "lmoustache;": "\u23b0", + "lnE;": "\u2268", + "lnap;": "\u2a89", + "lnapprox;": "\u2a89", + "lne;": "\u2a87", + "lneq;": "\u2a87", + "lneqq;": "\u2268", + "lnsim;": "\u22e6", + "loang;": "\u27ec", + "loarr;": "\u21fd", + "lobrk;": "\u27e6", + "longleftarrow;": "\u27f5", + "longleftrightarrow;": "\u27f7", + "longmapsto;": "\u27fc", + "longrightarrow;": "\u27f6", + "looparrowleft;": "\u21ab", + "looparrowright;": "\u21ac", + "lopar;": "\u2985", + "lopf;": "\U0001d55d", + "loplus;": "\u2a2d", + "lotimes;": "\u2a34", + "lowast;": "\u2217", + "lowbar;": "_", + "loz;": "\u25ca", + "lozenge;": "\u25ca", + "lozf;": "\u29eb", + "lpar;": "(", + "lparlt;": "\u2993", + "lrarr;": "\u21c6", + "lrcorner;": "\u231f", + "lrhar;": "\u21cb", + "lrhard;": "\u296d", + "lrm;": "\u200e", + "lrtri;": "\u22bf", + "lsaquo;": "\u2039", + "lscr;": "\U0001d4c1", + "lsh;": "\u21b0", + "lsim;": "\u2272", + "lsime;": "\u2a8d", + "lsimg;": "\u2a8f", + "lsqb;": "[", + "lsquo;": "\u2018", + "lsquor;": "\u201a", + "lstrok;": "\u0142", + "lt": "<", + "lt;": "<", + "ltcc;": "\u2aa6", + "ltcir;": "\u2a79", + "ltdot;": "\u22d6", + "lthree;": "\u22cb", + "ltimes;": "\u22c9", + "ltlarr;": "\u2976", + "ltquest;": "\u2a7b", + "ltrPar;": "\u2996", + "ltri;": "\u25c3", + "ltrie;": "\u22b4", + "ltrif;": "\u25c2", + "lurdshar;": "\u294a", + "luruhar;": "\u2966", + "lvertneqq;": "\u2268\ufe00", + "lvnE;": "\u2268\ufe00", + "mDDot;": "\u223a", + "macr": "\xaf", + "macr;": "\xaf", + "male;": "\u2642", + "malt;": "\u2720", + "maltese;": "\u2720", + "map;": "\u21a6", + "mapsto;": "\u21a6", + "mapstodown;": "\u21a7", + "mapstoleft;": "\u21a4", + "mapstoup;": "\u21a5", + "marker;": "\u25ae", + "mcomma;": "\u2a29", + "mcy;": "\u043c", + "mdash;": "\u2014", + "measuredangle;": "\u2221", + "mfr;": "\U0001d52a", + "mho;": "\u2127", + "micro": "\xb5", + "micro;": "\xb5", + "mid;": "\u2223", + "midast;": "*", + "midcir;": "\u2af0", + "middot": "\xb7", + "middot;": "\xb7", + "minus;": "\u2212", + "minusb;": "\u229f", + "minusd;": "\u2238", + "minusdu;": "\u2a2a", + "mlcp;": "\u2adb", + "mldr;": "\u2026", + "mnplus;": "\u2213", + "models;": "\u22a7", + "mopf;": "\U0001d55e", + "mp;": "\u2213", + "mscr;": "\U0001d4c2", + "mstpos;": "\u223e", + "mu;": "\u03bc", + "multimap;": "\u22b8", + "mumap;": "\u22b8", + "nGg;": "\u22d9\u0338", + "nGt;": "\u226b\u20d2", + "nGtv;": "\u226b\u0338", + "nLeftarrow;": "\u21cd", + "nLeftrightarrow;": "\u21ce", + "nLl;": "\u22d8\u0338", + "nLt;": "\u226a\u20d2", + "nLtv;": "\u226a\u0338", + "nRightarrow;": "\u21cf", + "nVDash;": "\u22af", + "nVdash;": "\u22ae", + "nabla;": "\u2207", + "nacute;": "\u0144", + "nang;": "\u2220\u20d2", + "nap;": "\u2249", + "napE;": "\u2a70\u0338", + "napid;": "\u224b\u0338", + "napos;": "\u0149", + "napprox;": "\u2249", + "natur;": "\u266e", + "natural;": "\u266e", + "naturals;": "\u2115", + "nbsp": "\xa0", + "nbsp;": "\xa0", + "nbump;": "\u224e\u0338", + "nbumpe;": "\u224f\u0338", + "ncap;": "\u2a43", + "ncaron;": "\u0148", + "ncedil;": "\u0146", + "ncong;": "\u2247", + "ncongdot;": "\u2a6d\u0338", + "ncup;": "\u2a42", + "ncy;": "\u043d", + "ndash;": "\u2013", + "ne;": "\u2260", + "neArr;": "\u21d7", + "nearhk;": "\u2924", + "nearr;": "\u2197", + "nearrow;": "\u2197", + "nedot;": "\u2250\u0338", + "nequiv;": "\u2262", + "nesear;": "\u2928", + "nesim;": "\u2242\u0338", + "nexist;": "\u2204", + "nexists;": "\u2204", + "nfr;": "\U0001d52b", + "ngE;": "\u2267\u0338", + "nge;": "\u2271", + "ngeq;": "\u2271", + "ngeqq;": "\u2267\u0338", + "ngeqslant;": "\u2a7e\u0338", + "nges;": "\u2a7e\u0338", + "ngsim;": "\u2275", + "ngt;": "\u226f", + "ngtr;": "\u226f", + "nhArr;": "\u21ce", + "nharr;": "\u21ae", + "nhpar;": "\u2af2", + "ni;": "\u220b", + "nis;": "\u22fc", + "nisd;": "\u22fa", + "niv;": "\u220b", + "njcy;": "\u045a", + "nlArr;": "\u21cd", + "nlE;": "\u2266\u0338", + "nlarr;": "\u219a", + "nldr;": "\u2025", + "nle;": "\u2270", + "nleftarrow;": "\u219a", + "nleftrightarrow;": "\u21ae", + "nleq;": "\u2270", + "nleqq;": "\u2266\u0338", + "nleqslant;": "\u2a7d\u0338", + "nles;": "\u2a7d\u0338", + "nless;": "\u226e", + "nlsim;": "\u2274", + "nlt;": "\u226e", + "nltri;": "\u22ea", + "nltrie;": "\u22ec", + "nmid;": "\u2224", + "nopf;": "\U0001d55f", + "not": "\xac", + "not;": "\xac", + "notin;": "\u2209", + "notinE;": "\u22f9\u0338", + "notindot;": "\u22f5\u0338", + "notinva;": "\u2209", + "notinvb;": "\u22f7", + "notinvc;": "\u22f6", + "notni;": "\u220c", + "notniva;": "\u220c", + "notnivb;": "\u22fe", + "notnivc;": "\u22fd", + "npar;": "\u2226", + "nparallel;": "\u2226", + "nparsl;": "\u2afd\u20e5", + "npart;": "\u2202\u0338", + "npolint;": "\u2a14", + "npr;": "\u2280", + "nprcue;": "\u22e0", + "npre;": "\u2aaf\u0338", + "nprec;": "\u2280", + "npreceq;": "\u2aaf\u0338", + "nrArr;": "\u21cf", + "nrarr;": "\u219b", + "nrarrc;": "\u2933\u0338", + "nrarrw;": "\u219d\u0338", + "nrightarrow;": "\u219b", + "nrtri;": "\u22eb", + "nrtrie;": "\u22ed", + "nsc;": "\u2281", + "nsccue;": "\u22e1", + "nsce;": "\u2ab0\u0338", + "nscr;": "\U0001d4c3", + "nshortmid;": "\u2224", + "nshortparallel;": "\u2226", + "nsim;": "\u2241", + "nsime;": "\u2244", + "nsimeq;": "\u2244", + "nsmid;": "\u2224", + "nspar;": "\u2226", + "nsqsube;": "\u22e2", + "nsqsupe;": "\u22e3", + "nsub;": "\u2284", + "nsubE;": "\u2ac5\u0338", + "nsube;": "\u2288", + "nsubset;": "\u2282\u20d2", + "nsubseteq;": "\u2288", + "nsubseteqq;": "\u2ac5\u0338", + "nsucc;": "\u2281", + "nsucceq;": "\u2ab0\u0338", + "nsup;": "\u2285", + "nsupE;": "\u2ac6\u0338", + "nsupe;": "\u2289", + "nsupset;": "\u2283\u20d2", + "nsupseteq;": "\u2289", + "nsupseteqq;": "\u2ac6\u0338", + "ntgl;": "\u2279", + "ntilde": "\xf1", + "ntilde;": "\xf1", + "ntlg;": "\u2278", + "ntriangleleft;": "\u22ea", + "ntrianglelefteq;": "\u22ec", + "ntriangleright;": "\u22eb", + "ntrianglerighteq;": "\u22ed", + "nu;": "\u03bd", + "num;": "#", + "numero;": "\u2116", + "numsp;": "\u2007", + "nvDash;": "\u22ad", + "nvHarr;": "\u2904", + "nvap;": "\u224d\u20d2", + "nvdash;": "\u22ac", + "nvge;": "\u2265\u20d2", + "nvgt;": ">\u20d2", + "nvinfin;": "\u29de", + "nvlArr;": "\u2902", + "nvle;": "\u2264\u20d2", + "nvlt;": "<\u20d2", + "nvltrie;": "\u22b4\u20d2", + "nvrArr;": "\u2903", + "nvrtrie;": "\u22b5\u20d2", + "nvsim;": "\u223c\u20d2", + "nwArr;": "\u21d6", + "nwarhk;": "\u2923", + "nwarr;": "\u2196", + "nwarrow;": "\u2196", + "nwnear;": "\u2927", + "oS;": "\u24c8", + "oacute": "\xf3", + "oacute;": "\xf3", + "oast;": "\u229b", + "ocir;": "\u229a", + "ocirc": "\xf4", + "ocirc;": "\xf4", + "ocy;": "\u043e", + "odash;": "\u229d", + "odblac;": "\u0151", + "odiv;": "\u2a38", + "odot;": "\u2299", + "odsold;": "\u29bc", + "oelig;": "\u0153", + "ofcir;": "\u29bf", + "ofr;": "\U0001d52c", + "ogon;": "\u02db", + "ograve": "\xf2", + "ograve;": "\xf2", + "ogt;": "\u29c1", + "ohbar;": "\u29b5", + "ohm;": "\u03a9", + "oint;": "\u222e", + "olarr;": "\u21ba", + "olcir;": "\u29be", + "olcross;": "\u29bb", + "oline;": "\u203e", + "olt;": "\u29c0", + "omacr;": "\u014d", + "omega;": "\u03c9", + "omicron;": "\u03bf", + "omid;": "\u29b6", + "ominus;": "\u2296", + "oopf;": "\U0001d560", + "opar;": "\u29b7", + "operp;": "\u29b9", + "oplus;": "\u2295", + "or;": "\u2228", + "orarr;": "\u21bb", + "ord;": "\u2a5d", + "order;": "\u2134", + "orderof;": "\u2134", + "ordf": "\xaa", + "ordf;": "\xaa", + "ordm": "\xba", + "ordm;": "\xba", + "origof;": "\u22b6", + "oror;": "\u2a56", + "orslope;": "\u2a57", + "orv;": "\u2a5b", + "oscr;": "\u2134", + "oslash": "\xf8", + "oslash;": "\xf8", + "osol;": "\u2298", + "otilde": "\xf5", + "otilde;": "\xf5", + "otimes;": "\u2297", + "otimesas;": "\u2a36", + "ouml": "\xf6", + "ouml;": "\xf6", + "ovbar;": "\u233d", + "par;": "\u2225", + "para": "\xb6", + "para;": "\xb6", + "parallel;": "\u2225", + "parsim;": "\u2af3", + "parsl;": "\u2afd", + "part;": "\u2202", + "pcy;": "\u043f", + "percnt;": "%", + "period;": ".", + "permil;": "\u2030", + "perp;": "\u22a5", + "pertenk;": "\u2031", + "pfr;": "\U0001d52d", + "phi;": "\u03c6", + "phiv;": "\u03d5", + "phmmat;": "\u2133", + "phone;": "\u260e", + "pi;": "\u03c0", + "pitchfork;": "\u22d4", + "piv;": "\u03d6", + "planck;": "\u210f", + "planckh;": "\u210e", + "plankv;": "\u210f", + "plus;": "+", + "plusacir;": "\u2a23", + "plusb;": "\u229e", + "pluscir;": "\u2a22", + "plusdo;": "\u2214", + "plusdu;": "\u2a25", + "pluse;": "\u2a72", + "plusmn": "\xb1", + "plusmn;": "\xb1", + "plussim;": "\u2a26", + "plustwo;": "\u2a27", + "pm;": "\xb1", + "pointint;": "\u2a15", + "popf;": "\U0001d561", + "pound": "\xa3", + "pound;": "\xa3", + "pr;": "\u227a", + "prE;": "\u2ab3", + "prap;": "\u2ab7", + "prcue;": "\u227c", + "pre;": "\u2aaf", + "prec;": "\u227a", + "precapprox;": "\u2ab7", + "preccurlyeq;": "\u227c", + "preceq;": "\u2aaf", + "precnapprox;": "\u2ab9", + "precneqq;": "\u2ab5", + "precnsim;": "\u22e8", + "precsim;": "\u227e", + "prime;": "\u2032", + "primes;": "\u2119", + "prnE;": "\u2ab5", + "prnap;": "\u2ab9", + "prnsim;": "\u22e8", + "prod;": "\u220f", + "profalar;": "\u232e", + "profline;": "\u2312", + "profsurf;": "\u2313", + "prop;": "\u221d", + "propto;": "\u221d", + "prsim;": "\u227e", + "prurel;": "\u22b0", + "pscr;": "\U0001d4c5", + "psi;": "\u03c8", + "puncsp;": "\u2008", + "qfr;": "\U0001d52e", + "qint;": "\u2a0c", + "qopf;": "\U0001d562", + "qprime;": "\u2057", + "qscr;": "\U0001d4c6", + "quaternions;": "\u210d", + "quatint;": "\u2a16", + "quest;": "?", + "questeq;": "\u225f", + "quot": "\"", + "quot;": "\"", + "rAarr;": "\u21db", + "rArr;": "\u21d2", + "rAtail;": "\u291c", + "rBarr;": "\u290f", + "rHar;": "\u2964", + "race;": "\u223d\u0331", + "racute;": "\u0155", + "radic;": "\u221a", + "raemptyv;": "\u29b3", + "rang;": "\u27e9", + "rangd;": "\u2992", + "range;": "\u29a5", + "rangle;": "\u27e9", + "raquo": "\xbb", + "raquo;": "\xbb", + "rarr;": "\u2192", + "rarrap;": "\u2975", + "rarrb;": "\u21e5", + "rarrbfs;": "\u2920", + "rarrc;": "\u2933", + "rarrfs;": "\u291e", + "rarrhk;": "\u21aa", + "rarrlp;": "\u21ac", + "rarrpl;": "\u2945", + "rarrsim;": "\u2974", + "rarrtl;": "\u21a3", + "rarrw;": "\u219d", + "ratail;": "\u291a", + "ratio;": "\u2236", + "rationals;": "\u211a", + "rbarr;": "\u290d", + "rbbrk;": "\u2773", + "rbrace;": "}", + "rbrack;": "]", + "rbrke;": "\u298c", + "rbrksld;": "\u298e", + "rbrkslu;": "\u2990", + "rcaron;": "\u0159", + "rcedil;": "\u0157", + "rceil;": "\u2309", + "rcub;": "}", + "rcy;": "\u0440", + "rdca;": "\u2937", + "rdldhar;": "\u2969", + "rdquo;": "\u201d", + "rdquor;": "\u201d", + "rdsh;": "\u21b3", + "real;": "\u211c", + "realine;": "\u211b", + "realpart;": "\u211c", + "reals;": "\u211d", + "rect;": "\u25ad", + "reg": "\xae", + "reg;": "\xae", + "rfisht;": "\u297d", + "rfloor;": "\u230b", + "rfr;": "\U0001d52f", + "rhard;": "\u21c1", + "rharu;": "\u21c0", + "rharul;": "\u296c", + "rho;": "\u03c1", + "rhov;": "\u03f1", + "rightarrow;": "\u2192", + "rightarrowtail;": "\u21a3", + "rightharpoondown;": "\u21c1", + "rightharpoonup;": "\u21c0", + "rightleftarrows;": "\u21c4", + "rightleftharpoons;": "\u21cc", + "rightrightarrows;": "\u21c9", + "rightsquigarrow;": "\u219d", + "rightthreetimes;": "\u22cc", + "ring;": "\u02da", + "risingdotseq;": "\u2253", + "rlarr;": "\u21c4", + "rlhar;": "\u21cc", + "rlm;": "\u200f", + "rmoust;": "\u23b1", + "rmoustache;": "\u23b1", + "rnmid;": "\u2aee", + "roang;": "\u27ed", + "roarr;": "\u21fe", + "robrk;": "\u27e7", + "ropar;": "\u2986", + "ropf;": "\U0001d563", + "roplus;": "\u2a2e", + "rotimes;": "\u2a35", + "rpar;": ")", + "rpargt;": "\u2994", + "rppolint;": "\u2a12", + "rrarr;": "\u21c9", + "rsaquo;": "\u203a", + "rscr;": "\U0001d4c7", + "rsh;": "\u21b1", + "rsqb;": "]", + "rsquo;": "\u2019", + "rsquor;": "\u2019", + "rthree;": "\u22cc", + "rtimes;": "\u22ca", + "rtri;": "\u25b9", + "rtrie;": "\u22b5", + "rtrif;": "\u25b8", + "rtriltri;": "\u29ce", + "ruluhar;": "\u2968", + "rx;": "\u211e", + "sacute;": "\u015b", + "sbquo;": "\u201a", + "sc;": "\u227b", + "scE;": "\u2ab4", + "scap;": "\u2ab8", + "scaron;": "\u0161", + "sccue;": "\u227d", + "sce;": "\u2ab0", + "scedil;": "\u015f", + "scirc;": "\u015d", + "scnE;": "\u2ab6", + "scnap;": "\u2aba", + "scnsim;": "\u22e9", + "scpolint;": "\u2a13", + "scsim;": "\u227f", + "scy;": "\u0441", + "sdot;": "\u22c5", + "sdotb;": "\u22a1", + "sdote;": "\u2a66", + "seArr;": "\u21d8", + "searhk;": "\u2925", + "searr;": "\u2198", + "searrow;": "\u2198", + "sect": "\xa7", + "sect;": "\xa7", + "semi;": ";", + "seswar;": "\u2929", + "setminus;": "\u2216", + "setmn;": "\u2216", + "sext;": "\u2736", + "sfr;": "\U0001d530", + "sfrown;": "\u2322", + "sharp;": "\u266f", + "shchcy;": "\u0449", + "shcy;": "\u0448", + "shortmid;": "\u2223", + "shortparallel;": "\u2225", + "shy": "\xad", + "shy;": "\xad", + "sigma;": "\u03c3", + "sigmaf;": "\u03c2", + "sigmav;": "\u03c2", + "sim;": "\u223c", + "simdot;": "\u2a6a", + "sime;": "\u2243", + "simeq;": "\u2243", + "simg;": "\u2a9e", + "simgE;": "\u2aa0", + "siml;": "\u2a9d", + "simlE;": "\u2a9f", + "simne;": "\u2246", + "simplus;": "\u2a24", + "simrarr;": "\u2972", + "slarr;": "\u2190", + "smallsetminus;": "\u2216", + "smashp;": "\u2a33", + "smeparsl;": "\u29e4", + "smid;": "\u2223", + "smile;": "\u2323", + "smt;": "\u2aaa", + "smte;": "\u2aac", + "smtes;": "\u2aac\ufe00", + "softcy;": "\u044c", + "sol;": "/", + "solb;": "\u29c4", + "solbar;": "\u233f", + "sopf;": "\U0001d564", + "spades;": "\u2660", + "spadesuit;": "\u2660", + "spar;": "\u2225", + "sqcap;": "\u2293", + "sqcaps;": "\u2293\ufe00", + "sqcup;": "\u2294", + "sqcups;": "\u2294\ufe00", + "sqsub;": "\u228f", + "sqsube;": "\u2291", + "sqsubset;": "\u228f", + "sqsubseteq;": "\u2291", + "sqsup;": "\u2290", + "sqsupe;": "\u2292", + "sqsupset;": "\u2290", + "sqsupseteq;": "\u2292", + "squ;": "\u25a1", + "square;": "\u25a1", + "squarf;": "\u25aa", + "squf;": "\u25aa", + "srarr;": "\u2192", + "sscr;": "\U0001d4c8", + "ssetmn;": "\u2216", + "ssmile;": "\u2323", + "sstarf;": "\u22c6", + "star;": "\u2606", + "starf;": "\u2605", + "straightepsilon;": "\u03f5", + "straightphi;": "\u03d5", + "strns;": "\xaf", + "sub;": "\u2282", + "subE;": "\u2ac5", + "subdot;": "\u2abd", + "sube;": "\u2286", + "subedot;": "\u2ac3", + "submult;": "\u2ac1", + "subnE;": "\u2acb", + "subne;": "\u228a", + "subplus;": "\u2abf", + "subrarr;": "\u2979", + "subset;": "\u2282", + "subseteq;": "\u2286", + "subseteqq;": "\u2ac5", + "subsetneq;": "\u228a", + "subsetneqq;": "\u2acb", + "subsim;": "\u2ac7", + "subsub;": "\u2ad5", + "subsup;": "\u2ad3", + "succ;": "\u227b", + "succapprox;": "\u2ab8", + "succcurlyeq;": "\u227d", + "succeq;": "\u2ab0", + "succnapprox;": "\u2aba", + "succneqq;": "\u2ab6", + "succnsim;": "\u22e9", + "succsim;": "\u227f", + "sum;": "\u2211", + "sung;": "\u266a", + "sup1": "\xb9", + "sup1;": "\xb9", + "sup2": "\xb2", + "sup2;": "\xb2", + "sup3": "\xb3", + "sup3;": "\xb3", + "sup;": "\u2283", + "supE;": "\u2ac6", + "supdot;": "\u2abe", + "supdsub;": "\u2ad8", + "supe;": "\u2287", + "supedot;": "\u2ac4", + "suphsol;": "\u27c9", + "suphsub;": "\u2ad7", + "suplarr;": "\u297b", + "supmult;": "\u2ac2", + "supnE;": "\u2acc", + "supne;": "\u228b", + "supplus;": "\u2ac0", + "supset;": "\u2283", + "supseteq;": "\u2287", + "supseteqq;": "\u2ac6", + "supsetneq;": "\u228b", + "supsetneqq;": "\u2acc", + "supsim;": "\u2ac8", + "supsub;": "\u2ad4", + "supsup;": "\u2ad6", + "swArr;": "\u21d9", + "swarhk;": "\u2926", + "swarr;": "\u2199", + "swarrow;": "\u2199", + "swnwar;": "\u292a", + "szlig": "\xdf", + "szlig;": "\xdf", + "target;": "\u2316", + "tau;": "\u03c4", + "tbrk;": "\u23b4", + "tcaron;": "\u0165", + "tcedil;": "\u0163", + "tcy;": "\u0442", + "tdot;": "\u20db", + "telrec;": "\u2315", + "tfr;": "\U0001d531", + "there4;": "\u2234", + "therefore;": "\u2234", + "theta;": "\u03b8", + "thetasym;": "\u03d1", + "thetav;": "\u03d1", + "thickapprox;": "\u2248", + "thicksim;": "\u223c", + "thinsp;": "\u2009", + "thkap;": "\u2248", + "thksim;": "\u223c", + "thorn": "\xfe", + "thorn;": "\xfe", + "tilde;": "\u02dc", + "times": "\xd7", + "times;": "\xd7", + "timesb;": "\u22a0", + "timesbar;": "\u2a31", + "timesd;": "\u2a30", + "tint;": "\u222d", + "toea;": "\u2928", + "top;": "\u22a4", + "topbot;": "\u2336", + "topcir;": "\u2af1", + "topf;": "\U0001d565", + "topfork;": "\u2ada", + "tosa;": "\u2929", + "tprime;": "\u2034", + "trade;": "\u2122", + "triangle;": "\u25b5", + "triangledown;": "\u25bf", + "triangleleft;": "\u25c3", + "trianglelefteq;": "\u22b4", + "triangleq;": "\u225c", + "triangleright;": "\u25b9", + "trianglerighteq;": "\u22b5", + "tridot;": "\u25ec", + "trie;": "\u225c", + "triminus;": "\u2a3a", + "triplus;": "\u2a39", + "trisb;": "\u29cd", + "tritime;": "\u2a3b", + "trpezium;": "\u23e2", + "tscr;": "\U0001d4c9", + "tscy;": "\u0446", + "tshcy;": "\u045b", + "tstrok;": "\u0167", + "twixt;": "\u226c", + "twoheadleftarrow;": "\u219e", + "twoheadrightarrow;": "\u21a0", + "uArr;": "\u21d1", + "uHar;": "\u2963", + "uacute": "\xfa", + "uacute;": "\xfa", + "uarr;": "\u2191", + "ubrcy;": "\u045e", + "ubreve;": "\u016d", + "ucirc": "\xfb", + "ucirc;": "\xfb", + "ucy;": "\u0443", + "udarr;": "\u21c5", + "udblac;": "\u0171", + "udhar;": "\u296e", + "ufisht;": "\u297e", + "ufr;": "\U0001d532", + "ugrave": "\xf9", + "ugrave;": "\xf9", + "uharl;": "\u21bf", + "uharr;": "\u21be", + "uhblk;": "\u2580", + "ulcorn;": "\u231c", + "ulcorner;": "\u231c", + "ulcrop;": "\u230f", + "ultri;": "\u25f8", + "umacr;": "\u016b", + "uml": "\xa8", + "uml;": "\xa8", + "uogon;": "\u0173", + "uopf;": "\U0001d566", + "uparrow;": "\u2191", + "updownarrow;": "\u2195", + "upharpoonleft;": "\u21bf", + "upharpoonright;": "\u21be", + "uplus;": "\u228e", + "upsi;": "\u03c5", + "upsih;": "\u03d2", + "upsilon;": "\u03c5", + "upuparrows;": "\u21c8", + "urcorn;": "\u231d", + "urcorner;": "\u231d", + "urcrop;": "\u230e", + "uring;": "\u016f", + "urtri;": "\u25f9", + "uscr;": "\U0001d4ca", + "utdot;": "\u22f0", + "utilde;": "\u0169", + "utri;": "\u25b5", + "utrif;": "\u25b4", + "uuarr;": "\u21c8", + "uuml": "\xfc", + "uuml;": "\xfc", + "uwangle;": "\u29a7", + "vArr;": "\u21d5", + "vBar;": "\u2ae8", + "vBarv;": "\u2ae9", + "vDash;": "\u22a8", + "vangrt;": "\u299c", + "varepsilon;": "\u03f5", + "varkappa;": "\u03f0", + "varnothing;": "\u2205", + "varphi;": "\u03d5", + "varpi;": "\u03d6", + "varpropto;": "\u221d", + "varr;": "\u2195", + "varrho;": "\u03f1", + "varsigma;": "\u03c2", + "varsubsetneq;": "\u228a\ufe00", + "varsubsetneqq;": "\u2acb\ufe00", + "varsupsetneq;": "\u228b\ufe00", + "varsupsetneqq;": "\u2acc\ufe00", + "vartheta;": "\u03d1", + "vartriangleleft;": "\u22b2", + "vartriangleright;": "\u22b3", + "vcy;": "\u0432", + "vdash;": "\u22a2", + "vee;": "\u2228", + "veebar;": "\u22bb", + "veeeq;": "\u225a", + "vellip;": "\u22ee", + "verbar;": "|", + "vert;": "|", + "vfr;": "\U0001d533", + "vltri;": "\u22b2", + "vnsub;": "\u2282\u20d2", + "vnsup;": "\u2283\u20d2", + "vopf;": "\U0001d567", + "vprop;": "\u221d", + "vrtri;": "\u22b3", + "vscr;": "\U0001d4cb", + "vsubnE;": "\u2acb\ufe00", + "vsubne;": "\u228a\ufe00", + "vsupnE;": "\u2acc\ufe00", + "vsupne;": "\u228b\ufe00", + "vzigzag;": "\u299a", + "wcirc;": "\u0175", + "wedbar;": "\u2a5f", + "wedge;": "\u2227", + "wedgeq;": "\u2259", + "weierp;": "\u2118", + "wfr;": "\U0001d534", + "wopf;": "\U0001d568", + "wp;": "\u2118", + "wr;": "\u2240", + "wreath;": "\u2240", + "wscr;": "\U0001d4cc", + "xcap;": "\u22c2", + "xcirc;": "\u25ef", + "xcup;": "\u22c3", + "xdtri;": "\u25bd", + "xfr;": "\U0001d535", + "xhArr;": "\u27fa", + "xharr;": "\u27f7", + "xi;": "\u03be", + "xlArr;": "\u27f8", + "xlarr;": "\u27f5", + "xmap;": "\u27fc", + "xnis;": "\u22fb", + "xodot;": "\u2a00", + "xopf;": "\U0001d569", + "xoplus;": "\u2a01", + "xotime;": "\u2a02", + "xrArr;": "\u27f9", + "xrarr;": "\u27f6", + "xscr;": "\U0001d4cd", + "xsqcup;": "\u2a06", + "xuplus;": "\u2a04", + "xutri;": "\u25b3", + "xvee;": "\u22c1", + "xwedge;": "\u22c0", + "yacute": "\xfd", + "yacute;": "\xfd", + "yacy;": "\u044f", + "ycirc;": "\u0177", + "ycy;": "\u044b", + "yen": "\xa5", + "yen;": "\xa5", + "yfr;": "\U0001d536", + "yicy;": "\u0457", + "yopf;": "\U0001d56a", + "yscr;": "\U0001d4ce", + "yucy;": "\u044e", + "yuml": "\xff", + "yuml;": "\xff", + "zacute;": "\u017a", + "zcaron;": "\u017e", + "zcy;": "\u0437", + "zdot;": "\u017c", + "zeetrf;": "\u2128", + "zeta;": "\u03b6", + "zfr;": "\U0001d537", + "zhcy;": "\u0436", + "zigrarr;": "\u21dd", + "zopf;": "\U0001d56b", + "zscr;": "\U0001d4cf", + "zwj;": "\u200d", + "zwnj;": "\u200c", +} + +replacementCharacters = { + 0x0: "\uFFFD", + 0x0d: "\u000D", + 0x80: "\u20AC", + 0x81: "\u0081", + 0x82: "\u201A", + 0x83: "\u0192", + 0x84: "\u201E", + 0x85: "\u2026", + 0x86: "\u2020", + 0x87: "\u2021", + 0x88: "\u02C6", + 0x89: "\u2030", + 0x8A: "\u0160", + 0x8B: "\u2039", + 0x8C: "\u0152", + 0x8D: "\u008D", + 0x8E: "\u017D", + 0x8F: "\u008F", + 0x90: "\u0090", + 0x91: "\u2018", + 0x92: "\u2019", + 0x93: "\u201C", + 0x94: "\u201D", + 0x95: "\u2022", + 0x96: "\u2013", + 0x97: "\u2014", + 0x98: "\u02DC", + 0x99: "\u2122", + 0x9A: "\u0161", + 0x9B: "\u203A", + 0x9C: "\u0153", + 0x9D: "\u009D", + 0x9E: "\u017E", + 0x9F: "\u0178", +} + +tokenTypes = { + "Doctype": 0, + "Characters": 1, + "SpaceCharacters": 2, + "StartTag": 3, + "EndTag": 4, + "EmptyTag": 5, + "Comment": 6, + "ParseError": 7 +} + +tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], + tokenTypes["EmptyTag"]]) + + +prefixes = dict([(v, k) for k, v in namespaces.items()]) +prefixes["http://www.w3.org/1998/Math/MathML"] = "math" + + +class DataLossWarning(UserWarning): + """Raised when the current tree is unable to represent the input data""" + pass + + +class _ReparseException(Exception): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py new file mode 100644 index 0000000..5ba926e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/alphabeticalattributes.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + +from collections import OrderedDict + + +def _attr_key(attr): + """Return an appropriate key for an attribute for sorting + + Attributes have a namespace that can be either ``None`` or a string. We + can't compare the two because they're different types, so we convert + ``None`` to an empty string first. + + """ + return (attr[0][0] or ''), attr[0][1] + + +class Filter(base.Filter): + """Alphabetizes attributes for elements""" + def __iter__(self): + for token in base.Filter.__iter__(self): + if token["type"] in ("StartTag", "EmptyTag"): + attrs = OrderedDict() + for name, value in sorted(token["data"].items(), + key=_attr_key): + attrs[name] = value + token["data"] = attrs + yield token diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/base.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/base.py new file mode 100644 index 0000000..c7dbaed --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/base.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import, division, unicode_literals + + +class Filter(object): + def __init__(self, source): + self.source = source + + def __iter__(self): + return iter(self.source) + + def __getattr__(self, name): + return getattr(self.source, name) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py new file mode 100644 index 0000000..aefb5c8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/inject_meta_charset.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Injects ``<meta charset=ENCODING>`` tag into head of document""" + def __init__(self, source, encoding): + """Creates a Filter + + :arg source: the source token stream + + :arg encoding: the encoding to set + + """ + base.Filter.__init__(self, source) + self.encoding = encoding + + def __iter__(self): + state = "pre_head" + meta_found = (self.encoding is None) + pending = [] + + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag": + if token["name"].lower() == "head": + state = "in_head" + + elif type == "EmptyTag": + if token["name"].lower() == "meta": + # replace charset with actual encoding + has_http_equiv_content_type = False + for (namespace, name), value in token["data"].items(): + if namespace is not None: + continue + elif name.lower() == 'charset': + token["data"][(namespace, name)] = self.encoding + meta_found = True + break + elif name == 'http-equiv' and value.lower() == 'content-type': + has_http_equiv_content_type = True + else: + if has_http_equiv_content_type and (None, "content") in token["data"]: + token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding + meta_found = True + + elif token["name"].lower() == "head" and not meta_found: + # insert meta into empty head + yield {"type": "StartTag", "name": "head", + "data": token["data"]} + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + yield {"type": "EndTag", "name": "head"} + meta_found = True + continue + + elif type == "EndTag": + if token["name"].lower() == "head" and pending: + # insert meta into head (if necessary) and flush pending queue + yield pending.pop(0) + if not meta_found: + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + while pending: + yield pending.pop(0) + meta_found = True + state = "post_head" + + if state == "in_head": + pending.append(token) + else: + yield token diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/lint.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/lint.py new file mode 100644 index 0000000..fcc07ee --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/lint.py @@ -0,0 +1,93 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type + +from . import base +from ..constants import namespaces, voidElements + +from ..constants import spaceCharacters +spaceCharacters = "".join(spaceCharacters) + + +class Filter(base.Filter): + """Lints the token stream for errors + + If it finds any errors, it'll raise an ``AssertionError``. + + """ + def __init__(self, source, require_matching_tags=True): + """Creates a Filter + + :arg source: the source token stream + + :arg require_matching_tags: whether or not to require matching tags + + """ + super(Filter, self).__init__(source) + self.require_matching_tags = require_matching_tags + + def __iter__(self): + open_elements = [] + for token in base.Filter.__iter__(self): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(token["data"], dict) + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert type == "EmptyTag" + else: + assert type == "StartTag" + if type == "StartTag" and self.require_matching_tags: + open_elements.append((namespace, name)) + for (namespace, name), value in token["data"].items(): + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(value, text_type) + + elif type == "EndTag": + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} + elif self.require_matching_tags: + start = open_elements.pop() + assert start == (namespace, name) + + elif type == "Comment": + data = token["data"] + assert isinstance(data, text_type) + + elif type in ("Characters", "SpaceCharacters"): + data = token["data"] + assert isinstance(data, text_type) + assert data != "" + if type == "SpaceCharacters": + assert data.strip(spaceCharacters) == "" + + elif type == "Doctype": + name = token["name"] + assert name is None or isinstance(name, text_type) + assert token["publicId"] is None or isinstance(name, text_type) + assert token["systemId"] is None or isinstance(name, text_type) + + elif type == "Entity": + assert isinstance(token["name"], text_type) + + elif type == "SerializerError": + assert isinstance(token["data"], text_type) + + else: + assert False, "Unknown token type: %(type)s" % {"type": type} + + yield token diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py new file mode 100644 index 0000000..4a86501 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/optionaltags.py @@ -0,0 +1,207 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Removes optional tags from the token stream""" + def slider(self): + previous1 = previous2 = None + for token in self.source: + if previous1 is not None: + yield previous2, previous1, token + previous2 = previous1 + previous1 = token + if previous1 is not None: + yield previous2, previous1, None + + def __iter__(self): + for previous, token, next in self.slider(): + type = token["type"] + if type == "StartTag": + if (token["data"] or + not self.is_optional_start(token["name"], previous, next)): + yield token + elif type == "EndTag": + if not self.is_optional_end(token["name"], next): + yield token + else: + yield token + + def is_optional_start(self, tagname, previous, next): + type = next and next["type"] or None + if tagname in 'html': + # An html element's start tag may be omitted if the first thing + # inside the html element is not a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname == 'head': + # A head element's start tag may be omitted if the first thing + # inside the head element is an element. + # XXX: we also omit the start tag if the head element is empty + if type in ("StartTag", "EmptyTag"): + return True + elif type == "EndTag": + return next["name"] == "head" + elif tagname == 'body': + # A body element's start tag may be omitted if the first thing + # inside the body element is not a space character or a comment, + # except if the first thing inside the body element is a script + # or style element and the node immediately preceding the body + # element is a head element whose end tag has been omitted. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we do not look at the preceding event, so we never omit + # the body element's start tag if it's followed by a script or + # a style element. + return next["name"] not in ('script', 'style') + else: + return True + elif tagname == 'colgroup': + # A colgroup element's start tag may be omitted if the first thing + # inside the colgroup element is a col element, and if the element + # is not immediately preceded by another colgroup element whose + # end tag has been omitted. + if type in ("StartTag", "EmptyTag"): + # XXX: we do not look at the preceding event, so instead we never + # omit the colgroup element's end tag when it is immediately + # followed by another colgroup element. See is_optional_end. + return next["name"] == "col" + else: + return False + elif tagname == 'tbody': + # A tbody element's start tag may be omitted if the first thing + # inside the tbody element is a tr element, and if the element is + # not immediately preceded by a tbody, thead, or tfoot element + # whose end tag has been omitted. + if type == "StartTag": + # omit the thead and tfoot elements' end tag when they are + # immediately followed by a tbody element. See is_optional_end. + if previous and previous['type'] == 'EndTag' and \ + previous['name'] in ('tbody', 'thead', 'tfoot'): + return False + return next["name"] == 'tr' + else: + return False + return False + + def is_optional_end(self, tagname, next): + type = next and next["type"] or None + if tagname in ('html', 'head', 'body'): + # An html element's end tag may be omitted if the html element + # is not immediately followed by a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname in ('li', 'optgroup', 'tr'): + # A li element's end tag may be omitted if the li element is + # immediately followed by another li element or if there is + # no more content in the parent element. + # An optgroup element's end tag may be omitted if the optgroup + # element is immediately followed by another optgroup element, + # or if there is no more content in the parent element. + # A tr element's end tag may be omitted if the tr element is + # immediately followed by another tr element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] == tagname + else: + return type == "EndTag" or type is None + elif tagname in ('dt', 'dd'): + # A dt element's end tag may be omitted if the dt element is + # immediately followed by another dt element or a dd element. + # A dd element's end tag may be omitted if the dd element is + # immediately followed by another dd element or a dt element, + # or if there is no more content in the parent element. + if type == "StartTag": + return next["name"] in ('dt', 'dd') + elif tagname == 'dd': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'p': + # A p element's end tag may be omitted if the p element is + # immediately followed by an address, article, aside, + # blockquote, datagrid, dialog, dir, div, dl, fieldset, + # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, + # nav, ol, p, pre, section, table, or ul, element, or if + # there is no more content in the parent element. + if type in ("StartTag", "EmptyTag"): + return next["name"] in ('address', 'article', 'aside', + 'blockquote', 'datagrid', 'dialog', + 'dir', 'div', 'dl', 'fieldset', 'footer', + 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'hr', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul') + else: + return type == "EndTag" or type is None + elif tagname == 'option': + # An option element's end tag may be omitted if the option + # element is immediately followed by another option element, + # or if it is immediately followed by an <code>optgroup</code> + # element, or if there is no more content in the parent + # element. + if type == "StartTag": + return next["name"] in ('option', 'optgroup') + else: + return type == "EndTag" or type is None + elif tagname in ('rt', 'rp'): + # An rt element's end tag may be omitted if the rt element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + # An rp element's end tag may be omitted if the rp element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('rt', 'rp') + else: + return type == "EndTag" or type is None + elif tagname == 'colgroup': + # A colgroup element's end tag may be omitted if the colgroup + # element is not immediately followed by a space character or + # a comment. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we also look for an immediately following colgroup + # element. See is_optional_start. + return next["name"] != 'colgroup' + else: + return True + elif tagname in ('thead', 'tbody'): + # A thead element's end tag may be omitted if the thead element + # is immediately followed by a tbody or tfoot element. + # A tbody element's end tag may be omitted if the tbody element + # is immediately followed by a tbody or tfoot element, or if + # there is no more content in the parent element. + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] in ['tbody', 'tfoot'] + elif tagname == 'tbody': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'tfoot': + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] == 'tbody' + else: + return type == "EndTag" or type is None + elif tagname in ('td', 'th'): + # A td element's end tag may be omitted if the td element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + # A th element's end tag may be omitted if the th element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('td', 'th') + else: + return type == "EndTag" or type is None + return False diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py new file mode 100644 index 0000000..af8e77b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/sanitizer.py @@ -0,0 +1,896 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +from xml.sax.saxutils import escape, unescape + +from pip._vendor.six.moves import urllib_parse as urlparse + +from . import base +from ..constants import namespaces, prefixes + +__all__ = ["Filter"] + + +allowed_elements = frozenset(( + (namespaces['html'], 'a'), + (namespaces['html'], 'abbr'), + (namespaces['html'], 'acronym'), + (namespaces['html'], 'address'), + (namespaces['html'], 'area'), + (namespaces['html'], 'article'), + (namespaces['html'], 'aside'), + (namespaces['html'], 'audio'), + (namespaces['html'], 'b'), + (namespaces['html'], 'big'), + (namespaces['html'], 'blockquote'), + (namespaces['html'], 'br'), + (namespaces['html'], 'button'), + (namespaces['html'], 'canvas'), + (namespaces['html'], 'caption'), + (namespaces['html'], 'center'), + (namespaces['html'], 'cite'), + (namespaces['html'], 'code'), + (namespaces['html'], 'col'), + (namespaces['html'], 'colgroup'), + (namespaces['html'], 'command'), + (namespaces['html'], 'datagrid'), + (namespaces['html'], 'datalist'), + (namespaces['html'], 'dd'), + (namespaces['html'], 'del'), + (namespaces['html'], 'details'), + (namespaces['html'], 'dfn'), + (namespaces['html'], 'dialog'), + (namespaces['html'], 'dir'), + (namespaces['html'], 'div'), + (namespaces['html'], 'dl'), + (namespaces['html'], 'dt'), + (namespaces['html'], 'em'), + (namespaces['html'], 'event-source'), + (namespaces['html'], 'fieldset'), + (namespaces['html'], 'figcaption'), + (namespaces['html'], 'figure'), + (namespaces['html'], 'footer'), + (namespaces['html'], 'font'), + (namespaces['html'], 'form'), + (namespaces['html'], 'header'), + (namespaces['html'], 'h1'), + (namespaces['html'], 'h2'), + (namespaces['html'], 'h3'), + (namespaces['html'], 'h4'), + (namespaces['html'], 'h5'), + (namespaces['html'], 'h6'), + (namespaces['html'], 'hr'), + (namespaces['html'], 'i'), + (namespaces['html'], 'img'), + (namespaces['html'], 'input'), + (namespaces['html'], 'ins'), + (namespaces['html'], 'keygen'), + (namespaces['html'], 'kbd'), + (namespaces['html'], 'label'), + (namespaces['html'], 'legend'), + (namespaces['html'], 'li'), + (namespaces['html'], 'm'), + (namespaces['html'], 'map'), + (namespaces['html'], 'menu'), + (namespaces['html'], 'meter'), + (namespaces['html'], 'multicol'), + (namespaces['html'], 'nav'), + (namespaces['html'], 'nextid'), + (namespaces['html'], 'ol'), + (namespaces['html'], 'output'), + (namespaces['html'], 'optgroup'), + (namespaces['html'], 'option'), + (namespaces['html'], 'p'), + (namespaces['html'], 'pre'), + (namespaces['html'], 'progress'), + (namespaces['html'], 'q'), + (namespaces['html'], 's'), + (namespaces['html'], 'samp'), + (namespaces['html'], 'section'), + (namespaces['html'], 'select'), + (namespaces['html'], 'small'), + (namespaces['html'], 'sound'), + (namespaces['html'], 'source'), + (namespaces['html'], 'spacer'), + (namespaces['html'], 'span'), + (namespaces['html'], 'strike'), + (namespaces['html'], 'strong'), + (namespaces['html'], 'sub'), + (namespaces['html'], 'sup'), + (namespaces['html'], 'table'), + (namespaces['html'], 'tbody'), + (namespaces['html'], 'td'), + (namespaces['html'], 'textarea'), + (namespaces['html'], 'time'), + (namespaces['html'], 'tfoot'), + (namespaces['html'], 'th'), + (namespaces['html'], 'thead'), + (namespaces['html'], 'tr'), + (namespaces['html'], 'tt'), + (namespaces['html'], 'u'), + (namespaces['html'], 'ul'), + (namespaces['html'], 'var'), + (namespaces['html'], 'video'), + (namespaces['mathml'], 'maction'), + (namespaces['mathml'], 'math'), + (namespaces['mathml'], 'merror'), + (namespaces['mathml'], 'mfrac'), + (namespaces['mathml'], 'mi'), + (namespaces['mathml'], 'mmultiscripts'), + (namespaces['mathml'], 'mn'), + (namespaces['mathml'], 'mo'), + (namespaces['mathml'], 'mover'), + (namespaces['mathml'], 'mpadded'), + (namespaces['mathml'], 'mphantom'), + (namespaces['mathml'], 'mprescripts'), + (namespaces['mathml'], 'mroot'), + (namespaces['mathml'], 'mrow'), + (namespaces['mathml'], 'mspace'), + (namespaces['mathml'], 'msqrt'), + (namespaces['mathml'], 'mstyle'), + (namespaces['mathml'], 'msub'), + (namespaces['mathml'], 'msubsup'), + (namespaces['mathml'], 'msup'), + (namespaces['mathml'], 'mtable'), + (namespaces['mathml'], 'mtd'), + (namespaces['mathml'], 'mtext'), + (namespaces['mathml'], 'mtr'), + (namespaces['mathml'], 'munder'), + (namespaces['mathml'], 'munderover'), + (namespaces['mathml'], 'none'), + (namespaces['svg'], 'a'), + (namespaces['svg'], 'animate'), + (namespaces['svg'], 'animateColor'), + (namespaces['svg'], 'animateMotion'), + (namespaces['svg'], 'animateTransform'), + (namespaces['svg'], 'clipPath'), + (namespaces['svg'], 'circle'), + (namespaces['svg'], 'defs'), + (namespaces['svg'], 'desc'), + (namespaces['svg'], 'ellipse'), + (namespaces['svg'], 'font-face'), + (namespaces['svg'], 'font-face-name'), + (namespaces['svg'], 'font-face-src'), + (namespaces['svg'], 'g'), + (namespaces['svg'], 'glyph'), + (namespaces['svg'], 'hkern'), + (namespaces['svg'], 'linearGradient'), + (namespaces['svg'], 'line'), + (namespaces['svg'], 'marker'), + (namespaces['svg'], 'metadata'), + (namespaces['svg'], 'missing-glyph'), + (namespaces['svg'], 'mpath'), + (namespaces['svg'], 'path'), + (namespaces['svg'], 'polygon'), + (namespaces['svg'], 'polyline'), + (namespaces['svg'], 'radialGradient'), + (namespaces['svg'], 'rect'), + (namespaces['svg'], 'set'), + (namespaces['svg'], 'stop'), + (namespaces['svg'], 'svg'), + (namespaces['svg'], 'switch'), + (namespaces['svg'], 'text'), + (namespaces['svg'], 'title'), + (namespaces['svg'], 'tspan'), + (namespaces['svg'], 'use'), +)) + +allowed_attributes = frozenset(( + # HTML attributes + (None, 'abbr'), + (None, 'accept'), + (None, 'accept-charset'), + (None, 'accesskey'), + (None, 'action'), + (None, 'align'), + (None, 'alt'), + (None, 'autocomplete'), + (None, 'autofocus'), + (None, 'axis'), + (None, 'background'), + (None, 'balance'), + (None, 'bgcolor'), + (None, 'bgproperties'), + (None, 'border'), + (None, 'bordercolor'), + (None, 'bordercolordark'), + (None, 'bordercolorlight'), + (None, 'bottompadding'), + (None, 'cellpadding'), + (None, 'cellspacing'), + (None, 'ch'), + (None, 'challenge'), + (None, 'char'), + (None, 'charoff'), + (None, 'choff'), + (None, 'charset'), + (None, 'checked'), + (None, 'cite'), + (None, 'class'), + (None, 'clear'), + (None, 'color'), + (None, 'cols'), + (None, 'colspan'), + (None, 'compact'), + (None, 'contenteditable'), + (None, 'controls'), + (None, 'coords'), + (None, 'data'), + (None, 'datafld'), + (None, 'datapagesize'), + (None, 'datasrc'), + (None, 'datetime'), + (None, 'default'), + (None, 'delay'), + (None, 'dir'), + (None, 'disabled'), + (None, 'draggable'), + (None, 'dynsrc'), + (None, 'enctype'), + (None, 'end'), + (None, 'face'), + (None, 'for'), + (None, 'form'), + (None, 'frame'), + (None, 'galleryimg'), + (None, 'gutter'), + (None, 'headers'), + (None, 'height'), + (None, 'hidefocus'), + (None, 'hidden'), + (None, 'high'), + (None, 'href'), + (None, 'hreflang'), + (None, 'hspace'), + (None, 'icon'), + (None, 'id'), + (None, 'inputmode'), + (None, 'ismap'), + (None, 'keytype'), + (None, 'label'), + (None, 'leftspacing'), + (None, 'lang'), + (None, 'list'), + (None, 'longdesc'), + (None, 'loop'), + (None, 'loopcount'), + (None, 'loopend'), + (None, 'loopstart'), + (None, 'low'), + (None, 'lowsrc'), + (None, 'max'), + (None, 'maxlength'), + (None, 'media'), + (None, 'method'), + (None, 'min'), + (None, 'multiple'), + (None, 'name'), + (None, 'nohref'), + (None, 'noshade'), + (None, 'nowrap'), + (None, 'open'), + (None, 'optimum'), + (None, 'pattern'), + (None, 'ping'), + (None, 'point-size'), + (None, 'poster'), + (None, 'pqg'), + (None, 'preload'), + (None, 'prompt'), + (None, 'radiogroup'), + (None, 'readonly'), + (None, 'rel'), + (None, 'repeat-max'), + (None, 'repeat-min'), + (None, 'replace'), + (None, 'required'), + (None, 'rev'), + (None, 'rightspacing'), + (None, 'rows'), + (None, 'rowspan'), + (None, 'rules'), + (None, 'scope'), + (None, 'selected'), + (None, 'shape'), + (None, 'size'), + (None, 'span'), + (None, 'src'), + (None, 'start'), + (None, 'step'), + (None, 'style'), + (None, 'summary'), + (None, 'suppress'), + (None, 'tabindex'), + (None, 'target'), + (None, 'template'), + (None, 'title'), + (None, 'toppadding'), + (None, 'type'), + (None, 'unselectable'), + (None, 'usemap'), + (None, 'urn'), + (None, 'valign'), + (None, 'value'), + (None, 'variable'), + (None, 'volume'), + (None, 'vspace'), + (None, 'vrml'), + (None, 'width'), + (None, 'wrap'), + (namespaces['xml'], 'lang'), + # MathML attributes + (None, 'actiontype'), + (None, 'align'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnlines'), + (None, 'columnspacing'), + (None, 'columnspan'), + (None, 'depth'), + (None, 'display'), + (None, 'displaystyle'), + (None, 'equalcolumns'), + (None, 'equalrows'), + (None, 'fence'), + (None, 'fontstyle'), + (None, 'fontweight'), + (None, 'frame'), + (None, 'height'), + (None, 'linethickness'), + (None, 'lspace'), + (None, 'mathbackground'), + (None, 'mathcolor'), + (None, 'mathvariant'), + (None, 'mathvariant'), + (None, 'maxsize'), + (None, 'minsize'), + (None, 'other'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowlines'), + (None, 'rowspacing'), + (None, 'rowspan'), + (None, 'rspace'), + (None, 'scriptlevel'), + (None, 'selection'), + (None, 'separator'), + (None, 'stretchy'), + (None, 'width'), + (None, 'width'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'type'), + # SVG attributes + (None, 'accent-height'), + (None, 'accumulate'), + (None, 'additive'), + (None, 'alphabetic'), + (None, 'arabic-form'), + (None, 'ascent'), + (None, 'attributeName'), + (None, 'attributeType'), + (None, 'baseProfile'), + (None, 'bbox'), + (None, 'begin'), + (None, 'by'), + (None, 'calcMode'), + (None, 'cap-height'), + (None, 'class'), + (None, 'clip-path'), + (None, 'color'), + (None, 'color-rendering'), + (None, 'content'), + (None, 'cx'), + (None, 'cy'), + (None, 'd'), + (None, 'dx'), + (None, 'dy'), + (None, 'descent'), + (None, 'display'), + (None, 'dur'), + (None, 'end'), + (None, 'fill'), + (None, 'fill-opacity'), + (None, 'fill-rule'), + (None, 'font-family'), + (None, 'font-size'), + (None, 'font-stretch'), + (None, 'font-style'), + (None, 'font-variant'), + (None, 'font-weight'), + (None, 'from'), + (None, 'fx'), + (None, 'fy'), + (None, 'g1'), + (None, 'g2'), + (None, 'glyph-name'), + (None, 'gradientUnits'), + (None, 'hanging'), + (None, 'height'), + (None, 'horiz-adv-x'), + (None, 'horiz-origin-x'), + (None, 'id'), + (None, 'ideographic'), + (None, 'k'), + (None, 'keyPoints'), + (None, 'keySplines'), + (None, 'keyTimes'), + (None, 'lang'), + (None, 'marker-end'), + (None, 'marker-mid'), + (None, 'marker-start'), + (None, 'markerHeight'), + (None, 'markerUnits'), + (None, 'markerWidth'), + (None, 'mathematical'), + (None, 'max'), + (None, 'min'), + (None, 'name'), + (None, 'offset'), + (None, 'opacity'), + (None, 'orient'), + (None, 'origin'), + (None, 'overline-position'), + (None, 'overline-thickness'), + (None, 'panose-1'), + (None, 'path'), + (None, 'pathLength'), + (None, 'points'), + (None, 'preserveAspectRatio'), + (None, 'r'), + (None, 'refX'), + (None, 'refY'), + (None, 'repeatCount'), + (None, 'repeatDur'), + (None, 'requiredExtensions'), + (None, 'requiredFeatures'), + (None, 'restart'), + (None, 'rotate'), + (None, 'rx'), + (None, 'ry'), + (None, 'slope'), + (None, 'stemh'), + (None, 'stemv'), + (None, 'stop-color'), + (None, 'stop-opacity'), + (None, 'strikethrough-position'), + (None, 'strikethrough-thickness'), + (None, 'stroke'), + (None, 'stroke-dasharray'), + (None, 'stroke-dashoffset'), + (None, 'stroke-linecap'), + (None, 'stroke-linejoin'), + (None, 'stroke-miterlimit'), + (None, 'stroke-opacity'), + (None, 'stroke-width'), + (None, 'systemLanguage'), + (None, 'target'), + (None, 'text-anchor'), + (None, 'to'), + (None, 'transform'), + (None, 'type'), + (None, 'u1'), + (None, 'u2'), + (None, 'underline-position'), + (None, 'underline-thickness'), + (None, 'unicode'), + (None, 'unicode-range'), + (None, 'units-per-em'), + (None, 'values'), + (None, 'version'), + (None, 'viewBox'), + (None, 'visibility'), + (None, 'width'), + (None, 'widths'), + (None, 'x'), + (None, 'x-height'), + (None, 'x1'), + (None, 'x2'), + (namespaces['xlink'], 'actuate'), + (namespaces['xlink'], 'arcrole'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'role'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'title'), + (namespaces['xlink'], 'type'), + (namespaces['xml'], 'base'), + (namespaces['xml'], 'lang'), + (namespaces['xml'], 'space'), + (None, 'y'), + (None, 'y1'), + (None, 'y2'), + (None, 'zoomAndPan'), +)) + +attr_val_is_uri = frozenset(( + (None, 'href'), + (None, 'src'), + (None, 'cite'), + (None, 'action'), + (None, 'longdesc'), + (None, 'poster'), + (None, 'background'), + (None, 'datasrc'), + (None, 'dynsrc'), + (None, 'lowsrc'), + (None, 'ping'), + (namespaces['xlink'], 'href'), + (namespaces['xml'], 'base'), +)) + +svg_attr_val_allows_ref = frozenset(( + (None, 'clip-path'), + (None, 'color-profile'), + (None, 'cursor'), + (None, 'fill'), + (None, 'filter'), + (None, 'marker'), + (None, 'marker-start'), + (None, 'marker-mid'), + (None, 'marker-end'), + (None, 'mask'), + (None, 'stroke'), +)) + +svg_allow_local_href = frozenset(( + (None, 'altGlyph'), + (None, 'animate'), + (None, 'animateColor'), + (None, 'animateMotion'), + (None, 'animateTransform'), + (None, 'cursor'), + (None, 'feImage'), + (None, 'filter'), + (None, 'linearGradient'), + (None, 'pattern'), + (None, 'radialGradient'), + (None, 'textpath'), + (None, 'tref'), + (None, 'set'), + (None, 'use') +)) + +allowed_css_properties = frozenset(( + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', +)) + +allowed_css_keywords = frozenset(( + 'auto', + 'aqua', + 'black', + 'block', + 'blue', + 'bold', + 'both', + 'bottom', + 'brown', + 'center', + 'collapse', + 'dashed', + 'dotted', + 'fuchsia', + 'gray', + 'green', + '!important', + 'italic', + 'left', + 'lime', + 'maroon', + 'medium', + 'none', + 'navy', + 'normal', + 'nowrap', + 'olive', + 'pointer', + 'purple', + 'red', + 'right', + 'solid', + 'silver', + 'teal', + 'top', + 'transparent', + 'underline', + 'white', + 'yellow', +)) + +allowed_svg_properties = frozenset(( + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', +)) + +allowed_protocols = frozenset(( + 'ed2k', + 'ftp', + 'http', + 'https', + 'irc', + 'mailto', + 'news', + 'gopher', + 'nntp', + 'telnet', + 'webcal', + 'xmpp', + 'callto', + 'feed', + 'urn', + 'aim', + 'rsync', + 'tag', + 'ssh', + 'sftp', + 'rtsp', + 'afs', + 'data', +)) + +allowed_content_types = frozenset(( + 'image/png', + 'image/jpeg', + 'image/gif', + 'image/webp', + 'image/bmp', + 'text/plain', +)) + + +data_content_type = re.compile(r''' + ^ + # Match a content type <application>/<type> + (?P<content_type>[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) + # Match any character set and encoding + (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) + |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) + # Assume the rest is data + ,.* + $ + ''', + re.VERBOSE) + + +class Filter(base.Filter): + """Sanitizes token stream of XHTML+MathML+SVG and of inline style attributes""" + def __init__(self, + source, + allowed_elements=allowed_elements, + allowed_attributes=allowed_attributes, + allowed_css_properties=allowed_css_properties, + allowed_css_keywords=allowed_css_keywords, + allowed_svg_properties=allowed_svg_properties, + allowed_protocols=allowed_protocols, + allowed_content_types=allowed_content_types, + attr_val_is_uri=attr_val_is_uri, + svg_attr_val_allows_ref=svg_attr_val_allows_ref, + svg_allow_local_href=svg_allow_local_href): + """Creates a Filter + + :arg allowed_elements: set of elements to allow--everything else will + be escaped + + :arg allowed_attributes: set of attributes to allow in + elements--everything else will be stripped + + :arg allowed_css_properties: set of CSS properties to allow--everything + else will be stripped + + :arg allowed_css_keywords: set of CSS keywords to allow--everything + else will be stripped + + :arg allowed_svg_properties: set of SVG properties to allow--everything + else will be removed + + :arg allowed_protocols: set of allowed protocols for URIs + + :arg allowed_content_types: set of allowed content types for ``data`` URIs. + + :arg attr_val_is_uri: set of attributes that have URI values--values + that have a scheme not listed in ``allowed_protocols`` are removed + + :arg svg_attr_val_allows_ref: set of SVG attributes that can have + references + + :arg svg_allow_local_href: set of SVG elements that can have local + hrefs--these are removed + + """ + super(Filter, self).__init__(source) + self.allowed_elements = allowed_elements + self.allowed_attributes = allowed_attributes + self.allowed_css_properties = allowed_css_properties + self.allowed_css_keywords = allowed_css_keywords + self.allowed_svg_properties = allowed_svg_properties + self.allowed_protocols = allowed_protocols + self.allowed_content_types = allowed_content_types + self.attr_val_is_uri = attr_val_is_uri + self.svg_attr_val_allows_ref = svg_attr_val_allows_ref + self.svg_allow_local_href = svg_allow_local_href + + def __iter__(self): + for token in base.Filter.__iter__(self): + token = self.sanitize_token(token) + if token: + yield token + + # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and + # stripping out all attributes not in ALLOWED_ATTRIBUTES. Style attributes + # are parsed, and a restricted set, specified by ALLOWED_CSS_PROPERTIES and + # ALLOWED_CSS_KEYWORDS, are allowed through. attributes in ATTR_VAL_IS_URI + # are scanned, and only URI schemes specified in ALLOWED_PROTOCOLS are + # allowed. + # + # sanitize_html('<script> do_nasty_stuff() </script>') + # => <script> do_nasty_stuff() </script> + # sanitize_html('<a href="javascript: sucker();">Click here for $100</a>') + # => <a>Click here for $100</a> + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "</%s>" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/html5parser.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..ae41a13 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2791 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import with_metaclass, viewkeys + +import types +from collections import OrderedDict + +from . import _inputstream +from . import _tokenizer + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = dict([(name, cls(self, self.tree)) for name, cls in + getPhases(debug).items()]) + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.normalizedTokens(): + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def normalizedTokens(self): + for token in self.tokenizer: + yield self.normalizeToken(token) + + def parse(self, stream, *args, **kwargs): + """Parse a HTML document into a well-formed tree + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def normalizeToken(self, token): + # HTML5 specific normalizations to the token stream + if token["type"] == tokenTypes["StartTag"]: + raw = token["data"] + token["data"] = OrderedDict(raw) + if len(raw) > len(token["data"]): + # we had some duplicated attribute, fix so first wins + token["data"].update(raw[::-1]) + + return token + + def adjustMathMLAttributes(self, token): + adjust_attributes(token, adjustMathMLAttributes) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = dict((value, key) for key, value in + tokenTypes.items()) + + def wrapped(self, *args, **kwargs): + if function.__name__.startswith("process") and len(args) > 0: + token = args[0] + try: + info = {"type": type_names[token['type']]} + except: + raise + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + return self.startTagHandler[token["name"]](token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + return self.endTagHandler[token["name"]](token) + + class InitialPhase(Phase): + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("head", "body", "html", "br"), self.endTagImplyHead) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + class InHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("title", self.startTagTitle), + (("noframes", "style"), self.startTagNoFramesStyle), + ("noscript", self.startTagNoscript), + ("script", self.startTagScript), + (("base", "basefont", "bgsound", "command", "link"), + self.startTagBaseLinkCommand), + ("meta", self.startTagMeta), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("head", self.endTagHead), + (("br", "html", "body"), self.endTagHtmlBodyBr) + ]) + self.endTagHandler.default = self.endTagOther + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + class InHeadNoscriptPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), self.startTagBaseLinkCommand), + (("head", "noscript"), self.startTagHeadNoscript), + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("noscript", self.endTagNoscript), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + class AfterHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", + "style", "title"), + self.startTagFromHead), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), + self.endTagHtmlBodyBr)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + class InBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody + # the really-really-really-very crazy mode + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + # Set this to the default handler + self.processSpaceCharacters = self.processSpaceCharactersNonPre + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("base", "basefont", "bgsound", "command", "link", "meta", + "script", "style", "title"), + self.startTagProcessInHead), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("address", "article", "aside", "blockquote", "center", "details", + "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", + "section", "summary", "ul"), + self.startTagCloseP), + (headingElements, self.startTagHeading), + (("pre", "listing"), self.startTagPreListing), + ("form", self.startTagForm), + (("li", "dd", "dt"), self.startTagListItem), + ("plaintext", self.startTagPlaintext), + ("a", self.startTagA), + (("b", "big", "code", "em", "font", "i", "s", "small", "strike", + "strong", "tt", "u"), self.startTagFormatting), + ("nobr", self.startTagNobr), + ("button", self.startTagButton), + (("applet", "marquee", "object"), self.startTagAppletMarqueeObject), + ("xmp", self.startTagXmp), + ("table", self.startTagTable), + (("area", "br", "embed", "img", "keygen", "wbr"), + self.startTagVoidFormatting), + (("param", "source", "track"), self.startTagParamSource), + ("input", self.startTagInput), + ("hr", self.startTagHr), + ("image", self.startTagImage), + ("isindex", self.startTagIsIndex), + ("textarea", self.startTagTextarea), + ("iframe", self.startTagIFrame), + ("noscript", self.startTagNoscript), + (("noembed", "noframes"), self.startTagRawtext), + ("select", self.startTagSelect), + (("rp", "rt"), self.startTagRpRt), + (("option", "optgroup"), self.startTagOpt), + (("math"), self.startTagMath), + (("svg"), self.startTagSvg), + (("caption", "col", "colgroup", "frame", "head", + "tbody", "td", "tfoot", "th", "thead", + "tr"), self.startTagMisplaced) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("body", self.endTagBody), + ("html", self.endTagHtml), + (("address", "article", "aside", "blockquote", "button", "center", + "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", + "section", "summary", "ul"), self.endTagBlock), + ("form", self.endTagForm), + ("p", self.endTagP), + (("dd", "dt", "li"), self.endTagListItem), + (headingElements, self.endTagHeading), + (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", + "strike", "strong", "tt", "u"), self.endTagFormatting), + (("applet", "marquee", "object"), self.endTagAppletMarqueeObject), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def isMatchingFormattingElement(self, node1, node2): + return (node1.name == node2.name and + node1.namespace == node2.namespace and + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of <pre>, <listing>, and <textarea> blocks) we + # want to drop leading newlines + data = token["data"] + self.processSpaceCharacters = self.processSpaceCharactersNonPre + if (data.startswith("\n") and + self.tree.openElements[-1].name in ("pre", "listing", "textarea") and + not self.tree.openElements[-1].hasContent()): + data = data[1:] + if data: + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(data) + + def processCharacters(self, token): + if token["data"] == "\u0000": + # The tokenizer should always emit null on its own + return + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + # This must be bad for performance + if (self.parser.framesetOK and + any([char not in spaceCharacters + for char in token["data"]])): + self.parser.framesetOK = False + + def processSpaceCharactersNonPre(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + + def startTagProcessInHead(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagBody(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "body"}) + if (len(self.tree.openElements) == 1 or + self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + else: + self.parser.framesetOK = False + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[1].attributes: + self.tree.openElements[1].attributes[attr] = value + + def startTagFrameset(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "frameset"}) + if (len(self.tree.openElements) == 1 or self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + elif not self.parser.framesetOK: + pass + else: + if self.tree.openElements[1].parent: + self.tree.openElements[1].parent.removeChild(self.tree.openElements[1]) + while self.tree.openElements[-1].name != "html": + self.tree.openElements.pop() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagCloseP(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + + def startTagPreListing(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + + def startTagForm(self, token): + if self.tree.formPointer: + self.parser.parseError("unexpected-start-tag", {"name": "form"}) + else: + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + + def startTagListItem(self, token): + self.parser.framesetOK = False + + stopNamesMap = {"li": ["li"], + "dt": ["dt", "dd"], + "dd": ["dt", "dd"]} + stopNames = stopNamesMap[token["name"]] + for node in reversed(self.tree.openElements): + if node.name in stopNames: + self.parser.phase.processEndTag( + impliedTagToken(node.name, "EndTag")) + break + if (node.nameTuple in specialElements and + node.name not in ("address", "div", "p")): + break + + if self.tree.elementInScope("p", variant="button"): + self.parser.phase.processEndTag( + impliedTagToken("p", "EndTag")) + + self.tree.insertElement(token) + + def startTagPlaintext(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.plaintextState + + def startTagHeading(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + if self.tree.openElements[-1].name in headingElements: + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagA(self, token): + afeAElement = self.tree.elementInActiveFormattingElements("a") + if afeAElement: + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "a", "endName": "a"}) + self.endTagFormatting(impliedTagToken("a")) + if afeAElement in self.tree.openElements: + self.tree.openElements.remove(afeAElement) + if afeAElement in self.tree.activeFormattingElements: + self.tree.activeFormattingElements.remove(afeAElement) + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagNobr(self, token): + self.tree.reconstructActiveFormattingElements() + if self.tree.elementInScope("nobr"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "nobr", "endName": "nobr"}) + self.processEndTag(impliedTagToken("nobr")) + # XXX Need tests that trigger the following + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagButton(self, token): + if self.tree.elementInScope("button"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "button", "endName": "button"}) + self.processEndTag(impliedTagToken("button")) + return token + else: + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + + def startTagAppletMarqueeObject(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.activeFormattingElements.append(Marker) + self.parser.framesetOK = False + + def startTagXmp(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.reconstructActiveFormattingElements() + self.parser.framesetOK = False + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagTable(self, token): + if self.parser.compatMode != "quirks": + if self.tree.elementInScope("p", variant="button"): + self.processEndTag(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.parser.phase = self.parser.phases["inTable"] + + def startTagVoidFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagInput(self, token): + framesetOK = self.parser.framesetOK + self.startTagVoidFormatting(token) + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + # input type=hidden doesn't change framesetOK + self.parser.framesetOK = framesetOK + + def startTagParamSource(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagHr(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagImage(self, token): + # No really... + self.parser.parseError("unexpected-start-tag-treated-as", + {"originalName": "image", "newName": "img"}) + self.processStartTag(impliedTagToken("img", "StartTag", + attributes=token["data"], + selfClosing=token["selfClosing"])) + + def startTagIsIndex(self, token): + self.parser.parseError("deprecated-tag", {"name": "isindex"}) + if self.tree.formPointer: + return + form_attrs = {} + if "action" in token["data"]: + form_attrs["action"] = token["data"]["action"] + self.processStartTag(impliedTagToken("form", "StartTag", + attributes=form_attrs)) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processStartTag(impliedTagToken("label", "StartTag")) + # XXX Localization ... + if "prompt" in token["data"]: + prompt = token["data"]["prompt"] + else: + prompt = "This is a searchable index. Enter search keywords: " + self.processCharacters( + {"type": tokenTypes["Characters"], "data": prompt}) + attributes = token["data"].copy() + if "action" in attributes: + del attributes["action"] + if "prompt" in attributes: + del attributes["prompt"] + attributes["name"] = "isindex" + self.processStartTag(impliedTagToken("input", "StartTag", + attributes=attributes, + selfClosing=token["selfClosing"])) + self.processEndTag(impliedTagToken("label")) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processEndTag(impliedTagToken("form")) + + def startTagTextarea(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.rcdataState + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + self.parser.framesetOK = False + + def startTagIFrame(self, token): + self.parser.framesetOK = False + self.startTagRawtext(token) + + def startTagNoscript(self, token): + if self.parser.scripting: + self.startTagRawtext(token) + else: + self.startTagOther(token) + + def startTagRawtext(self, token): + """iframe, noembed noframes, noscript(if scripting enabled)""" + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagOpt(self, token): + if self.tree.openElements[-1].name == "option": + self.parser.phase.processEndTag(impliedTagToken("option")) + self.tree.reconstructActiveFormattingElements() + self.parser.tree.insertElement(token) + + def startTagSelect(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + if self.parser.phase in (self.parser.phases["inTable"], + self.parser.phases["inCaption"], + self.parser.phases["inColumnGroup"], + self.parser.phases["inTableBody"], + self.parser.phases["inRow"], + self.parser.phases["inCell"]): + self.parser.phase = self.parser.phases["inSelectInTable"] + else: + self.parser.phase = self.parser.phases["inSelect"] + + def startTagRpRt(self, token): + if self.tree.elementInScope("ruby"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "ruby": + self.parser.parseError() + self.tree.insertElement(token) + + def startTagMath(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustMathMLAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["mathml"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagSvg(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["svg"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMisplaced(self, token): + """ Elements that should be children of other elements that have a + different insertion mode; here they are ignored + "caption", "col", "colgroup", "frame", "frameset", "head", + "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", + "tr", "noscript" + """ + self.parser.parseError("unexpected-start-tag-ignored", {"name": token["name"]}) + + def startTagOther(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + + def endTagP(self, token): + if not self.tree.elementInScope("p", variant="button"): + self.startTagCloseP(impliedTagToken("p", "StartTag")) + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + self.endTagP(impliedTagToken("p", "EndTag")) + else: + self.tree.generateImpliedEndTags("p") + if self.tree.openElements[-1].name != "p": + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + node = self.tree.openElements.pop() + while node.name != "p": + node = self.tree.openElements.pop() + + def endTagBody(self, token): + if not self.tree.elementInScope("body"): + self.parser.parseError() + return + elif self.tree.openElements[-1].name != "body": + for node in self.tree.openElements[2:]: + if node.name not in frozenset(("dd", "dt", "li", "optgroup", + "option", "p", "rp", "rt", + "tbody", "td", "tfoot", + "th", "thead", "tr", "body", + "html")): + # Not sure this is the correct name for the parse error + self.parser.parseError( + "expected-one-end-tag-but-got-another", + {"gotName": "body", "expectedName": node.name}) + break + self.parser.phase = self.parser.phases["afterBody"] + + def endTagHtml(self, token): + # We repeat the test for the body end tag token being ignored here + if self.tree.elementInScope("body"): + self.endTagBody(impliedTagToken("body")) + return token + + def endTagBlock(self, token): + # Put us back in the right whitespace handling mode + if token["name"] == "pre": + self.processSpaceCharacters = self.processSpaceCharactersNonPre + inScope = self.tree.elementInScope(token["name"]) + if inScope: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + if inScope: + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagForm(self, token): + node = self.tree.formPointer + self.tree.formPointer = None + if node is None or not self.tree.elementInScope(node): + self.parser.parseError("unexpected-end-tag", + {"name": "form"}) + else: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1] != node: + self.parser.parseError("end-tag-too-early-ignored", + {"name": "form"}) + self.tree.openElements.remove(node) + + def endTagListItem(self, token): + if token["name"] == "li": + variant = "list" + else: + variant = None + if not self.tree.elementInScope(token["name"], variant=variant): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + else: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError( + "end-tag-too-early", + {"name": token["name"]}) + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagHeading(self, token): + for item in headingElements: + if self.tree.elementInScope(item): + self.tree.generateImpliedEndTags() + break + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + for item in headingElements: + if self.tree.elementInScope(item): + item = self.tree.openElements.pop() + while item.name not in headingElements: + item = self.tree.openElements.pop() + break + + def endTagFormatting(self, token): + """The much-feared adoption agency algorithm""" + # http://svn.whatwg.org/webapps/complete.html#adoptionAgency revision 7867 + # XXX Better parseError messages appreciated. + + # Step 1 + outerLoopCounter = 0 + + # Step 2 + while outerLoopCounter < 8: + + # Step 3 + outerLoopCounter += 1 + + # Step 4: + + # Let the formatting element be the last element in + # the list of active formatting elements that: + # - is between the end of the list and the last scope + # marker in the list, if any, or the start of the list + # otherwise, and + # - has the same tag name as the token. + formattingElement = self.tree.elementInActiveFormattingElements( + token["name"]) + if (not formattingElement or + (formattingElement in self.tree.openElements and + not self.tree.elementInScope(formattingElement.name))): + # If there is no such node, then abort these steps + # and instead act as described in the "any other + # end tag" entry below. + self.endTagOther(token) + return + + # Otherwise, if there is such a node, but that node is + # not in the stack of open elements, then this is a + # parse error; remove the element from the list, and + # abort these steps. + elif formattingElement not in self.tree.openElements: + self.parser.parseError("adoption-agency-1.2", {"name": token["name"]}) + self.tree.activeFormattingElements.remove(formattingElement) + return + + # Otherwise, if there is such a node, and that node is + # also in the stack of open elements, but the element + # is not in scope, then this is a parse error; ignore + # the token, and abort these steps. + elif not self.tree.elementInScope(formattingElement.name): + self.parser.parseError("adoption-agency-4.4", {"name": token["name"]}) + return + + # Otherwise, there is a formatting element and that + # element is in the stack and is in scope. If the + # element is not the current node, this is a parse + # error. In any case, proceed with the algorithm as + # written in the following steps. + else: + if formattingElement != self.tree.openElements[-1]: + self.parser.parseError("adoption-agency-1.3", {"name": token["name"]}) + + # Step 5: + + # Let the furthest block be the topmost node in the + # stack of open elements that is lower in the stack + # than the formatting element, and is an element in + # the special category. There might not be one. + afeIndex = self.tree.openElements.index(formattingElement) + furthestBlock = None + for element in self.tree.openElements[afeIndex:]: + if element.nameTuple in specialElements: + furthestBlock = element + break + + # Step 6: + + # If there is no furthest block, then the UA must + # first pop all the nodes from the bottom of the stack + # of open elements, from the current node up to and + # including the formatting element, then remove the + # formatting element from the list of active + # formatting elements, and finally abort these steps. + if furthestBlock is None: + element = self.tree.openElements.pop() + while element != formattingElement: + element = self.tree.openElements.pop() + self.tree.activeFormattingElements.remove(element) + return + + # Step 7 + commonAncestor = self.tree.openElements[afeIndex - 1] + + # Step 8: + # The bookmark is supposed to help us identify where to reinsert + # nodes in step 15. We have to ensure that we reinsert nodes after + # the node before the active formatting element. Note the bookmark + # can move in step 9.7 + bookmark = self.tree.activeFormattingElements.index(formattingElement) + + # Step 9 + lastNode = node = furthestBlock + innerLoopCounter = 0 + + index = self.tree.openElements.index(node) + while innerLoopCounter < 3: + innerLoopCounter += 1 + # Node is element before node in open elements + index -= 1 + node = self.tree.openElements[index] + if node not in self.tree.activeFormattingElements: + self.tree.openElements.remove(node) + continue + # Step 9.6 + if node == formattingElement: + break + # Step 9.7 + if lastNode == furthestBlock: + bookmark = self.tree.activeFormattingElements.index(node) + 1 + # Step 9.8 + clone = node.cloneNode() + # Replace node with clone + self.tree.activeFormattingElements[ + self.tree.activeFormattingElements.index(node)] = clone + self.tree.openElements[ + self.tree.openElements.index(node)] = clone + node = clone + # Step 9.9 + # Remove lastNode from its parents, if any + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + node.appendChild(lastNode) + # Step 9.10 + lastNode = node + + # Step 10 + # Foster parent lastNode if commonAncestor is a + # table, tbody, tfoot, thead, or tr we need to foster + # parent the lastNode + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + + if commonAncestor.name in frozenset(("table", "tbody", "tfoot", "thead", "tr")): + parent, insertBefore = self.tree.getTableMisnestedNodePosition() + parent.insertBefore(lastNode, insertBefore) + else: + commonAncestor.appendChild(lastNode) + + # Step 11 + clone = formattingElement.cloneNode() + + # Step 12 + furthestBlock.reparentChildren(clone) + + # Step 13 + furthestBlock.appendChild(clone) + + # Step 14 + self.tree.activeFormattingElements.remove(formattingElement) + self.tree.activeFormattingElements.insert(bookmark, clone) + + # Step 15 + self.tree.openElements.remove(formattingElement) + self.tree.openElements.insert( + self.tree.openElements.index(furthestBlock) + 1, clone) + + def endTagAppletMarqueeObject(self, token): + if self.tree.elementInScope(token["name"]): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + if self.tree.elementInScope(token["name"]): + element = self.tree.openElements.pop() + while element.name != token["name"]: + element = self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + + def endTagBr(self, token): + self.parser.parseError("unexpected-end-tag-treated-as", + {"originalName": "br", "newName": "br element"}) + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(impliedTagToken("br", "StartTag")) + self.tree.openElements.pop() + + def endTagOther(self, token): + for node in self.tree.openElements[::-1]: + if node.name == token["name"]: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + while self.tree.openElements.pop() != node: + pass + break + else: + if node.nameTuple in specialElements: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + break + + class TextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([ + ("script", self.endTagScript)]) + self.endTagHandler.default = self.endTagOther + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processEOF(self): + self.parser.parseError("expected-named-closing-tag-but-got-eof", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + return True + + def startTagOther(self, token): + assert False, "Tried to process start tag %s in RCDATA/RAWTEXT mode" % token['name'] + + def endTagScript(self, token): + node = self.tree.openElements.pop() + assert node.name == "script" + self.parser.phase = self.parser.originalPhase + # The rest of this method is all stuff that only happens if + # document.write works + + def endTagOther(self, token): + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + + class InTablePhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("caption", self.startTagCaption), + ("colgroup", self.startTagColgroup), + ("col", self.startTagCol), + (("tbody", "tfoot", "thead"), self.startTagRowGroup), + (("td", "th", "tr"), self.startTagImplyTbody), + ("table", self.startTagTable), + (("style", "script"), self.startTagStyleScript), + ("input", self.startTagInput), + ("form", self.startTagForm) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "tbody", "td", + "tfoot", "th", "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableContext(self): + # "clear the stack back to a table context" + while self.tree.openElements[-1].name not in ("table", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + # When the current node is <html> it's an innerHTML case + + # processing methods + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-table") + else: + assert self.parser.innerHTML + # Stop parsing + + def processSpaceCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processSpaceCharacters(token) + + def processCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processCharacters(token) + + def insertText(self, token): + # If we get here there must be at least one non-whitespace character + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processCharacters(token) + self.tree.insertFromTable = False + + def startTagCaption(self, token): + self.clearStackToTableContext() + self.tree.activeFormattingElements.append(Marker) + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCaption"] + + def startTagColgroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inColumnGroup"] + + def startTagCol(self, token): + self.startTagColgroup(impliedTagToken("colgroup", "StartTag")) + return token + + def startTagRowGroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inTableBody"] + + def startTagImplyTbody(self, token): + self.startTagRowGroup(impliedTagToken("tbody", "StartTag")) + return token + + def startTagTable(self, token): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "table", "endName": "table"}) + self.parser.phase.processEndTag(impliedTagToken("table")) + if not self.parser.innerHTML: + return token + + def startTagStyleScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagInput(self, token): + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + self.parser.parseError("unexpected-hidden-input-in-table") + self.tree.insertElement(token) + # XXX associate with form + self.tree.openElements.pop() + else: + self.startTagOther(token) + + def startTagForm(self, token): + self.parser.parseError("unexpected-form-in-table") + if self.tree.formPointer is None: + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + self.tree.openElements.pop() + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processStartTag(token) + self.tree.insertFromTable = False + + def endTagTable(self, token): + if self.tree.elementInScope("table", variant="table"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "table": + self.parser.parseError("end-tag-too-early-named", + {"gotName": "table", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "table": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processEndTag(token) + self.tree.insertFromTable = False + + class InTableTextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.originalPhase = None + self.characterTokens = [] + + def flushCharacters(self): + data = "".join([item["data"] for item in self.characterTokens]) + if any([item not in spaceCharacters for item in data]): + token = {"type": tokenTypes["Characters"], "data": data} + self.parser.phases["inTable"].insertText(token) + elif data: + self.tree.insertText(data) + self.characterTokens = [] + + def processComment(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEOF(self): + self.flushCharacters() + self.parser.phase = self.originalPhase + return True + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.characterTokens.append(token) + + def processSpaceCharacters(self, token): + # pretty sure we should never reach here + self.characterTokens.append(token) + # assert False + + def processStartTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEndTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + class InCaptionPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-caption + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableElement) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("caption", self.endTagCaption), + ("table", self.endTagTable), + (("body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagCaption(self): + return not self.tree.elementInScope("caption", variant="table") + + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableElement(self, token): + self.parser.parseError() + # XXX Have to duplicate logic here to find out if the tag is ignored + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagCaption(self, token): + if not self.ignoreEndTagCaption(): + # AT this code is quite similar to endTagTable in "InTable" + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "caption": + self.parser.parseError("expected-one-end-tag-but-got-another", + {"gotName": "caption", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "caption": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inTable"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + self.parser.parseError() + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InColumnGroupPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-column + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("col", self.startTagCol) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("colgroup", self.endTagColgroup), + ("col", self.endTagCol) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagColgroup(self): + return self.tree.openElements[-1].name == "html" + + def processEOF(self): + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + return + else: + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return True + + def processCharacters(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def startTagCol(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def endTagColgroup(self, token): + if self.ignoreEndTagColgroup(): + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + else: + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + + def endTagCol(self, token): + self.parser.parseError("no-end-tag", {"name": "col"}) + + def endTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + class InTableBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table0 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("tr", self.startTagTr), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead"), + self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "td", "th", + "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableBodyContext(self): + while self.tree.openElements[-1].name not in ("tbody", "tfoot", + "thead", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTr(self, token): + self.clearStackToTableBodyContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inRow"] + + def startTagTableCell(self, token): + self.parser.parseError("unexpected-cell-in-table-body", + {"name": token["name"]}) + self.startTagTr(impliedTagToken("tr", "StartTag")) + return token + + def startTagTableOther(self, token): + # XXX AT Any ideas on how to share this with endTagTable? + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.clearStackToTableBodyContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + else: + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagTable(self, token): + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InRowPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-row + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead", + "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("tr", self.endTagTr), + ("table", self.endTagTable), + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + (("body", "caption", "col", "colgroup", "html", "td", "th"), + self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods (XXX unify this with other table helper methods) + def clearStackToTableRowContext(self): + while self.tree.openElements[-1].name not in ("tr", "html"): + self.parser.parseError("unexpected-implied-end-tag-in-table-row", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + + def ignoreEndTagTr(self): + return not self.tree.elementInScope("tr", variant="table") + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTableCell(self, token): + self.clearStackToTableRowContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCell"] + self.tree.activeFormattingElements.append(Marker) + + def startTagTableOther(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTr(self, token): + if not self.ignoreEndTagTr(): + self.clearStackToTableRowContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTableBody"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # Reprocess the current tag if the tr end tag was not ignored + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagTr(impliedTagToken("tr")) + return token + else: + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-row", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InCellPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-cell + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("td", "th"), self.endTagTableCell), + (("body", "caption", "col", "colgroup", "html"), self.endTagIgnore), + (("table", "tbody", "tfoot", "thead", "tr"), self.endTagImply) + ]) + self.endTagHandler.default = self.endTagOther + + # helper + def closeCell(self): + if self.tree.elementInScope("td", variant="table"): + self.endTagTableCell(impliedTagToken("td")) + elif self.tree.elementInScope("th", variant="table"): + self.endTagTableCell(impliedTagToken("th")) + + # the rest + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableOther(self, token): + if (self.tree.elementInScope("td", variant="table") or + self.tree.elementInScope("th", variant="table")): + self.closeCell() + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagTableCell(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.tree.generateImpliedEndTags(token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-cell-end-tag", + {"name": token["name"]}) + while True: + node = self.tree.openElements.pop() + if node.name == token["name"]: + break + else: + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inRow"] + else: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagImply(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.closeCell() + return token + else: + # sometimes innerHTML case + self.parser.parseError() + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InSelectPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("option", self.startTagOption), + ("optgroup", self.startTagOptgroup), + ("select", self.startTagSelect), + (("input", "keygen", "textarea"), self.startTagInput), + ("script", self.startTagScript) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("option", self.endTagOption), + ("optgroup", self.endTagOptgroup), + ("select", self.endTagSelect) + ]) + self.endTagHandler.default = self.endTagOther + + # http://www.whatwg.org/specs/web-apps/current-work/#in-select + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-select") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.tree.insertText(token["data"]) + + def startTagOption(self, token): + # We need to imply </option> if <option> is the current node. + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagOptgroup(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagSelect(self, token): + self.parser.parseError("unexpected-select-in-select") + self.endTagSelect(impliedTagToken("select")) + + def startTagInput(self, token): + self.parser.parseError("unexpected-input-in-select") + if self.tree.elementInScope("select", variant="select"): + self.endTagSelect(impliedTagToken("select")) + return token + else: + assert self.parser.innerHTML + + def startTagScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-select", + {"name": token["name"]}) + + def endTagOption(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "option"}) + + def endTagOptgroup(self, token): + # </optgroup> implicitly closes <option> + if (self.tree.openElements[-1].name == "option" and + self.tree.openElements[-2].name == "optgroup"): + self.tree.openElements.pop() + # It also closes </optgroup> + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + # But nothing else + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "optgroup"}) + + def endTagSelect(self, token): + if self.tree.elementInScope("select", variant="select"): + node = self.tree.openElements.pop() + while node.name != "select": + node = self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-select", + {"name": token["name"]}) + + class InSelectInTablePhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.startTagTable) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.endTagTable) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.phases["inSelect"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inSelect"].processCharacters(token) + + def startTagTable(self, token): + self.parser.parseError("unexpected-table-element-start-tag-in-select-in-table", {"name": token["name"]}) + self.endTagOther(impliedTagToken("select")) + return token + + def startTagOther(self, token): + return self.parser.phases["inSelect"].processStartTag(token) + + def endTagTable(self, token): + self.parser.parseError("unexpected-table-element-end-tag-in-select-in-table", {"name": token["name"]}) + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagOther(impliedTagToken("select")) + return token + + def endTagOther(self, token): + return self.parser.phases["inSelect"].processEndTag(token) + + class InForeignContentPhase(Phase): + breakoutElements = frozenset(["b", "big", "blockquote", "body", "br", + "center", "code", "dd", "div", "dl", "dt", + "em", "embed", "h1", "h2", "h3", + "h4", "h5", "h6", "head", "hr", "i", "img", + "li", "listing", "menu", "meta", "nobr", + "ol", "p", "pre", "ruby", "s", "small", + "span", "strong", "strike", "sub", "sup", + "table", "tt", "u", "ul", "var"]) + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + def adjustSVGTagNames(self, token): + replacements = {"altglyph": "altGlyph", + "altglyphdef": "altGlyphDef", + "altglyphitem": "altGlyphItem", + "animatecolor": "animateColor", + "animatemotion": "animateMotion", + "animatetransform": "animateTransform", + "clippath": "clipPath", + "feblend": "feBlend", + "fecolormatrix": "feColorMatrix", + "fecomponenttransfer": "feComponentTransfer", + "fecomposite": "feComposite", + "feconvolvematrix": "feConvolveMatrix", + "fediffuselighting": "feDiffuseLighting", + "fedisplacementmap": "feDisplacementMap", + "fedistantlight": "feDistantLight", + "feflood": "feFlood", + "fefunca": "feFuncA", + "fefuncb": "feFuncB", + "fefuncg": "feFuncG", + "fefuncr": "feFuncR", + "fegaussianblur": "feGaussianBlur", + "feimage": "feImage", + "femerge": "feMerge", + "femergenode": "feMergeNode", + "femorphology": "feMorphology", + "feoffset": "feOffset", + "fepointlight": "fePointLight", + "fespecularlighting": "feSpecularLighting", + "fespotlight": "feSpotLight", + "fetile": "feTile", + "feturbulence": "feTurbulence", + "foreignobject": "foreignObject", + "glyphref": "glyphRef", + "lineargradient": "linearGradient", + "radialgradient": "radialGradient", + "textpath": "textPath"} + + if token["name"] in replacements: + token["name"] = replacements[token["name"]] + + def processCharacters(self, token): + if token["data"] == "\u0000": + token["data"] = "\uFFFD" + elif (self.parser.framesetOK and + any(char not in spaceCharacters for char in token["data"])): + self.parser.framesetOK = False + Phase.processCharacters(self, token) + + def processStartTag(self, token): + currentNode = self.tree.openElements[-1] + if (token["name"] in self.breakoutElements or + (token["name"] == "font" and + set(token["data"].keys()) & set(["color", "face", "size"]))): + self.parser.parseError("unexpected-html-element-in-foreign-content", + {"name": token["name"]}) + while (self.tree.openElements[-1].namespace != + self.tree.defaultNamespace and + not self.parser.isHTMLIntegrationPoint(self.tree.openElements[-1]) and + not self.parser.isMathMLTextIntegrationPoint(self.tree.openElements[-1])): + self.tree.openElements.pop() + return token + + else: + if currentNode.namespace == namespaces["mathml"]: + self.parser.adjustMathMLAttributes(token) + elif currentNode.namespace == namespaces["svg"]: + self.adjustSVGTagNames(token) + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = currentNode.namespace + self.tree.insertElement(token) + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def processEndTag(self, token): + nodeIndex = len(self.tree.openElements) - 1 + node = self.tree.openElements[-1] + if node.name.translate(asciiUpper2Lower) != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + while True: + if node.name.translate(asciiUpper2Lower) == token["name"]: + # XXX this isn't in the spec but it seems necessary + if self.parser.phase == self.parser.phases["inTableText"]: + self.parser.phase.flushCharacters() + self.parser.phase = self.parser.phase.originalPhase + while self.tree.openElements.pop() != node: + assert self.tree.openElements + new_token = None + break + nodeIndex -= 1 + + node = self.tree.openElements[nodeIndex] + if node.namespace != self.tree.defaultNamespace: + continue + else: + new_token = self.parser.phase.processEndTag(token) + break + return new_token + + class AfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([("html", self.endTagHtml)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processComment(self, token): + # This is needed because data is to be appended to the <html> element + # here and not to whatever is currently open. + self.tree.insertComment(token, self.tree.openElements[0]) + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-body") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def endTagHtml(self, name): + if self.parser.innerHTML: + self.parser.parseError("unexpected-end-tag-after-body-innerhtml") + else: + self.parser.phase = self.parser.phases["afterAfterBody"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class InFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-frameset + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("frameset", self.startTagFrameset), + ("frame", self.startTagFrame), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("frameset", self.endTagFrameset) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-frameset") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-in-frameset") + + def startTagFrameset(self, token): + self.tree.insertElement(token) + + def startTagFrame(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + + def startTagNoframes(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-frameset", + {"name": token["name"]}) + + def endTagFrameset(self, token): + if self.tree.openElements[-1].name == "html": + # innerHTML case + self.parser.parseError("unexpected-frameset-in-frameset-innerhtml") + else: + self.tree.openElements.pop() + if (not self.parser.innerHTML and + self.tree.openElements[-1].name != "frameset"): + # If we're not in innerHTML mode and the current node is not a + # "frameset" element (anymore) then switch. + self.parser.phase = self.parser.phases["afterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-frameset", + {"name": token["name"]}) + + class AfterFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#after3 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("html", self.endTagHtml) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-frameset") + + def startTagNoframes(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-frameset", + {"name": token["name"]}) + + def endTagHtml(self, token): + self.parser.phase = self.parser.phases["afterAfterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-frameset", + {"name": token["name"]}) + + class AfterAfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class AfterAfterFramesetPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoFrames) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagNoFrames(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + # pylint:enable=unused-argument + + return { + "initial": InitialPhase, + "beforeHtml": BeforeHtmlPhase, + "beforeHead": BeforeHeadPhase, + "inHead": InHeadPhase, + "inHeadNoscript": InHeadNoscriptPhase, + "afterHead": AfterHeadPhase, + "inBody": InBodyPhase, + "text": TextPhase, + "inTable": InTablePhase, + "inTableText": InTableTextPhase, + "inCaption": InCaptionPhase, + "inColumnGroup": InColumnGroupPhase, + "inTableBody": InTableBodyPhase, + "inRow": InRowPhase, + "inCell": InCellPhase, + "inSelect": InSelectPhase, + "inSelectInTable": InSelectInTablePhase, + "inForeignContent": InForeignContentPhase, + "afterBody": AfterBodyPhase, + "inFrameset": InFramesetPhase, + "afterFrameset": AfterFramesetPhase, + "afterAfterBody": AfterAfterBodyPhase, + "afterAfterFrameset": AfterAfterFramesetPhase, + # XXX after after frameset + } + + +def adjust_attributes(token, replacements): + needs_adjustment = viewkeys(token['data']) & viewkeys(replacements) + if needs_adjustment: + token['data'] = OrderedDict((replacements.get(k, k), v) + for k, v in token['data'].items()) + + +def impliedTagToken(name, type="EndTag", attributes=None, + selfClosing=False): + if attributes is None: + attributes = {} + return {"type": tokenTypes[type], "name": name, "data": attributes, + "selfClosing": selfClosing} + + +class ParseError(Exception): + """Error in parsed document""" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/serializer.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/serializer.py new file mode 100644 index 0000000..53f4d44 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/serializer.py @@ -0,0 +1,409 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +import re + +from codecs import register_error, xmlcharrefreplace_errors + +from .constants import voidElements, booleanAttributes, spaceCharacters +from .constants import rcdataElements, entities, xmlEntities +from . import treewalkers, _utils +from xml.sax.saxutils import escape + +_quoteAttributeSpecChars = "".join(spaceCharacters) + "\"'=<>`" +_quoteAttributeSpec = re.compile("[" + _quoteAttributeSpecChars + "]") +_quoteAttributeLegacy = re.compile("[" + _quoteAttributeSpecChars + + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n" + "\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15" + "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20\x2f\x60\xa0\u1680\u180e\u180f\u2000" + "\u2001\u2002\u2003\u2004\u2005\u2006\u2007" + "\u2008\u2009\u200a\u2028\u2029\u202f\u205f" + "\u3000]") + + +_encode_entity_map = {} +_is_ucs4 = len("\U0010FFFF") == 1 +for k, v in list(entities.items()): + # skip multi-character entities + if ((_is_ucs4 and len(v) > 1) or + (not _is_ucs4 and len(v) > 2)): + continue + if v != "&": + if len(v) == 2: + v = _utils.surrogatePairToCodepoint(v) + else: + v = ord(v) + if v not in _encode_entity_map or k.islower(): + # prefer < over < and similarly for &, >, etc. + _encode_entity_map[v] = k + + +def htmlentityreplace_errors(exc): + if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): + res = [] + codepoints = [] + skip = False + for i, c in enumerate(exc.object[exc.start:exc.end]): + if skip: + skip = False + continue + index = i + exc.start + if _utils.isSurrogatePair(exc.object[index:min([exc.end, index + 2])]): + codepoint = _utils.surrogatePairToCodepoint(exc.object[index:index + 2]) + skip = True + else: + codepoint = ord(c) + codepoints.append(codepoint) + for cp in codepoints: + e = _encode_entity_map.get(cp) + if e: + res.append("&") + res.append(e) + if not e.endswith(";"): + res.append(";") + else: + res.append("&#x%s;" % (hex(cp)[2:])) + return ("".join(res), exc.end) + else: + return xmlcharrefreplace_errors(exc) + + +register_error("htmlentityreplace", htmlentityreplace_errors) + + +def serialize(input, tree="etree", encoding=None, **serializer_opts): + """Serializes the input token stream using the specified treewalker + + :arg input: the token stream to serialize + + :arg tree: the treewalker to use + + :arg encoding: the encoding to use + + :arg serializer_opts: any options to pass to the + :py:class:`html5lib.serializer.HTMLSerializer` that gets created + + :returns: the tree serialized as a string + + Example: + + >>> from html5lib.html5parser import parse + >>> from html5lib.serializer import serialize + >>> token_stream = parse('<html><body><p>Hi!</p></body></html>') + >>> serialize(token_stream, omit_optional_tags=False) + '<html><head></head><body><p>Hi!</p></body></html>' + + """ + # XXX: Should we cache this? + walker = treewalkers.getTreeWalker(tree) + s = HTMLSerializer(**serializer_opts) + return s.render(walker(input), encoding) + + +class HTMLSerializer(object): + + # attribute quoting options + quote_attr_values = "legacy" # be secure by default + quote_char = '"' + use_best_quote_char = True + + # tag syntax options + omit_optional_tags = True + minimize_boolean_attributes = True + use_trailing_solidus = False + space_before_trailing_solidus = True + + # escaping options + escape_lt_in_attrs = False + escape_rcdata = False + resolve_entities = True + + # miscellaneous options + alphabetical_attributes = False + inject_meta_charset = True + strip_whitespace = False + sanitize = False + + options = ("quote_attr_values", "quote_char", "use_best_quote_char", + "omit_optional_tags", "minimize_boolean_attributes", + "use_trailing_solidus", "space_before_trailing_solidus", + "escape_lt_in_attrs", "escape_rcdata", "resolve_entities", + "alphabetical_attributes", "inject_meta_charset", + "strip_whitespace", "sanitize") + + def __init__(self, **kwargs): + """Initialize HTMLSerializer + + :arg inject_meta_charset: Whether or not to inject the meta charset. + + Defaults to ``True``. + + :arg quote_attr_values: Whether to quote attribute values that don't + require quoting per legacy browser behavior (``"legacy"``), when + required by the standard (``"spec"``), or always (``"always"``). + + Defaults to ``"legacy"``. + + :arg quote_char: Use given quote character for attribute quoting. + + Defaults to ``"`` which will use double quotes unless attribute + value contains a double quote, in which case single quotes are + used. + + :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute + values. + + Defaults to ``False``. + + :arg escape_rcdata: Whether to escape characters that need to be + escaped within normal elements within rcdata elements such as + style. + + Defaults to ``False``. + + :arg resolve_entities: Whether to resolve named character entities that + appear in the source tree. The XML predefined entities < > + & " ' are unaffected by this setting. + + Defaults to ``True``. + + :arg strip_whitespace: Whether to remove semantically meaningless + whitespace. (This compresses all whitespace to a single space + except within ``pre``.) + + Defaults to ``False``. + + :arg minimize_boolean_attributes: Shortens boolean attributes to give + just the attribute value, for example:: + + <input disabled="disabled"> + + becomes:: + + <input disabled> + + Defaults to ``True``. + + :arg use_trailing_solidus: Includes a close-tag slash at the end of the + start tag of void elements (empty elements whose end tag is + forbidden). E.g. ``<hr/>``. + + Defaults to ``False``. + + :arg space_before_trailing_solidus: Places a space immediately before + the closing slash in a tag using a trailing solidus. E.g. + ``<hr />``. Requires ``use_trailing_solidus=True``. + + Defaults to ``True``. + + :arg sanitize: Strip all unsafe or unknown constructs from output. + See :py:class:`html5lib.filters.sanitizer.Filter`. + + Defaults to ``False``. + + :arg omit_optional_tags: Omit start/end tags that are optional. + + Defaults to ``True``. + + :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. + + Defaults to ``False``. + + """ + unexpected_args = frozenset(kwargs) - frozenset(self.options) + if len(unexpected_args) > 0: + raise TypeError("__init__() got an unexpected keyword argument '%s'" % next(iter(unexpected_args))) + if 'quote_char' in kwargs: + self.use_best_quote_char = False + for attr in self.options: + setattr(self, attr, kwargs.get(attr, getattr(self, attr))) + self.errors = [] + self.strict = False + + def encode(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "htmlentityreplace") + else: + return string + + def encodeStrict(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "strict") + else: + return string + + def serialize(self, treewalker, encoding=None): + # pylint:disable=too-many-nested-blocks + self.encoding = encoding + in_cdata = False + self.errors = [] + + if encoding and self.inject_meta_charset: + from .filters.inject_meta_charset import Filter + treewalker = Filter(treewalker, encoding) + # Alphabetical attributes is here under the assumption that none of + # the later filters add or change order of attributes; it needs to be + # before the sanitizer so escaped elements come out correctly + if self.alphabetical_attributes: + from .filters.alphabeticalattributes import Filter + treewalker = Filter(treewalker) + # WhitespaceFilter should be used before OptionalTagFilter + # for maximum efficiently of this latter filter + if self.strip_whitespace: + from .filters.whitespace import Filter + treewalker = Filter(treewalker) + if self.sanitize: + from .filters.sanitizer import Filter + treewalker = Filter(treewalker) + if self.omit_optional_tags: + from .filters.optionaltags import Filter + treewalker = Filter(treewalker) + + for token in treewalker: + type = token["type"] + if type == "Doctype": + doctype = "<!DOCTYPE %s" % token["name"] + + if token["publicId"]: + doctype += ' PUBLIC "%s"' % token["publicId"] + elif token["systemId"]: + doctype += " SYSTEM" + if token["systemId"]: + if token["systemId"].find('"') >= 0: + if token["systemId"].find("'") >= 0: + self.serializeError("System identifer contains both single and double quote characters") + quote_char = "'" + else: + quote_char = '"' + doctype += " %s%s%s" % (quote_char, token["systemId"], quote_char) + + doctype += ">" + yield self.encodeStrict(doctype) + + elif type in ("Characters", "SpaceCharacters"): + if type == "SpaceCharacters" or in_cdata: + if in_cdata and token["data"].find("</") >= 0: + self.serializeError("Unexpected </ in CDATA") + yield self.encode(token["data"]) + else: + yield self.encode(escape(token["data"])) + + elif type in ("StartTag", "EmptyTag"): + name = token["name"] + yield self.encodeStrict("<%s" % name) + if name in rcdataElements and not self.escape_rcdata: + in_cdata = True + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + for (_, attr_name), attr_value in token["data"].items(): + # TODO: Add namespace support here + k = attr_name + v = attr_value + yield self.encodeStrict(' ') + + yield self.encodeStrict(k) + if not self.minimize_boolean_attributes or \ + (k not in booleanAttributes.get(name, tuple()) and + k not in booleanAttributes.get("", tuple())): + yield self.encodeStrict("=") + if self.quote_attr_values == "always" or len(v) == 0: + quote_attr = True + elif self.quote_attr_values == "spec": + quote_attr = _quoteAttributeSpec.search(v) is not None + elif self.quote_attr_values == "legacy": + quote_attr = _quoteAttributeLegacy.search(v) is not None + else: + raise ValueError("quote_attr_values must be one of: " + "'always', 'spec', or 'legacy'") + v = v.replace("&", "&") + if self.escape_lt_in_attrs: + v = v.replace("<", "<") + if quote_attr: + quote_char = self.quote_char + if self.use_best_quote_char: + if "'" in v and '"' not in v: + quote_char = '"' + elif '"' in v and "'" not in v: + quote_char = "'" + if quote_char == "'": + v = v.replace("'", "'") + else: + v = v.replace('"', """) + yield self.encodeStrict(quote_char) + yield self.encode(v) + yield self.encodeStrict(quote_char) + else: + yield self.encode(v) + if name in voidElements and self.use_trailing_solidus: + if self.space_before_trailing_solidus: + yield self.encodeStrict(" /") + else: + yield self.encodeStrict("/") + yield self.encode(">") + + elif type == "EndTag": + name = token["name"] + if name in rcdataElements: + in_cdata = False + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + yield self.encodeStrict("</%s>" % name) + + elif type == "Comment": + data = token["data"] + if data.find("--") >= 0: + self.serializeError("Comment contains --") + yield self.encodeStrict("<!--%s-->" % token["data"]) + + elif type == "Entity": + name = token["name"] + key = name + ";" + if key not in entities: + self.serializeError("Entity %s not recognized" % name) + if self.resolve_entities and key not in xmlEntities: + data = entities[key] + else: + data = "&%s;" % name + yield self.encodeStrict(data) + + else: + self.serializeError(token["data"]) + + def render(self, treewalker, encoding=None): + """Serializes the stream from the treewalker into a string + + :arg treewalker: the treewalker to serialize + + :arg encoding: the string encoding to use + + :returns: the serialized tree + + Example: + + >>> from html5lib import parse, getTreeWalker + >>> from html5lib.serializer import HTMLSerializer + >>> token_stream = parse('<html><body>Hi!</body></html>') + >>> walker = getTreeWalker('etree') + >>> serializer = HTMLSerializer(omit_optional_tags=False) + >>> serializer.render(walker(token_stream)) + '<html><head></head><body>Hi!</body></html>' + + """ + if encoding: + return b"".join(list(self.serialize(treewalker, encoding))) + else: + return "".join(list(self.serialize(treewalker))) + + def serializeError(self, data="XXX ERROR MESSAGE NEEDED"): + # XXX The idea is to make data mandatory. + self.errors.append(data) + if self.strict: + raise SerializeError + + +class SerializeError(Exception): + """Error in serialized tree""" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py new file mode 100644 index 0000000..7ef5959 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/__init__.py @@ -0,0 +1,30 @@ +"""Tree adapters let you convert from one tree structure to another + +Example: + +.. code-block:: python + + from pip._vendor import html5lib + from pip._vendor.html5lib.treeadapters import genshi + + doc = '<html><body>Hi!</body></html>' + treebuilder = html5lib.getTreeBuilder('etree') + parser = html5lib.HTMLParser(tree=treebuilder) + tree = parser.parse(doc) + TreeWalker = html5lib.getTreeWalker('etree') + + genshi_tree = genshi.to_genshi(TreeWalker(tree)) + +""" +from __future__ import absolute_import, division, unicode_literals + +from . import sax + +__all__ = ["sax"] + +try: + from . import genshi # noqa +except ImportError: + pass +else: + __all__.append("genshi") diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py new file mode 100644 index 0000000..61d5fb6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/genshi.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName, Attrs +from genshi.core import START, END, TEXT, COMMENT, DOCTYPE + + +def to_genshi(walker): + """Convert a tree to a genshi tree + + :arg walker: the treewalker to use to walk the tree to convert it + + :returns: generator of genshi nodes + + """ + text = [] + for token in walker: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + text.append(token["data"]) + elif text: + yield TEXT, "".join(text), (None, -1, -1) + text = [] + + if type in ("StartTag", "EmptyTag"): + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value) + for attr, value in token["data"].items()]) + yield (START, (QName(name), attrs), (None, -1, -1)) + if type == "EmptyTag": + type = "EndTag" + + if type == "EndTag": + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + + yield END, QName(name), (None, -1, -1) + + elif type == "Comment": + yield COMMENT, token["data"], (None, -1, -1) + + elif type == "Doctype": + yield DOCTYPE, (token["name"], token["publicId"], + token["systemId"]), (None, -1, -1) + + else: + pass # FIXME: What to do? + + if text: + yield TEXT, "".join(text), (None, -1, -1) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py new file mode 100644 index 0000000..f4ccea5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treeadapters/sax.py @@ -0,0 +1,50 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.sax.xmlreader import AttributesNSImpl + +from ..constants import adjustForeignAttributes, unadjustForeignAttributes + +prefix_mapping = {} +for prefix, localName, namespace in adjustForeignAttributes.values(): + if prefix is not None: + prefix_mapping[prefix] = namespace + + +def to_sax(walker, handler): + """Call SAX-like content handler based on treewalker walker + + :arg walker: the treewalker to use to walk the tree to convert it + + :arg handler: SAX handler to use + + """ + handler.startDocument() + for prefix, namespace in prefix_mapping.items(): + handler.startPrefixMapping(prefix, namespace) + + for token in walker: + type = token["type"] + if type == "Doctype": + continue + elif type in ("StartTag", "EmptyTag"): + attrs = AttributesNSImpl(token["data"], + unadjustForeignAttributes) + handler.startElementNS((token["namespace"], token["name"]), + token["name"], + attrs) + if type == "EmptyTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type == "EndTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type in ("Characters", "SpaceCharacters"): + handler.characters(token["data"]) + elif type == "Comment": + pass + else: + assert False, "Unknown token type" + + for prefix, namespace in prefix_mapping.items(): + handler.endPrefixMapping(prefix) + handler.endDocument() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py new file mode 100644 index 0000000..d44447e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__init__.py @@ -0,0 +1,88 @@ +"""A collection of modules for building different kinds of trees from HTML +documents. + +To create a treebuilder for a new type of tree, you need to do +implement several things: + +1. A set of classes for various types of elements: Document, Doctype, Comment, + Element. These must implement the interface of ``base.treebuilders.Node`` + (although comment nodes have a different signature for their constructor, + see ``treebuilders.etree.Comment``) Textual content may also be implemented + as another node type, or not, as your tree implementation requires. + +2. A treebuilder object (called ``TreeBuilder`` by convention) that inherits + from ``treebuilders.base.TreeBuilder``. This has 4 required attributes: + + * ``documentClass`` - the class to use for the bottommost node of a document + * ``elementClass`` - the class to use for HTML Elements + * ``commentClass`` - the class to use for comments + * ``doctypeClass`` - the class to use for doctypes + + It also has one required method: + + * ``getDocument`` - Returns the root node of the complete document tree + +3. If you wish to run the unit tests, you must also create a ``testSerializer`` + method on your treebuilder which accepts a node and returns a string + containing Node and its children serialized according to the format used in + the unittests + +""" + +from __future__ import absolute_import, division, unicode_literals + +from .._utils import default_etree + +treeBuilderCache = {} + + +def getTreeBuilder(treeType, implementation=None, **kwargs): + """Get a TreeBuilder class for various types of trees with built-in support + + :arg treeType: the name of the tree type required (case-insensitive). Supported + values are: + + * "dom" - A generic builder for DOM implementations, defaulting to a + xml.dom.minidom based implementation. + * "etree" - A generic builder for tree implementations exposing an + ElementTree-like interface, defaulting to xml.etree.cElementTree if + available and xml.etree.ElementTree if not. + * "lxml" - A etree-based builder for lxml.etree, handling limitations + of lxml's implementation. + + :arg implementation: (Currently applies to the "etree" and "dom" tree + types). A module implementing the tree type e.g. xml.etree.ElementTree + or xml.etree.cElementTree. + + :arg kwargs: Any additional options to pass to the TreeBuilder when + creating it. + + Example: + + >>> from html5lib.treebuilders import getTreeBuilder + >>> builder = getTreeBuilder('etree') + + """ + + treeType = treeType.lower() + if treeType not in treeBuilderCache: + if treeType == "dom": + from . import dom + # Come up with a sane default (pref. from the stdlib) + if implementation is None: + from xml.dom import minidom + implementation = minidom + # NEVER cache here, caching is done in the dom submodule + return dom.getDomModule(implementation, **kwargs).TreeBuilder + elif treeType == "lxml": + from . import etree_lxml + treeBuilderCache[treeType] = etree_lxml.TreeBuilder + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeBuilder + else: + raise ValueError("""Unrecognised treebuilder "%s" """ % treeType) + return treeBuilderCache.get(treeType) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..00cfcaf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000..ae169a3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc new file mode 100644 index 0000000..6a8dec5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py new file mode 100644 index 0000000..73973db --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/base.py @@ -0,0 +1,417 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from ..constants import scopingElements, tableInsertModeElements, namespaces + +# The scope markers are inserted when entering object elements, +# marquees, table cells, and table captions, and are used to prevent formatting +# from "leaking" into tables, object elements, and marquees. +Marker = None + +listElementsMap = { + None: (frozenset(scopingElements), False), + "button": (frozenset(scopingElements | set([(namespaces["html"], "button")])), False), + "list": (frozenset(scopingElements | set([(namespaces["html"], "ol"), + (namespaces["html"], "ul")])), False), + "table": (frozenset([(namespaces["html"], "html"), + (namespaces["html"], "table")]), False), + "select": (frozenset([(namespaces["html"], "optgroup"), + (namespaces["html"], "option")]), True) +} + + +class Node(object): + """Represents an item in the tree""" + def __init__(self, name): + """Creates a Node + + :arg name: The tag name associated with the node + + """ + # The tag name assocaited with the node + self.name = name + # The parent of the current node (or None for the document node) + self.parent = None + # The value of the current node (applies to text nodes and comments) + self.value = None + # A dict holding name -> value pairs for attributes of the node + self.attributes = {} + # A list of child nodes of the current node. This must include all + # elements but not necessarily other node types. + self.childNodes = [] + # A list of miscellaneous flags that can be set on the node. + self._flags = [] + + def __str__(self): + attributesStr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in + self.attributes.items()]) + if attributesStr: + return "<%s %s>" % (self.name, attributesStr) + else: + return "<%s>" % (self.name) + + def __repr__(self): + return "<%s>" % (self.name) + + def appendChild(self, node): + """Insert node as a child of the current node + + :arg node: the node to insert + + """ + raise NotImplementedError + + def insertText(self, data, insertBefore=None): + """Insert data as text in the current node, positioned before the + start of node insertBefore or to the end of the node's text. + + :arg data: the data to insert + + :arg insertBefore: True if you want to insert the text before the node + and False if you want to insert it after the node + + """ + raise NotImplementedError + + def insertBefore(self, node, refNode): + """Insert node as a child of the current node, before refNode in the + list of child nodes. Raises ValueError if refNode is not a child of + the current node + + :arg node: the node to insert + + :arg refNode: the child node to insert the node before + + """ + raise NotImplementedError + + def removeChild(self, node): + """Remove node from the children of the current node + + :arg node: the child node to remove + + """ + raise NotImplementedError + + def reparentChildren(self, newParent): + """Move all the children of the current node to newParent. + This is needed so that trees that don't store text as nodes move the + text in the correct way + + :arg newParent: the node to move all this node's children to + + """ + # XXX - should this method be made more general? + for child in self.childNodes: + newParent.appendChild(child) + self.childNodes = [] + + def cloneNode(self): + """Return a shallow copy of the current node i.e. a node with the same + name and attributes but with no parent or child nodes + """ + raise NotImplementedError + + def hasContent(self): + """Return true if the node has children or text, false otherwise + """ + raise NotImplementedError + + +class ActiveFormattingElements(list): + def append(self, node): + equalCount = 0 + if node != Marker: + for element in self[::-1]: + if element == Marker: + break + if self.nodesEqual(element, node): + equalCount += 1 + if equalCount == 3: + self.remove(element) + break + list.append(self, node) + + def nodesEqual(self, node1, node2): + if not node1.nameTuple == node2.nameTuple: + return False + + if not node1.attributes == node2.attributes: + return False + + return True + + +class TreeBuilder(object): + """Base treebuilder implementation + + * documentClass - the class to use for the bottommost node of a document + * elementClass - the class to use for HTML Elements + * commentClass - the class to use for comments + * doctypeClass - the class to use for doctypes + + """ + # pylint:disable=not-callable + + # Document class + documentClass = None + + # The class to use for creating a node + elementClass = None + + # The class to use for creating comments + commentClass = None + + # The class to use for creating doctypes + doctypeClass = None + + # Fragment class + fragmentClass = None + + def __init__(self, namespaceHTMLElements): + """Create a TreeBuilder + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + """ + if namespaceHTMLElements: + self.defaultNamespace = "http://www.w3.org/1999/xhtml" + else: + self.defaultNamespace = None + self.reset() + + def reset(self): + self.openElements = [] + self.activeFormattingElements = ActiveFormattingElements() + + # XXX - rename these to headElement, formElement + self.headPointer = None + self.formPointer = None + + self.insertFromTable = False + + self.document = self.documentClass() + + def elementInScope(self, target, variant=None): + + # If we pass a node in we match that. if we pass a string + # match any node with that name + exactNode = hasattr(target, "nameTuple") + if not exactNode: + if isinstance(target, text_type): + target = (namespaces["html"], target) + assert isinstance(target, tuple) + + listElements, invert = listElementsMap[variant] + + for node in reversed(self.openElements): + if exactNode and node == target: + return True + elif not exactNode and node.nameTuple == target: + return True + elif (invert ^ (node.nameTuple in listElements)): + return False + + assert False # We should never reach this point + + def reconstructActiveFormattingElements(self): + # Within this algorithm the order of steps described in the + # specification is not quite the same as the order of steps in the + # code. It should still do the same though. + + # Step 1: stop the algorithm when there's nothing to do. + if not self.activeFormattingElements: + return + + # Step 2 and step 3: we start with the last element. So i is -1. + i = len(self.activeFormattingElements) - 1 + entry = self.activeFormattingElements[i] + if entry == Marker or entry in self.openElements: + return + + # Step 6 + while entry != Marker and entry not in self.openElements: + if i == 0: + # This will be reset to 0 below + i = -1 + break + i -= 1 + # Step 5: let entry be one earlier in the list. + entry = self.activeFormattingElements[i] + + while True: + # Step 7 + i += 1 + + # Step 8 + entry = self.activeFormattingElements[i] + clone = entry.cloneNode() # Mainly to get a new copy of the attributes + + # Step 9 + element = self.insertElement({"type": "StartTag", + "name": clone.name, + "namespace": clone.namespace, + "data": clone.attributes}) + + # Step 10 + self.activeFormattingElements[i] = element + + # Step 11 + if element == self.activeFormattingElements[-1]: + break + + def clearActiveFormattingElements(self): + entry = self.activeFormattingElements.pop() + while self.activeFormattingElements and entry != Marker: + entry = self.activeFormattingElements.pop() + + def elementInActiveFormattingElements(self, name): + """Check if an element exists between the end of the active + formatting elements and the last marker. If it does, return it, else + return false""" + + for item in self.activeFormattingElements[::-1]: + # Check for Marker first because if it's a Marker it doesn't have a + # name attribute. + if item == Marker: + break + elif item.name == name: + return item + return False + + def insertRoot(self, token): + element = self.createElement(token) + self.openElements.append(element) + self.document.appendChild(element) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + doctype = self.doctypeClass(name, publicId, systemId) + self.document.appendChild(doctype) + + def insertComment(self, token, parent=None): + if parent is None: + parent = self.openElements[-1] + parent.appendChild(self.commentClass(token["data"])) + + def createElement(self, token): + """Create an element but don't insert it anywhere""" + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + return element + + def _getInsertFromTable(self): + return self._insertFromTable + + def _setInsertFromTable(self, value): + """Switch the function used to insert an element from the + normal one to the misnested table one and back again""" + self._insertFromTable = value + if value: + self.insertElement = self.insertElementTable + else: + self.insertElement = self.insertElementNormal + + insertFromTable = property(_getInsertFromTable, _setInsertFromTable) + + def insertElementNormal(self, token): + name = token["name"] + assert isinstance(name, text_type), "Element %s not unicode" % name + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + self.openElements[-1].appendChild(element) + self.openElements.append(element) + return element + + def insertElementTable(self, token): + """Create an element and insert it into the tree""" + element = self.createElement(token) + if self.openElements[-1].name not in tableInsertModeElements: + return self.insertElementNormal(token) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + if insertBefore is None: + parent.appendChild(element) + else: + parent.insertBefore(element, insertBefore) + self.openElements.append(element) + return element + + def insertText(self, data, parent=None): + """Insert text data.""" + if parent is None: + parent = self.openElements[-1] + + if (not self.insertFromTable or (self.insertFromTable and + self.openElements[-1].name + not in tableInsertModeElements)): + parent.insertText(data) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + parent.insertText(data, insertBefore) + + def getTableMisnestedNodePosition(self): + """Get the foster parent element, and sibling to insert before + (or None) when inserting a misnested table node""" + # The foster parent element is the one which comes before the most + # recently opened table element + # XXX - this is really inelegant + lastTable = None + fosterParent = None + insertBefore = None + for elm in self.openElements[::-1]: + if elm.name == "table": + lastTable = elm + break + if lastTable: + # XXX - we should really check that this parent is actually a + # node here + if lastTable.parent: + fosterParent = lastTable.parent + insertBefore = lastTable + else: + fosterParent = self.openElements[ + self.openElements.index(lastTable) - 1] + else: + fosterParent = self.openElements[0] + return fosterParent, insertBefore + + def generateImpliedEndTags(self, exclude=None): + name = self.openElements[-1].name + # XXX td, th and tr are not actually needed + if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and + name != exclude): + self.openElements.pop() + # XXX This is not entirely what the specification says. We should + # investigate it more closely. + self.generateImpliedEndTags(exclude) + + def getDocument(self): + """Return the final tree""" + return self.document + + def getFragment(self): + """Return the final fragment""" + # assert self.innerHTML + fragment = self.fragmentClass() + self.openElements[0].reparentChildren(fragment) + return fragment + + def testSerializer(self, node): + """Serialize the subtree of node in the format required by unit tests + + :arg node: the node from which to start serializing + + """ + raise NotImplementedError diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py new file mode 100644 index 0000000..dcfac22 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/dom.py @@ -0,0 +1,236 @@ +from __future__ import absolute_import, division, unicode_literals + + +from collections import MutableMapping +from xml.dom import minidom, Node +import weakref + +from . import base +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + + +def getDomBuilder(DomImplementation): + Dom = DomImplementation + + class AttrList(MutableMapping): + def __init__(self, element): + self.element = element + + def __iter__(self): + return iter(self.element.attributes.keys()) + + def __setitem__(self, name, value): + if isinstance(name, tuple): + raise NotImplementedError + else: + attr = self.element.ownerDocument.createAttribute(name) + attr.value = value + self.element.attributes[name] = attr + + def __len__(self): + return len(self.element.attributes) + + def items(self): + return list(self.element.attributes.items()) + + def values(self): + return list(self.element.attributes.values()) + + def __getitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + return self.element.attributes[name].value + + def __delitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + del self.element.attributes[name] + + class NodeBuilder(base.Node): + def __init__(self, element): + base.Node.__init__(self, element.nodeName) + self.element = element + + namespace = property(lambda self: hasattr(self.element, "namespaceURI") and + self.element.namespaceURI or None) + + def appendChild(self, node): + node.parent = self + self.element.appendChild(node.element) + + def insertText(self, data, insertBefore=None): + text = self.element.ownerDocument.createTextNode(data) + if insertBefore: + self.element.insertBefore(text, insertBefore.element) + else: + self.element.appendChild(text) + + def insertBefore(self, node, refNode): + self.element.insertBefore(node.element, refNode.element) + node.parent = self + + def removeChild(self, node): + if node.element.parentNode == self.element: + self.element.removeChild(node.element) + node.parent = None + + def reparentChildren(self, newParent): + while self.element.hasChildNodes(): + child = self.element.firstChild + self.element.removeChild(child) + newParent.element.appendChild(child) + self.childNodes = [] + + def getAttributes(self): + return AttrList(self.element) + + def setAttributes(self, attributes): + if attributes: + for name, value in list(attributes.items()): + if isinstance(name, tuple): + if name[0] is not None: + qualifiedName = (name[0] + ":" + name[1]) + else: + qualifiedName = name[1] + self.element.setAttributeNS(name[2], qualifiedName, + value) + else: + self.element.setAttribute( + name, value) + attributes = property(getAttributes, setAttributes) + + def cloneNode(self): + return NodeBuilder(self.element.cloneNode(False)) + + def hasContent(self): + return self.element.hasChildNodes() + + def getNameTuple(self): + if self.namespace is None: + return namespaces["html"], self.name + else: + return self.namespace, self.name + + nameTuple = property(getNameTuple) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + def documentClass(self): + self.dom = Dom.getDOMImplementation().createDocument(None, None, None) + return weakref.proxy(self) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + domimpl = Dom.getDOMImplementation() + doctype = domimpl.createDocumentType(name, publicId, systemId) + self.document.appendChild(NodeBuilder(doctype)) + if Dom == minidom: + doctype.ownerDocument = self.dom + + def elementClass(self, name, namespace=None): + if namespace is None and self.defaultNamespace is None: + node = self.dom.createElement(name) + else: + node = self.dom.createElementNS(namespace, name) + + return NodeBuilder(node) + + def commentClass(self, data): + return NodeBuilder(self.dom.createComment(data)) + + def fragmentClass(self): + return NodeBuilder(self.dom.createDocumentFragment()) + + def appendChild(self, node): + self.dom.appendChild(node.element) + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + return self.dom + + def getFragment(self): + return base.TreeBuilder.getFragment(self).element + + def insertText(self, data, parent=None): + data = data + if parent != self: + base.TreeBuilder.insertText(self, data, parent) + else: + # HACK: allow text nodes as children of the document node + if hasattr(self.dom, '_child_node_types'): + # pylint:disable=protected-access + if Node.TEXT_NODE not in self.dom._child_node_types: + self.dom._child_node_types = list(self.dom._child_node_types) + self.dom._child_node_types.append(Node.TEXT_NODE) + self.dom.appendChild(self.dom.createTextNode(data)) + + implementation = DomImplementation + name = None + + def testSerializer(element): + element.normalize() + rv = [] + + def serializeElement(element, indent=0): + if element.nodeType == Node.DOCUMENT_TYPE_NODE: + if element.name: + if element.publicId or element.systemId: + publicId = element.publicId or "" + systemId = element.systemId or "" + rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" % + (' ' * indent, element.name, publicId, systemId)) + else: + rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name)) + else: + rv.append("|%s<!DOCTYPE >" % (' ' * indent,)) + elif element.nodeType == Node.DOCUMENT_NODE: + rv.append("#document") + elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE: + rv.append("#document-fragment") + elif element.nodeType == Node.COMMENT_NODE: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue)) + elif element.nodeType == Node.TEXT_NODE: + rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue)) + else: + if (hasattr(element, "namespaceURI") and + element.namespaceURI is not None): + name = "%s %s" % (constants.prefixes[element.namespaceURI], + element.nodeName) + else: + name = element.nodeName + rv.append("|%s<%s>" % (' ' * indent, name)) + if element.hasAttributes(): + attributes = [] + for i in range(len(element.attributes)): + attr = element.attributes.item(i) + name = attr.nodeName + value = attr.value + ns = attr.namespaceURI + if ns: + name = "%s %s" % (constants.prefixes[ns], attr.localName) + else: + name = attr.nodeName + attributes.append((name, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + indent += 2 + for child in element.childNodes: + serializeElement(child, indent) + serializeElement(element, 0) + + return "\n".join(rv) + + return locals() + + +# The actual means to get a module! +getDomModule = moduleFactoryFactory(getDomBuilder) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py new file mode 100644 index 0000000..0dedf44 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree.py @@ -0,0 +1,340 @@ +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +from pip._vendor.six import text_type + +import re + +from . import base +from .. import _ihatexml +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation, fullTree=False): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class Element(base.Node): + def __init__(self, name, namespace=None): + self._name = name + self._namespace = namespace + self._element = ElementTree.Element(self._getETreeTag(name, + namespace)) + if namespace is None: + self.nameTuple = namespaces["html"], self._name + else: + self.nameTuple = self._namespace, self._name + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getETreeTag(self, name, namespace): + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + return etree_tag + + def _setName(self, name): + self._name = name + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getName(self): + return self._name + + name = property(_getName, _setName) + + def _setNamespace(self, namespace): + self._namespace = namespace + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getNamespace(self): + return self._namespace + + namespace = property(_getNamespace, _setNamespace) + + def _getAttributes(self): + return self._element.attrib + + def _setAttributes(self, attributes): + # Delete existing attributes first + # XXX - there may be a better way to do this... + for key in list(self._element.attrib.keys()): + del self._element.attrib[key] + for key, value in attributes.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], key[1]) + else: + name = key + self._element.set(name, value) + + attributes = property(_getAttributes, _setAttributes) + + def _getChildNodes(self): + return self._childNodes + + def _setChildNodes(self, value): + del self._element[:] + self._childNodes = [] + for element in value: + self.insertChild(element) + + childNodes = property(_getChildNodes, _setChildNodes) + + def hasContent(self): + """Return true if the node has children or text""" + return bool(self._element.text or len(self._element)) + + def appendChild(self, node): + self._childNodes.append(node) + self._element.append(node._element) + node.parent = self + + def insertBefore(self, node, refNode): + index = list(self._element).index(refNode._element) + self._element.insert(index, node._element) + node.parent = self + + def removeChild(self, node): + self._childNodes.remove(node) + self._element.remove(node._element) + node.parent = None + + def insertText(self, data, insertBefore=None): + if not(len(self._element)): + if not self._element.text: + self._element.text = "" + self._element.text += data + elif insertBefore is None: + # Insert the text as the tail of the last child element + if not self._element[-1].tail: + self._element[-1].tail = "" + self._element[-1].tail += data + else: + # Insert the text before the specified node + children = list(self._element) + index = children.index(insertBefore._element) + if index > 0: + if not self._element[index - 1].tail: + self._element[index - 1].tail = "" + self._element[index - 1].tail += data + else: + if not self._element.text: + self._element.text = "" + self._element.text += data + + def cloneNode(self): + element = type(self)(self.name, self.namespace) + for name, value in self.attributes.items(): + element.attributes[name] = value + return element + + def reparentChildren(self, newParent): + if newParent.childNodes: + newParent.childNodes[-1]._element.tail += self._element.text + else: + if not newParent._element.text: + newParent._element.text = "" + if self._element.text is not None: + newParent._element.text += self._element.text + self._element.text = "" + base.Node.reparentChildren(self, newParent) + + class Comment(Element): + def __init__(self, data): + # Use the superclass constructor to set all properties on the + # wrapper element + self._element = ElementTree.Comment(data) + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getData(self): + return self._element.text + + def _setData(self, value): + self._element.text = value + + data = property(_getData, _setData) + + class DocumentType(Element): + def __init__(self, name, publicId, systemId): + Element.__init__(self, "<!DOCTYPE>") + self._element.text = name + self.publicId = publicId + self.systemId = systemId + + def _getPublicId(self): + return self._element.get("publicId", "") + + def _setPublicId(self, value): + if value is not None: + self._element.set("publicId", value) + + publicId = property(_getPublicId, _setPublicId) + + def _getSystemId(self): + return self._element.get("systemId", "") + + def _setSystemId(self, value): + if value is not None: + self._element.set("systemId", value) + + systemId = property(_getSystemId, _setSystemId) + + class Document(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_ROOT") + + class DocumentFragment(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_FRAGMENT") + + def testSerializer(element): + rv = [] + + def serializeElement(element, indent=0): + if not(hasattr(element, "tag")): + element = element.getroot() + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + rv.append("#document") + if element.text is not None: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + elif element.tag == ElementTreeCommentType: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + else: + assert isinstance(element.tag, text_type), \ + "Expected unicode, got %s, %s" % (type(element.tag), element.tag) + nsmatch = tag_regexp.match(element.tag) + + if nsmatch is None: + name = element.tag + else: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + name = "%s %s" % (prefix, name) + rv.append("|%s<%s>" % (' ' * indent, name)) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = name + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + def tostring(element): # pylint:disable=unused-variable + """Serialize an element and its child nodes to a string""" + rv = [] + filter = _ihatexml.InfosetFilter() + + def serializeElement(element): + if isinstance(element, ElementTree.ElementTree): + element = element.getroot() + + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + if element.text is not None: + rv.append(element.text) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + + for child in element: + serializeElement(child) + + elif element.tag == ElementTreeCommentType: + rv.append("<!--%s-->" % (element.text,)) + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (filter.fromXmlName(element.tag),)) + else: + attr = " ".join(["%s=\"%s\"" % ( + filter.fromXmlName(name), value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + documentClass = Document + doctypeClass = DocumentType + elementClass = Element + commentClass = Comment + fragmentClass = DocumentFragment + implementation = ElementTreeImplementation + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._element + else: + if self.defaultNamespace is not None: + return self.document._element.find( + "{%s}html" % self.defaultNamespace) + else: + return self.document._element.find("html") + + def getFragment(self): + return base.TreeBuilder.getFragment(self)._element + + return locals() + + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py new file mode 100644 index 0000000..ca12a99 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treebuilders/etree_lxml.py @@ -0,0 +1,366 @@ +"""Module for supporting the lxml.etree library. The idea here is to use as much +of the native library as possible, without using fragile hacks like custom element +names that break between releases. The downside of this is that we cannot represent +all possible trees; specifically the following are known to cause problems: + +Text or comments as siblings of the root element +Docypes with no name + +When any of these things occur, we emit a DataLossWarning +""" + +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +import warnings +import re +import sys + +from . import base +from ..constants import DataLossWarning +from .. import constants +from . import etree as etree_builders +from .. import _ihatexml + +import lxml.etree as etree + + +fullTree = True +tag_regexp = re.compile("{([^}]*)}(.*)") + +comment_type = etree.Comment("asd").tag + + +class DocumentType(object): + def __init__(self, name, publicId, systemId): + self.name = name + self.publicId = publicId + self.systemId = systemId + + +class Document(object): + def __init__(self): + self._elementTree = None + self._childNodes = [] + + def appendChild(self, element): + self._elementTree.getroot().addnext(element._element) + + def _getChildNodes(self): + return self._childNodes + + childNodes = property(_getChildNodes) + + +def testSerializer(element): + rv = [] + infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + + def serializeElement(element, indent=0): + if not hasattr(element, "tag"): + if hasattr(element, "getroot"): + # Full tree case + rv.append("#document") + if element.docinfo.internalDTD: + if not (element.docinfo.public_id or + element.docinfo.system_url): + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + else: + dtd_str = """<!DOCTYPE %s "%s" "%s">""" % ( + element.docinfo.root_name, + element.docinfo.public_id, + element.docinfo.system_url) + rv.append("|%s%s" % (' ' * (indent + 2), dtd_str)) + next_element = element.getroot() + while next_element.getprevious() is not None: + next_element = next_element.getprevious() + while next_element is not None: + serializeElement(next_element, indent + 2) + next_element = next_element.getnext() + elif isinstance(element, str) or isinstance(element, bytes): + # Text in a fragment + assert isinstance(element, str) or sys.version_info[0] == 2 + rv.append("|%s\"%s\"" % (' ' * indent, element)) + else: + # Fragment case + rv.append("#document-fragment") + for next_element in element: + serializeElement(next_element, indent + 2) + elif element.tag == comment_type: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * indent, element.tail)) + else: + assert isinstance(element, etree._Element) + nsmatch = etree_builders.tag_regexp.match(element.tag) + if nsmatch is not None: + ns = nsmatch.group(1) + tag = nsmatch.group(2) + prefix = constants.prefixes[ns] + rv.append("|%s<%s %s>" % (' ' * indent, prefix, + infosetFilter.fromXmlName(tag))) + else: + rv.append("|%s<%s>" % (' ' * indent, + infosetFilter.fromXmlName(element.tag))) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + name = infosetFilter.fromXmlName(name) + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = infosetFilter.fromXmlName(name) + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + +def tostring(element): + """Serialize an element and its child nodes to a string""" + rv = [] + + def serializeElement(element): + if not hasattr(element, "tag"): + if element.docinfo.internalDTD: + if element.docinfo.doctype: + dtd_str = element.docinfo.doctype + else: + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + rv.append(dtd_str) + serializeElement(element.getroot()) + + elif element.tag == comment_type: + rv.append("<!--%s-->" % (element.text,)) + + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (element.tag,)) + else: + attr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if hasattr(element, "tail") and element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + +class TreeBuilder(base.TreeBuilder): + documentClass = Document + doctypeClass = DocumentType + elementClass = None + commentClass = None + fragmentClass = Document + implementation = etree + + def __init__(self, namespaceHTMLElements, fullTree=False): + builder = etree_builders.getETreeModule(etree, fullTree=fullTree) + infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + self.namespaceHTMLElements = namespaceHTMLElements + + class Attributes(dict): + def __init__(self, element, value=None): + if value is None: + value = {} + self._element = element + dict.__init__(self, value) # pylint:disable=non-parent-init-called + for key, value in self.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + def __setitem__(self, key, value): + dict.__setitem__(self, key, value) + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + class Element(builder.Element): + def __init__(self, name, namespace): + name = infosetFilter.coerceElement(name) + builder.Element.__init__(self, name, namespace=namespace) + self._attributes = Attributes(self) + + def _setName(self, name): + self._name = infosetFilter.coerceElement(name) + self._element.tag = self._getETreeTag( + self._name, self._namespace) + + def _getName(self): + return infosetFilter.fromXmlName(self._name) + + name = property(_getName, _setName) + + def _getAttributes(self): + return self._attributes + + def _setAttributes(self, attributes): + self._attributes = Attributes(self, attributes) + + attributes = property(_getAttributes, _setAttributes) + + def insertText(self, data, insertBefore=None): + data = infosetFilter.coerceCharacters(data) + builder.Element.insertText(self, data, insertBefore) + + def appendChild(self, child): + builder.Element.appendChild(self, child) + + class Comment(builder.Comment): + def __init__(self, data): + data = infosetFilter.coerceComment(data) + builder.Comment.__init__(self, data) + + def _setData(self, data): + data = infosetFilter.coerceComment(data) + self._element.text = data + + def _getData(self): + return self._element.text + + data = property(_getData, _setData) + + self.elementClass = Element + self.commentClass = Comment + # self.fragmentClass = builder.DocumentFragment + base.TreeBuilder.__init__(self, namespaceHTMLElements) + + def reset(self): + base.TreeBuilder.reset(self) + self.insertComment = self.insertCommentInitial + self.initial_comments = [] + self.doctype = None + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._elementTree + else: + return self.document._elementTree.getroot() + + def getFragment(self): + fragment = [] + element = self.openElements[0]._element + if element.text: + fragment.append(element.text) + fragment.extend(list(element)) + if element.tail: + fragment.append(element.tail) + return fragment + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + if not name: + warnings.warn("lxml cannot represent empty doctype", DataLossWarning) + self.doctype = None + else: + coercedName = self.infosetFilter.coerceElement(name) + if coercedName != name: + warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning) + + doctype = self.doctypeClass(coercedName, publicId, systemId) + self.doctype = doctype + + def insertCommentInitial(self, data, parent=None): + assert parent is None or parent is self.document + assert self.document._elementTree is None + self.initial_comments.append(data) + + def insertCommentMain(self, data, parent=None): + if (parent == self.document and + self.document._elementTree.getroot()[-1].tag == comment_type): + warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning) + super(TreeBuilder, self).insertComment(data, parent) + + def insertRoot(self, token): + # Because of the way libxml2 works, it doesn't seem to be possible to + # alter information like the doctype after the tree has been parsed. + # Therefore we need to use the built-in parser to create our initial + # tree, after which we can add elements like normal + docStr = "" + if self.doctype: + assert self.doctype.name + docStr += "<!DOCTYPE %s" % self.doctype.name + if (self.doctype.publicId is not None or + self.doctype.systemId is not None): + docStr += (' PUBLIC "%s" ' % + (self.infosetFilter.coercePubid(self.doctype.publicId or ""))) + if self.doctype.systemId: + sysid = self.doctype.systemId + if sysid.find("'") >= 0 and sysid.find('"') >= 0: + warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning) + sysid = sysid.replace("'", 'U00027') + if sysid.find("'") >= 0: + docStr += '"%s"' % sysid + else: + docStr += "'%s'" % sysid + else: + docStr += "''" + docStr += ">" + if self.doctype.name != token["name"]: + warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning) + docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>" + root = etree.fromstring(docStr) + + # Append the initial comments: + for comment_token in self.initial_comments: + comment = self.commentClass(comment_token["data"]) + root.addprevious(comment._element) + + # Create the root document and add the ElementTree to it + self.document = self.documentClass() + self.document._elementTree = root.getroottree() + + # Give the root element the right name + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + root.tag = etree_tag + + # Add the root element to the internal child/open data structures + root_element = self.elementClass(name, namespace) + root_element._element = root + self.document._childNodes.append(root_element) + self.openElements.append(root_element) + + # Reset to the default insert comment function + self.insertComment = self.insertCommentMain diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py new file mode 100644 index 0000000..9bec207 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__init__.py @@ -0,0 +1,154 @@ +"""A collection of modules for iterating through different kinds of +tree, generating tokens identical to those produced by the tokenizer +module. + +To create a tree walker for a new type of tree, you need to do +implement a tree walker object (called TreeWalker by convention) that +implements a 'serialize' method taking a tree as sole argument and +returning an iterator generating tokens. +""" + +from __future__ import absolute_import, division, unicode_literals + +from .. import constants +from .._utils import default_etree + +__all__ = ["getTreeWalker", "pprint"] + +treeWalkerCache = {} + + +def getTreeWalker(treeType, implementation=None, **kwargs): + """Get a TreeWalker class for various types of tree with built-in support + + :arg str treeType: the name of the tree type required (case-insensitive). + Supported values are: + + * "dom": The xml.dom.minidom DOM implementation + * "etree": A generic walker for tree implementations exposing an + elementtree-like interface (known to work with ElementTree, + cElementTree and lxml.etree). + * "lxml": Optimized walker for lxml.etree + * "genshi": a Genshi stream + + :arg implementation: A module implementing the tree type e.g. + xml.etree.ElementTree or cElementTree (Currently applies to the "etree" + tree type only). + + :arg kwargs: keyword arguments passed to the etree walker--for other + walkers, this has no effect + + :returns: a TreeWalker class + + """ + + treeType = treeType.lower() + if treeType not in treeWalkerCache: + if treeType == "dom": + from . import dom + treeWalkerCache[treeType] = dom.TreeWalker + elif treeType == "genshi": + from . import genshi + treeWalkerCache[treeType] = genshi.TreeWalker + elif treeType == "lxml": + from . import etree_lxml + treeWalkerCache[treeType] = etree_lxml.TreeWalker + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # XXX: NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeWalker + return treeWalkerCache.get(treeType) + + +def concatenateCharacterTokens(tokens): + pendingCharacters = [] + for token in tokens: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + pendingCharacters.append(token["data"]) + else: + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + pendingCharacters = [] + yield token + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + + +def pprint(walker): + """Pretty printer for tree walkers + + Takes a TreeWalker instance and pretty prints the output of walking the tree. + + :arg walker: a TreeWalker instance + + """ + output = [] + indent = 0 + for token in concatenateCharacterTokens(walker): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + # tag name + if token["namespace"] and token["namespace"] != constants.namespaces["html"]: + if token["namespace"] in constants.prefixes: + ns = constants.prefixes[token["namespace"]] + else: + ns = token["namespace"] + name = "%s %s" % (ns, token["name"]) + else: + name = token["name"] + output.append("%s<%s>" % (" " * indent, name)) + indent += 2 + # attributes (sorted for consistent ordering) + attrs = token["data"] + for (namespace, localname), value in sorted(attrs.items()): + if namespace: + if namespace in constants.prefixes: + ns = constants.prefixes[namespace] + else: + ns = namespace + name = "%s %s" % (ns, localname) + else: + name = localname + output.append("%s%s=\"%s\"" % (" " * indent, name, value)) + # self-closing + if type == "EmptyTag": + indent -= 2 + + elif type == "EndTag": + indent -= 2 + + elif type == "Comment": + output.append("%s<!-- %s -->" % (" " * indent, token["data"])) + + elif type == "Doctype": + if token["name"]: + if token["publicId"]: + output.append("""%s<!DOCTYPE %s "%s" "%s">""" % + (" " * indent, + token["name"], + token["publicId"], + token["systemId"] if token["systemId"] else "")) + elif token["systemId"]: + output.append("""%s<!DOCTYPE %s "" "%s">""" % + (" " * indent, + token["name"], + token["systemId"])) + else: + output.append("%s<!DOCTYPE %s>" % (" " * indent, + token["name"])) + else: + output.append("%s<!DOCTYPE >" % (" " * indent,)) + + elif type == "Characters": + output.append("%s\"%s\"" % (" " * indent, token["data"])) + + elif type == "SpaceCharacters": + assert False, "concatenateCharacterTokens should have got rid of all Space tokens" + + else: + raise ValueError("Unknown token type, %s" % type) + + return "\n".join(output) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..a352ddb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py new file mode 100644 index 0000000..80c474c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/base.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node +from ..constants import namespaces, voidElements, spaceCharacters + +__all__ = ["DOCUMENT", "DOCTYPE", "TEXT", "ELEMENT", "COMMENT", "ENTITY", "UNKNOWN", + "TreeWalker", "NonRecursiveTreeWalker"] + +DOCUMENT = Node.DOCUMENT_NODE +DOCTYPE = Node.DOCUMENT_TYPE_NODE +TEXT = Node.TEXT_NODE +ELEMENT = Node.ELEMENT_NODE +COMMENT = Node.COMMENT_NODE +ENTITY = Node.ENTITY_NODE +UNKNOWN = "<#UNKNOWN#>" + +spaceCharacters = "".join(spaceCharacters) + + +class TreeWalker(object): + """Walks a tree yielding tokens + + Tokens are dicts that all have a ``type`` field specifying the type of the + token. + + """ + def __init__(self, tree): + """Creates a TreeWalker + + :arg tree: the tree to walk + + """ + self.tree = tree + + def __iter__(self): + raise NotImplementedError + + def error(self, msg): + """Generates an error token with the given message + + :arg msg: the error message + + :returns: SerializeError token + + """ + return {"type": "SerializeError", "data": msg} + + def emptyTag(self, namespace, name, attrs, hasChildren=False): + """Generates an EmptyTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :arg hasChildren: whether or not to yield a SerializationError because + this tag shouldn't have children + + :returns: EmptyTag token + + """ + yield {"type": "EmptyTag", "name": name, + "namespace": namespace, + "data": attrs} + if hasChildren: + yield self.error("Void element has children") + + def startTag(self, namespace, name, attrs): + """Generates a StartTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :returns: StartTag token + + """ + return {"type": "StartTag", + "name": name, + "namespace": namespace, + "data": attrs} + + def endTag(self, namespace, name): + """Generates an EndTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :returns: EndTag token + + """ + return {"type": "EndTag", + "name": name, + "namespace": namespace} + + def text(self, data): + """Generates SpaceCharacters and Characters tokens + + Depending on what's in the data, this generates one or more + ``SpaceCharacters`` and ``Characters`` tokens. + + For example: + + >>> from html5lib.treewalkers.base import TreeWalker + >>> # Give it an empty tree just so it instantiates + >>> walker = TreeWalker([]) + >>> list(walker.text('')) + [] + >>> list(walker.text(' ')) + [{u'data': ' ', u'type': u'SpaceCharacters'}] + >>> list(walker.text(' abc ')) # doctest: +NORMALIZE_WHITESPACE + [{u'data': ' ', u'type': u'SpaceCharacters'}, + {u'data': u'abc', u'type': u'Characters'}, + {u'data': u' ', u'type': u'SpaceCharacters'}] + + :arg data: the text data + + :returns: one or more ``SpaceCharacters`` and ``Characters`` tokens + + """ + data = data + middle = data.lstrip(spaceCharacters) + left = data[:len(data) - len(middle)] + if left: + yield {"type": "SpaceCharacters", "data": left} + data = middle + middle = data.rstrip(spaceCharacters) + right = data[len(middle):] + if middle: + yield {"type": "Characters", "data": middle} + if right: + yield {"type": "SpaceCharacters", "data": right} + + def comment(self, data): + """Generates a Comment token + + :arg data: the comment + + :returns: Comment token + + """ + return {"type": "Comment", "data": data} + + def doctype(self, name, publicId=None, systemId=None): + """Generates a Doctype token + + :arg name: + + :arg publicId: + + :arg systemId: + + :returns: the Doctype token + + """ + return {"type": "Doctype", + "name": name, + "publicId": publicId, + "systemId": systemId} + + def entity(self, name): + """Generates an Entity token + + :arg name: the entity name + + :returns: an Entity token + + """ + return {"type": "Entity", "name": name} + + def unknown(self, nodeType): + """Handles unknown node types""" + return self.error("Unknown node type: " + nodeType) + + +class NonRecursiveTreeWalker(TreeWalker): + def getNodeDetails(self, node): + raise NotImplementedError + + def getFirstChild(self, node): + raise NotImplementedError + + def getNextSibling(self, node): + raise NotImplementedError + + def getParentNode(self, node): + raise NotImplementedError + + def __iter__(self): + currentNode = self.tree + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + hasChildren = False + + if type == DOCTYPE: + yield self.doctype(*details) + + elif type == TEXT: + for token in self.text(*details): + yield token + + elif type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + for token in self.emptyTag(namespace, name, attributes, + hasChildren): + yield token + hasChildren = False + else: + yield self.startTag(namespace, name, attributes) + + elif type == COMMENT: + yield self.comment(details[0]) + + elif type == ENTITY: + yield self.entity(details[0]) + + elif type == DOCUMENT: + hasChildren = True + + else: + yield self.unknown(details[0]) + + if hasChildren: + firstChild = self.getFirstChild(currentNode) + else: + firstChild = None + + if firstChild is not None: + currentNode = firstChild + else: + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + if type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (namespace and namespace != namespaces["html"]) or name not in voidElements: + yield self.endTag(namespace, name) + if self.tree is currentNode: + currentNode = None + break + nextSibling = self.getNextSibling(currentNode) + if nextSibling is not None: + currentNode = nextSibling + break + else: + currentNode = self.getParentNode(currentNode) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py new file mode 100644 index 0000000..b0c89b0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/dom.py @@ -0,0 +1,43 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node + +from . import base + + +class TreeWalker(base.NonRecursiveTreeWalker): + def getNodeDetails(self, node): + if node.nodeType == Node.DOCUMENT_TYPE_NODE: + return base.DOCTYPE, node.name, node.publicId, node.systemId + + elif node.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + return base.TEXT, node.nodeValue + + elif node.nodeType == Node.ELEMENT_NODE: + attrs = {} + for attr in list(node.attributes.keys()): + attr = node.getAttributeNode(attr) + if attr.namespaceURI: + attrs[(attr.namespaceURI, attr.localName)] = attr.value + else: + attrs[(None, attr.name)] = attr.value + return (base.ELEMENT, node.namespaceURI, node.nodeName, + attrs, node.hasChildNodes()) + + elif node.nodeType == Node.COMMENT_NODE: + return base.COMMENT, node.nodeValue + + elif node.nodeType in (Node.DOCUMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE): + return (base.DOCUMENT,) + + else: + return base.UNKNOWN, node.nodeType + + def getFirstChild(self, node): + return node.firstChild + + def getNextSibling(self, node): + return node.nextSibling + + def getParentNode(self, node): + return node.parentNode diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py new file mode 100644 index 0000000..95fc0c1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree.py @@ -0,0 +1,130 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import OrderedDict +import re + +from pip._vendor.six import string_types + +from . import base +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class TreeWalker(base.NonRecursiveTreeWalker): # pylint:disable=unused-variable + """Given the particular ElementTree representation, this implementation, + to avoid using recursion, returns "nodes" as tuples with the following + content: + + 1. The current element + + 2. The index of the element relative to its parent + + 3. A stack of ancestor elements + + 4. A flag "text", "tail" or None to indicate if the current node is a + text node; either the text or tail of the current element (1) + """ + def getNodeDetails(self, node): + if isinstance(node, tuple): # It might be the root Element + elt, _, _, flag = node + if flag in ("text", "tail"): + return base.TEXT, getattr(elt, flag) + else: + node = elt + + if not(hasattr(node, "tag")): + node = node.getroot() + + if node.tag in ("DOCUMENT_ROOT", "DOCUMENT_FRAGMENT"): + return (base.DOCUMENT,) + + elif node.tag == "<!DOCTYPE>": + return (base.DOCTYPE, node.text, + node.get("publicId"), node.get("systemId")) + + elif node.tag == ElementTreeCommentType: + return base.COMMENT, node.text + + else: + assert isinstance(node.tag, string_types), type(node.tag) + # This is assumed to be an ordinary element + match = tag_regexp.match(node.tag) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = node.tag + attrs = OrderedDict() + for name, value in list(node.attrib.items()): + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, tag, + attrs, len(node) or node.text) + + def getFirstChild(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + element, key, parents, flag = node, None, [], None + + if flag in ("text", "tail"): + return None + else: + if element.text: + return element, key, parents, "text" + elif len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + + def getNextSibling(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + else: + if element.tail and flag != "tail": + return element, key, parents, "tail" + elif key < len(parents[-1]) - 1: + return parents[-1][key + 1], key + 1, parents, None + else: + return None + + def getParentNode(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if not parents: + return element + else: + return element, key, parents, None + else: + parent = parents.pop() + if not parents: + return parent + else: + assert list(parents[-1]).count(parent) == 1 + return parent, list(parents[-1]).index(parent), parents, None + + return locals() + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py new file mode 100644 index 0000000..e81ddf3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/etree_lxml.py @@ -0,0 +1,213 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from lxml import etree +from ..treebuilders.etree import tag_regexp + +from . import base + +from .. import _ihatexml + + +def ensure_str(s): + if s is None: + return None + elif isinstance(s, text_type): + return s + else: + return s.decode("ascii", "strict") + + +class Root(object): + def __init__(self, et): + self.elementtree = et + self.children = [] + + try: + if et.docinfo.internalDTD: + self.children.append(Doctype(self, + ensure_str(et.docinfo.root_name), + ensure_str(et.docinfo.public_id), + ensure_str(et.docinfo.system_url))) + except AttributeError: + pass + + try: + node = et.getroot() + except AttributeError: + node = et + + while node.getprevious() is not None: + node = node.getprevious() + while node is not None: + self.children.append(node) + node = node.getnext() + + self.text = None + self.tail = None + + def __getitem__(self, key): + return self.children[key] + + def getnext(self): + return None + + def __len__(self): + return 1 + + +class Doctype(object): + def __init__(self, root_node, name, public_id, system_id): + self.root_node = root_node + self.name = name + self.public_id = public_id + self.system_id = system_id + + self.text = None + self.tail = None + + def getnext(self): + return self.root_node.children[1] + + +class FragmentRoot(Root): + def __init__(self, children): + self.children = [FragmentWrapper(self, child) for child in children] + self.text = self.tail = None + + def getnext(self): + return None + + +class FragmentWrapper(object): + def __init__(self, fragment_root, obj): + self.root_node = fragment_root + self.obj = obj + if hasattr(self.obj, 'text'): + self.text = ensure_str(self.obj.text) + else: + self.text = None + if hasattr(self.obj, 'tail'): + self.tail = ensure_str(self.obj.tail) + else: + self.tail = None + + def __getattr__(self, name): + return getattr(self.obj, name) + + def getnext(self): + siblings = self.root_node.children + idx = siblings.index(self) + if idx < len(siblings) - 1: + return siblings[idx + 1] + else: + return None + + def __getitem__(self, key): + return self.obj[key] + + def __bool__(self): + return bool(self.obj) + + def getparent(self): + return None + + def __str__(self): + return str(self.obj) + + def __unicode__(self): + return str(self.obj) + + def __len__(self): + return len(self.obj) + + +class TreeWalker(base.NonRecursiveTreeWalker): + def __init__(self, tree): + # pylint:disable=redefined-variable-type + if isinstance(tree, list): + self.fragmentChildren = set(tree) + tree = FragmentRoot(tree) + else: + self.fragmentChildren = set() + tree = Root(tree) + base.NonRecursiveTreeWalker.__init__(self, tree) + self.filter = _ihatexml.InfosetFilter() + + def getNodeDetails(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + return base.TEXT, ensure_str(getattr(node, key)) + + elif isinstance(node, Root): + return (base.DOCUMENT,) + + elif isinstance(node, Doctype): + return base.DOCTYPE, node.name, node.public_id, node.system_id + + elif isinstance(node, FragmentWrapper) and not hasattr(node, "tag"): + return base.TEXT, ensure_str(node.obj) + + elif node.tag == etree.Comment: + return base.COMMENT, ensure_str(node.text) + + elif node.tag == etree.Entity: + return base.ENTITY, ensure_str(node.text)[1:-1] # strip &; + + else: + # This is assumed to be an ordinary element + match = tag_regexp.match(ensure_str(node.tag)) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = ensure_str(node.tag) + attrs = {} + for name, value in list(node.attrib.items()): + name = ensure_str(name) + value = ensure_str(value) + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, self.filter.fromXmlName(tag), + attrs, len(node) > 0 or node.text) + + def getFirstChild(self, node): + assert not isinstance(node, tuple), "Text nodes have no children" + + assert len(node) or node.text, "Node has no children" + if node.text: + return (node, "text") + else: + return node[0] + + def getNextSibling(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + # XXX: we cannot use a "bool(node) and node[0] or None" construct here + # because node[0] might evaluate to False if it has no child element + if len(node): + return node[0] + else: + return None + else: # tail + return node.getnext() + + return (node, "tail") if node.tail else node.getnext() + + def getParentNode(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + return node + # else: fallback to "normal" processing + elif node in self.fragmentChildren: + return None + + return node.getparent() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py new file mode 100644 index 0000000..7483be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/html5lib/treewalkers/genshi.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName +from genshi.core import START, END, XML_NAMESPACE, DOCTYPE, TEXT +from genshi.core import START_NS, END_NS, START_CDATA, END_CDATA, PI, COMMENT + +from . import base + +from ..constants import voidElements, namespaces + + +class TreeWalker(base.TreeWalker): + def __iter__(self): + # Buffer the events so we can pass in the following one + previous = None + for event in self.tree: + if previous is not None: + for token in self.tokens(previous, event): + yield token + previous = event + + # Don't forget the final event! + if previous is not None: + for token in self.tokens(previous, None): + yield token + + def tokens(self, event, next): + kind, data, _ = event + if kind == START: + tag, attribs = data + name = tag.localname + namespace = tag.namespace + converted_attribs = {} + for k, v in attribs: + if isinstance(k, QName): + converted_attribs[(k.namespace, k.localname)] = v + else: + converted_attribs[(None, k)] = v + + if namespace == namespaces["html"] and name in voidElements: + for token in self.emptyTag(namespace, name, converted_attribs, + not next or next[0] != END or + next[1] != tag): + yield token + else: + yield self.startTag(namespace, name, converted_attribs) + + elif kind == END: + name = data.localname + namespace = data.namespace + if namespace != namespaces["html"] or name not in voidElements: + yield self.endTag(namespace, name) + + elif kind == COMMENT: + yield self.comment(data) + + elif kind == TEXT: + for token in self.text(data): + yield token + + elif kind == DOCTYPE: + yield self.doctype(*data) + + elif kind in (XML_NAMESPACE, DOCTYPE, START_NS, END_NS, + START_CDATA, END_CDATA, PI): + pass + + else: + yield self.unknown(kind) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__init__.py new file mode 100644 index 0000000..847bf93 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__init__.py @@ -0,0 +1,2 @@ +from .package_data import __version__ +from .core import * diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..c46c010 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/core.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000..c388fa5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/core.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc new file mode 100644 index 0000000..a7bb4c2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc new file mode 100644 index 0000000..a2144df Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc new file mode 100644 index 0000000..3a6fa60 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/codec.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/codec.py new file mode 100644 index 0000000..98c65ea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/codec.py @@ -0,0 +1,118 @@ +from .core import encode, decode, alabel, ulabel, IDNAError +import codecs +import re + +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +class Codec(codecs.Codec): + + def encode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return "", 0 + + return encode(data), len(data) + + def decode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return u"", 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return ("", 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return (u"", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(data, unicode): + labels = _unicode_dots_re.split(data) + else: + # Must be ASCII string + data = str(data) + unicode(data, "ascii") + labels = data.split(".") + + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = u'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = u'.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result = u".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/compat.py new file mode 100644 index 0000000..4d47f33 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/compat.py @@ -0,0 +1,12 @@ +from .core import * +from .codec import * + +def ToASCII(label): + return encode(label) + +def ToUnicode(label): + return decode(label) + +def nameprep(s): + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/core.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/core.py new file mode 100644 index 0000000..b55b664 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/core.py @@ -0,0 +1,387 @@ +from . import idnadata +import bisect +import unicodedata +import re +import sys +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +if sys.version_info[0] == 3: + unicode = str + unichr = chr + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp): + return unicodedata.combining(unichr(cp)) + +def _is_script(cp, script): + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s): + return s.encode('punycode') + +def _unot(s): + return 'U+{0:04X}'.format(s) + + +def valid_label_length(label): + + if len(label) > 63: + return False + return True + + +def valid_string_length(label, trailing_dot): + + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label, check_ltr=False): + + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == '': + # String likely comes from a newer version of Unicode + raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx)) + if direction in ['R', 'AL', 'AN']: + bidi_label = True + break + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label): + + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label): + + if label[2:4] == '--': + raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') + if label[0] == '-' or label[-1] == '-': + raise IDNAError('Label must not start or end with a hyphen') + return True + + +def check_nfc(label): + + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label, pos): + + cp_value = ord(label[pos]) + + if cp_value == 0x200c: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label, pos, exception=False): + + cp_value = ord(label[pos]) + + if cp_value == 0x00b7: + if 0 < pos < len(label)-1: + if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == u'\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + +def check_label(label): + + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + if not valid_contexto(label, pos): + raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label): + + try: + label = label.encode('ascii') + try: + ulabel(label) + except IDNAError: + raise IDNAError('The label {0} is not a valid A-label'.format(label)) + if not valid_label_length(label): + raise IDNAError('Label too long') + return label + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = unicode(label) + check_label(label) + label = _punycode(label) + label = _alabel_prefix + label + + if not valid_label_length(label): + raise IDNAError('Label too long') + + return label + + +def ulabel(label): + + if not isinstance(label, (bytes, bytearray)): + try: + label = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + + label = label.lower() + if label.startswith(_alabel_prefix): + label = label[len(_alabel_prefix):] + else: + check_label(label) + return label.decode('ascii') + + label = label.decode('punycode') + check_label(label) + return label + + +def uts46_remap(domain, std3_rules=True, transitional=False): + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = u"" + try: + for pos, char in enumerate(domain): + code_point = ord(char) + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, "Z")) - 1] + status = uts46row[1] + replacement = uts46row[2] if len(uts46row) == 3 else None + if (status == "V" or + (status == "D" and not transitional) or + (status == "3" and std3_rules and replacement is None)): + output += char + elif replacement is not None and (status == "M" or + (status == "3" and std3_rules) or + (status == "D" and transitional)): + output += replacement + elif status != "I": + raise IndexError() + return unicodedata.normalize("NFC", output) + except IndexError: + raise InvalidCodepoint( + "Codepoint {0} not allowed at position {1} in {2}".format( + _unot(code_point), pos + 1, repr(domain))) + + +def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split('.') + else: + labels = _unicode_dots_re.split(s) + while labels and not labels[0]: + del labels[0] + if not labels: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + result.append(alabel(label)) + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s, strict=False, uts46=False, std3_rules=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split(u'.') + while labels and not labels[0]: + del labels[0] + if not labels: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + result.append(ulabel(label)) + if trailing_dot: + result.append(u'') + return u'.'.join(result) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/idnadata.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/idnadata.py new file mode 100644 index 0000000..c48f1b5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/idnadata.py @@ -0,0 +1,1585 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "6.3.0" +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0x101400001018b, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004db6, + 0x4e0000009fcd, + 0xf9000000fa6e, + 0xfa700000fada, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2f8000002fa1e, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5f0000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b002, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1b0000001b001, + ), +} +joining_types = { + 0x600: 85, + 0x601: 85, + 0x602: 85, + 0x603: 85, + 0x604: 85, + 0x608: 85, + 0x60b: 85, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 68, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 82, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 85, + 0x857: 85, + 0x858: 85, + 0x8a0: 68, + 0x8a2: 68, + 0x8a3: 68, + 0x8a4: 68, + 0x8a5: 68, + 0x8a6: 68, + 0x8a7: 68, + 0x8a8: 68, + 0x8a9: 68, + 0x8aa: 82, + 0x8ab: 82, + 0x8ac: 82, + 0x1806: 85, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 85, + 0x1886: 85, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5590000055a, + 0x56100000587, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5f0000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x8000000082e, + 0x8400000085c, + 0x8a0000008a1, + 0x8a2000008ad, + 0x8e4000008ff, + 0x90000000958, + 0x96000000964, + 0x96600000970, + 0x97100000978, + 0x97900000980, + 0x98100000984, + 0x9850000098d, + 0x98f00000991, + 0x993000009a9, + 0x9aa000009b1, + 0x9b2000009b3, + 0x9b6000009ba, + 0x9bc000009c5, + 0x9c7000009c9, + 0x9cb000009cf, + 0x9d7000009d8, + 0x9e0000009e4, + 0x9e6000009f2, + 0xa0100000a04, + 0xa0500000a0b, + 0xa0f00000a11, + 0xa1300000a29, + 0xa2a00000a31, + 0xa3200000a33, + 0xa3500000a36, + 0xa3800000a3a, + 0xa3c00000a3d, + 0xa3e00000a43, + 0xa4700000a49, + 0xa4b00000a4e, + 0xa5100000a52, + 0xa5c00000a5d, + 0xa6600000a76, + 0xa8100000a84, + 0xa8500000a8e, + 0xa8f00000a92, + 0xa9300000aa9, + 0xaaa00000ab1, + 0xab200000ab4, + 0xab500000aba, + 0xabc00000ac6, + 0xac700000aca, + 0xacb00000ace, + 0xad000000ad1, + 0xae000000ae4, + 0xae600000af0, + 0xb0100000b04, + 0xb0500000b0d, + 0xb0f00000b11, + 0xb1300000b29, + 0xb2a00000b31, + 0xb3200000b34, + 0xb3500000b3a, + 0xb3c00000b45, + 0xb4700000b49, + 0xb4b00000b4e, + 0xb5600000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0100000c04, + 0xc0500000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c34, + 0xc3500000c3a, + 0xc3d00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5a, + 0xc6000000c64, + 0xc6600000c70, + 0xc8200000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcde00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf3, + 0xd0200000d04, + 0xd0500000d0d, + 0xd0e00000d11, + 0xd1200000d3b, + 0xd3d00000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5700000d58, + 0xd6000000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8200000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8700000e89, + 0xe8a00000e8b, + 0xe8d00000e8e, + 0xe9400000e98, + 0xe9900000ea0, + 0xea100000ea4, + 0xea500000ea6, + 0xea700000ea8, + 0xeaa00000eac, + 0xead00000eb3, + 0xeb400000eba, + 0xebb00000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ece, + 0xed000000eda, + 0xede00000ee0, + 0xf0000000f01, + 0xf0b00000f0c, + 0xf1800000f1a, + 0xf2000000f2a, + 0xf3500000f36, + 0xf3700000f38, + 0xf3900000f3a, + 0xf3e00000f43, + 0xf4400000f48, + 0xf4900000f4d, + 0xf4e00000f52, + 0xf5300000f57, + 0xf5800000f5c, + 0xf5d00000f69, + 0xf6a00000f6d, + 0xf7100000f73, + 0xf7400000f75, + 0xf7a00000f81, + 0xf8200000f85, + 0xf8600000f93, + 0xf9400000f98, + 0xf9900000f9d, + 0xf9e00000fa2, + 0xfa300000fa7, + 0xfa800000fac, + 0xfad00000fb9, + 0xfba00000fbd, + 0xfc600000fc7, + 0x10000000104a, + 0x10500000109e, + 0x10d0000010fb, + 0x10fd00001100, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f5, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x17000000170d, + 0x170e00001715, + 0x172000001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001878, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191d, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1b0000001b4c, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cf7, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001de7, + 0x1dfc00001e00, + 0x1e0100001e02, + 0x1e0300001e04, + 0x1e0500001e06, + 0x1e0700001e08, + 0x1e0900001e0a, + 0x1e0b00001e0c, + 0x1e0d00001e0e, + 0x1e0f00001e10, + 0x1e1100001e12, + 0x1e1300001e14, + 0x1e1500001e16, + 0x1e1700001e18, + 0x1e1900001e1a, + 0x1e1b00001e1c, + 0x1e1d00001e1e, + 0x1e1f00001e20, + 0x1e2100001e22, + 0x1e2300001e24, + 0x1e2500001e26, + 0x1e2700001e28, + 0x1e2900001e2a, + 0x1e2b00001e2c, + 0x1e2d00001e2e, + 0x1e2f00001e30, + 0x1e3100001e32, + 0x1e3300001e34, + 0x1e3500001e36, + 0x1e3700001e38, + 0x1e3900001e3a, + 0x1e3b00001e3c, + 0x1e3d00001e3e, + 0x1e3f00001e40, + 0x1e4100001e42, + 0x1e4300001e44, + 0x1e4500001e46, + 0x1e4700001e48, + 0x1e4900001e4a, + 0x1e4b00001e4c, + 0x1e4d00001e4e, + 0x1e4f00001e50, + 0x1e5100001e52, + 0x1e5300001e54, + 0x1e5500001e56, + 0x1e5700001e58, + 0x1e5900001e5a, + 0x1e5b00001e5c, + 0x1e5d00001e5e, + 0x1e5f00001e60, + 0x1e6100001e62, + 0x1e6300001e64, + 0x1e6500001e66, + 0x1e6700001e68, + 0x1e6900001e6a, + 0x1e6b00001e6c, + 0x1e6d00001e6e, + 0x1e6f00001e70, + 0x1e7100001e72, + 0x1e7300001e74, + 0x1e7500001e76, + 0x1e7700001e78, + 0x1e7900001e7a, + 0x1e7b00001e7c, + 0x1e7d00001e7e, + 0x1e7f00001e80, + 0x1e8100001e82, + 0x1e8300001e84, + 0x1e8500001e86, + 0x1e8700001e88, + 0x1e8900001e8a, + 0x1e8b00001e8c, + 0x1e8d00001e8e, + 0x1e8f00001e90, + 0x1e9100001e92, + 0x1e9300001e94, + 0x1e9500001e9a, + 0x1e9c00001e9e, + 0x1e9f00001ea0, + 0x1ea100001ea2, + 0x1ea300001ea4, + 0x1ea500001ea6, + 0x1ea700001ea8, + 0x1ea900001eaa, + 0x1eab00001eac, + 0x1ead00001eae, + 0x1eaf00001eb0, + 0x1eb100001eb2, + 0x1eb300001eb4, + 0x1eb500001eb6, + 0x1eb700001eb8, + 0x1eb900001eba, + 0x1ebb00001ebc, + 0x1ebd00001ebe, + 0x1ebf00001ec0, + 0x1ec100001ec2, + 0x1ec300001ec4, + 0x1ec500001ec6, + 0x1ec700001ec8, + 0x1ec900001eca, + 0x1ecb00001ecc, + 0x1ecd00001ece, + 0x1ecf00001ed0, + 0x1ed100001ed2, + 0x1ed300001ed4, + 0x1ed500001ed6, + 0x1ed700001ed8, + 0x1ed900001eda, + 0x1edb00001edc, + 0x1edd00001ede, + 0x1edf00001ee0, + 0x1ee100001ee2, + 0x1ee300001ee4, + 0x1ee500001ee6, + 0x1ee700001ee8, + 0x1ee900001eea, + 0x1eeb00001eec, + 0x1eed00001eee, + 0x1eef00001ef0, + 0x1ef100001ef2, + 0x1ef300001ef4, + 0x1ef500001ef6, + 0x1ef700001ef8, + 0x1ef900001efa, + 0x1efb00001efc, + 0x1efd00001efe, + 0x1eff00001f08, + 0x1f1000001f16, + 0x1f2000001f28, + 0x1f3000001f38, + 0x1f4000001f46, + 0x1f5000001f58, + 0x1f6000001f68, + 0x1f7000001f71, + 0x1f7200001f73, + 0x1f7400001f75, + 0x1f7600001f77, + 0x1f7800001f79, + 0x1f7a00001f7b, + 0x1f7c00001f7d, + 0x1fb000001fb2, + 0x1fb600001fb7, + 0x1fc600001fc7, + 0x1fd000001fd3, + 0x1fd600001fd8, + 0x1fe000001fe3, + 0x1fe400001fe8, + 0x1ff600001ff7, + 0x214e0000214f, + 0x218400002185, + 0x2c3000002c5f, + 0x2c6100002c62, + 0x2c6500002c67, + 0x2c6800002c69, + 0x2c6a00002c6b, + 0x2c6c00002c6d, + 0x2c7100002c72, + 0x2c7300002c75, + 0x2c7600002c7c, + 0x2c8100002c82, + 0x2c8300002c84, + 0x2c8500002c86, + 0x2c8700002c88, + 0x2c8900002c8a, + 0x2c8b00002c8c, + 0x2c8d00002c8e, + 0x2c8f00002c90, + 0x2c9100002c92, + 0x2c9300002c94, + 0x2c9500002c96, + 0x2c9700002c98, + 0x2c9900002c9a, + 0x2c9b00002c9c, + 0x2c9d00002c9e, + 0x2c9f00002ca0, + 0x2ca100002ca2, + 0x2ca300002ca4, + 0x2ca500002ca6, + 0x2ca700002ca8, + 0x2ca900002caa, + 0x2cab00002cac, + 0x2cad00002cae, + 0x2caf00002cb0, + 0x2cb100002cb2, + 0x2cb300002cb4, + 0x2cb500002cb6, + 0x2cb700002cb8, + 0x2cb900002cba, + 0x2cbb00002cbc, + 0x2cbd00002cbe, + 0x2cbf00002cc0, + 0x2cc100002cc2, + 0x2cc300002cc4, + 0x2cc500002cc6, + 0x2cc700002cc8, + 0x2cc900002cca, + 0x2ccb00002ccc, + 0x2ccd00002cce, + 0x2ccf00002cd0, + 0x2cd100002cd2, + 0x2cd300002cd4, + 0x2cd500002cd6, + 0x2cd700002cd8, + 0x2cd900002cda, + 0x2cdb00002cdc, + 0x2cdd00002cde, + 0x2cdf00002ce0, + 0x2ce100002ce2, + 0x2ce300002ce5, + 0x2cec00002ced, + 0x2cee00002cf2, + 0x2cf300002cf4, + 0x2d0000002d26, + 0x2d2700002d28, + 0x2d2d00002d2e, + 0x2d3000002d68, + 0x2d7f00002d97, + 0x2da000002da7, + 0x2da800002daf, + 0x2db000002db7, + 0x2db800002dbf, + 0x2dc000002dc7, + 0x2dc800002dcf, + 0x2dd000002dd7, + 0x2dd800002ddf, + 0x2de000002e00, + 0x2e2f00002e30, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 0x30990000309b, + 0x309d0000309f, + 0x30a1000030fb, + 0x30fc000030ff, + 0x31050000312e, + 0x31a0000031bb, + 0x31f000003200, + 0x340000004db6, + 0x4e0000009fcd, + 0xa0000000a48d, + 0xa4d00000a4fe, + 0xa5000000a60d, + 0xa6100000a62c, + 0xa6410000a642, + 0xa6430000a644, + 0xa6450000a646, + 0xa6470000a648, + 0xa6490000a64a, + 0xa64b0000a64c, + 0xa64d0000a64e, + 0xa64f0000a650, + 0xa6510000a652, + 0xa6530000a654, + 0xa6550000a656, + 0xa6570000a658, + 0xa6590000a65a, + 0xa65b0000a65c, + 0xa65d0000a65e, + 0xa65f0000a660, + 0xa6610000a662, + 0xa6630000a664, + 0xa6650000a666, + 0xa6670000a668, + 0xa6690000a66a, + 0xa66b0000a66c, + 0xa66d0000a670, + 0xa6740000a67e, + 0xa67f0000a680, + 0xa6810000a682, + 0xa6830000a684, + 0xa6850000a686, + 0xa6870000a688, + 0xa6890000a68a, + 0xa68b0000a68c, + 0xa68d0000a68e, + 0xa68f0000a690, + 0xa6910000a692, + 0xa6930000a694, + 0xa6950000a696, + 0xa6970000a698, + 0xa69f0000a6e6, + 0xa6f00000a6f2, + 0xa7170000a720, + 0xa7230000a724, + 0xa7250000a726, + 0xa7270000a728, + 0xa7290000a72a, + 0xa72b0000a72c, + 0xa72d0000a72e, + 0xa72f0000a732, + 0xa7330000a734, + 0xa7350000a736, + 0xa7370000a738, + 0xa7390000a73a, + 0xa73b0000a73c, + 0xa73d0000a73e, + 0xa73f0000a740, + 0xa7410000a742, + 0xa7430000a744, + 0xa7450000a746, + 0xa7470000a748, + 0xa7490000a74a, + 0xa74b0000a74c, + 0xa74d0000a74e, + 0xa74f0000a750, + 0xa7510000a752, + 0xa7530000a754, + 0xa7550000a756, + 0xa7570000a758, + 0xa7590000a75a, + 0xa75b0000a75c, + 0xa75d0000a75e, + 0xa75f0000a760, + 0xa7610000a762, + 0xa7630000a764, + 0xa7650000a766, + 0xa7670000a768, + 0xa7690000a76a, + 0xa76b0000a76c, + 0xa76d0000a76e, + 0xa76f0000a770, + 0xa7710000a779, + 0xa77a0000a77b, + 0xa77c0000a77d, + 0xa77f0000a780, + 0xa7810000a782, + 0xa7830000a784, + 0xa7850000a786, + 0xa7870000a789, + 0xa78c0000a78d, + 0xa78e0000a78f, + 0xa7910000a792, + 0xa7930000a794, + 0xa7a10000a7a2, + 0xa7a30000a7a4, + 0xa7a50000a7a6, + 0xa7a70000a7a8, + 0xa7a90000a7aa, + 0xa7fa0000a828, + 0xa8400000a874, + 0xa8800000a8c5, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa9000000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aa7c, + 0xaa800000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xabc00000abeb, + 0xabec0000abee, + 0xabf00000abfa, + 0xac000000d7a4, + 0xfa0e0000fa10, + 0xfa110000fa12, + 0xfa130000fa15, + 0xfa1f0000fa20, + 0xfa210000fa22, + 0xfa230000fa25, + 0xfa270000fa2a, + 0xfb1e0000fb1f, + 0xfe200000fe27, + 0xfe730000fe74, + 0x100000001000c, + 0x1000d00010027, + 0x100280001003b, + 0x1003c0001003e, + 0x1003f0001004e, + 0x100500001005e, + 0x10080000100fb, + 0x101fd000101fe, + 0x102800001029d, + 0x102a0000102d1, + 0x103000001031f, + 0x1033000010341, + 0x103420001034a, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a34, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10c0000010c49, + 0x1100000011047, + 0x1106600011070, + 0x11080000110bb, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x11180000111c5, + 0x111d0000111da, + 0x11680000116b8, + 0x116c0000116ca, + 0x120000001236f, + 0x130000001342f, + 0x1680000016a39, + 0x16f0000016f45, + 0x16f5000016f7f, + 0x16f8f00016fa0, + 0x1b0000001b002, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/intranges.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/intranges.py new file mode 100644 index 0000000..fa8a735 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/intranges.py @@ -0,0 +1,53 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect + +def intranges_from_list(list_): + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start, end): + return (start << 32) | end + +def _decode_range(r): + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_, ranges): + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/package_data.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/package_data.py new file mode 100644 index 0000000..fc33139 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '2.6' + diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/uts46data.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/uts46data.py new file mode 100644 index 0000000..f9b3236 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/idna/uts46data.py @@ -0,0 +1,7634 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "6.3.0" +def _seg_0(): + return [ + (0x0, '3'), + (0x1, '3'), + (0x2, '3'), + (0x3, '3'), + (0x4, '3'), + (0x5, '3'), + (0x6, '3'), + (0x7, '3'), + (0x8, '3'), + (0x9, '3'), + (0xA, '3'), + (0xB, '3'), + (0xC, '3'), + (0xD, '3'), + (0xE, '3'), + (0xF, '3'), + (0x10, '3'), + (0x11, '3'), + (0x12, '3'), + (0x13, '3'), + (0x14, '3'), + (0x15, '3'), + (0x16, '3'), + (0x17, '3'), + (0x18, '3'), + (0x19, '3'), + (0x1A, '3'), + (0x1B, '3'), + (0x1C, '3'), + (0x1D, '3'), + (0x1E, '3'), + (0x1F, '3'), + (0x20, '3'), + (0x21, '3'), + (0x22, '3'), + (0x23, '3'), + (0x24, '3'), + (0x25, '3'), + (0x26, '3'), + (0x27, '3'), + (0x28, '3'), + (0x29, '3'), + (0x2A, '3'), + (0x2B, '3'), + (0x2C, '3'), + (0x2D, 'V'), + (0x2E, 'V'), + (0x2F, '3'), + (0x30, 'V'), + (0x31, 'V'), + (0x32, 'V'), + (0x33, 'V'), + (0x34, 'V'), + (0x35, 'V'), + (0x36, 'V'), + (0x37, 'V'), + (0x38, 'V'), + (0x39, 'V'), + (0x3A, '3'), + (0x3B, '3'), + (0x3C, '3'), + (0x3D, '3'), + (0x3E, '3'), + (0x3F, '3'), + (0x40, '3'), + (0x41, 'M', u'a'), + (0x42, 'M', u'b'), + (0x43, 'M', u'c'), + (0x44, 'M', u'd'), + (0x45, 'M', u'e'), + (0x46, 'M', u'f'), + (0x47, 'M', u'g'), + (0x48, 'M', u'h'), + (0x49, 'M', u'i'), + (0x4A, 'M', u'j'), + (0x4B, 'M', u'k'), + (0x4C, 'M', u'l'), + (0x4D, 'M', u'm'), + (0x4E, 'M', u'n'), + (0x4F, 'M', u'o'), + (0x50, 'M', u'p'), + (0x51, 'M', u'q'), + (0x52, 'M', u'r'), + (0x53, 'M', u's'), + (0x54, 'M', u't'), + (0x55, 'M', u'u'), + (0x56, 'M', u'v'), + (0x57, 'M', u'w'), + (0x58, 'M', u'x'), + (0x59, 'M', u'y'), + (0x5A, 'M', u'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1(): + return [ + (0x64, 'V'), + (0x65, 'V'), + (0x66, 'V'), + (0x67, 'V'), + (0x68, 'V'), + (0x69, 'V'), + (0x6A, 'V'), + (0x6B, 'V'), + (0x6C, 'V'), + (0x6D, 'V'), + (0x6E, 'V'), + (0x6F, 'V'), + (0x70, 'V'), + (0x71, 'V'), + (0x72, 'V'), + (0x73, 'V'), + (0x74, 'V'), + (0x75, 'V'), + (0x76, 'V'), + (0x77, 'V'), + (0x78, 'V'), + (0x79, 'V'), + (0x7A, 'V'), + (0x7B, '3'), + (0x7C, '3'), + (0x7D, '3'), + (0x7E, '3'), + (0x7F, '3'), + (0x80, 'X'), + (0x81, 'X'), + (0x82, 'X'), + (0x83, 'X'), + (0x84, 'X'), + (0x85, 'X'), + (0x86, 'X'), + (0x87, 'X'), + (0x88, 'X'), + (0x89, 'X'), + (0x8A, 'X'), + (0x8B, 'X'), + (0x8C, 'X'), + (0x8D, 'X'), + (0x8E, 'X'), + (0x8F, 'X'), + (0x90, 'X'), + (0x91, 'X'), + (0x92, 'X'), + (0x93, 'X'), + (0x94, 'X'), + (0x95, 'X'), + (0x96, 'X'), + (0x97, 'X'), + (0x98, 'X'), + (0x99, 'X'), + (0x9A, 'X'), + (0x9B, 'X'), + (0x9C, 'X'), + (0x9D, 'X'), + (0x9E, 'X'), + (0x9F, 'X'), + (0xA0, '3', u' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', u' ̈'), + (0xA9, 'V'), + (0xAA, 'M', u'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', u' ̄'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', u'2'), + (0xB3, 'M', u'3'), + (0xB4, '3', u' ́'), + (0xB5, 'M', u'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', u' ̧'), + (0xB9, 'M', u'1'), + (0xBA, 'M', u'o'), + (0xBB, 'V'), + (0xBC, 'M', u'1⁄4'), + (0xBD, 'M', u'1⁄2'), + (0xBE, 'M', u'3⁄4'), + (0xBF, 'V'), + (0xC0, 'M', u'à'), + (0xC1, 'M', u'á'), + (0xC2, 'M', u'â'), + (0xC3, 'M', u'ã'), + (0xC4, 'M', u'ä'), + (0xC5, 'M', u'å'), + (0xC6, 'M', u'æ'), + (0xC7, 'M', u'ç'), + ] + +def _seg_2(): + return [ + (0xC8, 'M', u'è'), + (0xC9, 'M', u'é'), + (0xCA, 'M', u'ê'), + (0xCB, 'M', u'ë'), + (0xCC, 'M', u'ì'), + (0xCD, 'M', u'í'), + (0xCE, 'M', u'î'), + (0xCF, 'M', u'ï'), + (0xD0, 'M', u'ð'), + (0xD1, 'M', u'ñ'), + (0xD2, 'M', u'ò'), + (0xD3, 'M', u'ó'), + (0xD4, 'M', u'ô'), + (0xD5, 'M', u'õ'), + (0xD6, 'M', u'ö'), + (0xD7, 'V'), + (0xD8, 'M', u'ø'), + (0xD9, 'M', u'ù'), + (0xDA, 'M', u'ú'), + (0xDB, 'M', u'û'), + (0xDC, 'M', u'ü'), + (0xDD, 'M', u'ý'), + (0xDE, 'M', u'þ'), + (0xDF, 'D', u'ss'), + (0xE0, 'V'), + (0xE1, 'V'), + (0xE2, 'V'), + (0xE3, 'V'), + (0xE4, 'V'), + (0xE5, 'V'), + (0xE6, 'V'), + (0xE7, 'V'), + (0xE8, 'V'), + (0xE9, 'V'), + (0xEA, 'V'), + (0xEB, 'V'), + (0xEC, 'V'), + (0xED, 'V'), + (0xEE, 'V'), + (0xEF, 'V'), + (0xF0, 'V'), + (0xF1, 'V'), + (0xF2, 'V'), + (0xF3, 'V'), + (0xF4, 'V'), + (0xF5, 'V'), + (0xF6, 'V'), + (0xF7, 'V'), + (0xF8, 'V'), + (0xF9, 'V'), + (0xFA, 'V'), + (0xFB, 'V'), + (0xFC, 'V'), + (0xFD, 'V'), + (0xFE, 'V'), + (0xFF, 'V'), + (0x100, 'M', u'ā'), + (0x101, 'V'), + (0x102, 'M', u'ă'), + (0x103, 'V'), + (0x104, 'M', u'ą'), + (0x105, 'V'), + (0x106, 'M', u'ć'), + (0x107, 'V'), + (0x108, 'M', u'ĉ'), + (0x109, 'V'), + (0x10A, 'M', u'ċ'), + (0x10B, 'V'), + (0x10C, 'M', u'č'), + (0x10D, 'V'), + (0x10E, 'M', u'ď'), + (0x10F, 'V'), + (0x110, 'M', u'đ'), + (0x111, 'V'), + (0x112, 'M', u'ē'), + (0x113, 'V'), + (0x114, 'M', u'ĕ'), + (0x115, 'V'), + (0x116, 'M', u'ė'), + (0x117, 'V'), + (0x118, 'M', u'ę'), + (0x119, 'V'), + (0x11A, 'M', u'ě'), + (0x11B, 'V'), + (0x11C, 'M', u'ĝ'), + (0x11D, 'V'), + (0x11E, 'M', u'ğ'), + (0x11F, 'V'), + (0x120, 'M', u'ġ'), + (0x121, 'V'), + (0x122, 'M', u'ģ'), + (0x123, 'V'), + (0x124, 'M', u'ĥ'), + (0x125, 'V'), + (0x126, 'M', u'ħ'), + (0x127, 'V'), + (0x128, 'M', u'ĩ'), + (0x129, 'V'), + (0x12A, 'M', u'ī'), + (0x12B, 'V'), + ] + +def _seg_3(): + return [ + (0x12C, 'M', u'ĭ'), + (0x12D, 'V'), + (0x12E, 'M', u'į'), + (0x12F, 'V'), + (0x130, 'M', u'i̇'), + (0x131, 'V'), + (0x132, 'M', u'ij'), + (0x134, 'M', u'ĵ'), + (0x135, 'V'), + (0x136, 'M', u'ķ'), + (0x137, 'V'), + (0x139, 'M', u'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', u'ļ'), + (0x13C, 'V'), + (0x13D, 'M', u'ľ'), + (0x13E, 'V'), + (0x13F, 'M', u'l·'), + (0x141, 'M', u'ł'), + (0x142, 'V'), + (0x143, 'M', u'ń'), + (0x144, 'V'), + (0x145, 'M', u'ņ'), + (0x146, 'V'), + (0x147, 'M', u'ň'), + (0x148, 'V'), + (0x149, 'M', u'ʼn'), + (0x14A, 'M', u'ŋ'), + (0x14B, 'V'), + (0x14C, 'M', u'ō'), + (0x14D, 'V'), + (0x14E, 'M', u'ŏ'), + (0x14F, 'V'), + (0x150, 'M', u'ő'), + (0x151, 'V'), + (0x152, 'M', u'œ'), + (0x153, 'V'), + (0x154, 'M', u'ŕ'), + (0x155, 'V'), + (0x156, 'M', u'ŗ'), + (0x157, 'V'), + (0x158, 'M', u'ř'), + (0x159, 'V'), + (0x15A, 'M', u'ś'), + (0x15B, 'V'), + (0x15C, 'M', u'ŝ'), + (0x15D, 'V'), + (0x15E, 'M', u'ş'), + (0x15F, 'V'), + (0x160, 'M', u'š'), + (0x161, 'V'), + (0x162, 'M', u'ţ'), + (0x163, 'V'), + (0x164, 'M', u'ť'), + (0x165, 'V'), + (0x166, 'M', u'ŧ'), + (0x167, 'V'), + (0x168, 'M', u'ũ'), + (0x169, 'V'), + (0x16A, 'M', u'ū'), + (0x16B, 'V'), + (0x16C, 'M', u'ŭ'), + (0x16D, 'V'), + (0x16E, 'M', u'ů'), + (0x16F, 'V'), + (0x170, 'M', u'ű'), + (0x171, 'V'), + (0x172, 'M', u'ų'), + (0x173, 'V'), + (0x174, 'M', u'ŵ'), + (0x175, 'V'), + (0x176, 'M', u'ŷ'), + (0x177, 'V'), + (0x178, 'M', u'ÿ'), + (0x179, 'M', u'ź'), + (0x17A, 'V'), + (0x17B, 'M', u'ż'), + (0x17C, 'V'), + (0x17D, 'M', u'ž'), + (0x17E, 'V'), + (0x17F, 'M', u's'), + (0x180, 'V'), + (0x181, 'M', u'ɓ'), + (0x182, 'M', u'ƃ'), + (0x183, 'V'), + (0x184, 'M', u'ƅ'), + (0x185, 'V'), + (0x186, 'M', u'ɔ'), + (0x187, 'M', u'ƈ'), + (0x188, 'V'), + (0x189, 'M', u'ɖ'), + (0x18A, 'M', u'ɗ'), + (0x18B, 'M', u'ƌ'), + (0x18C, 'V'), + (0x18E, 'M', u'ǝ'), + (0x18F, 'M', u'ə'), + (0x190, 'M', u'ɛ'), + (0x191, 'M', u'ƒ'), + (0x192, 'V'), + (0x193, 'M', u'ɠ'), + ] + +def _seg_4(): + return [ + (0x194, 'M', u'ɣ'), + (0x195, 'V'), + (0x196, 'M', u'ɩ'), + (0x197, 'M', u'ɨ'), + (0x198, 'M', u'ƙ'), + (0x199, 'V'), + (0x19C, 'M', u'ɯ'), + (0x19D, 'M', u'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', u'ɵ'), + (0x1A0, 'M', u'ơ'), + (0x1A1, 'V'), + (0x1A2, 'M', u'ƣ'), + (0x1A3, 'V'), + (0x1A4, 'M', u'ƥ'), + (0x1A5, 'V'), + (0x1A6, 'M', u'ʀ'), + (0x1A7, 'M', u'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', u'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', u'ƭ'), + (0x1AD, 'V'), + (0x1AE, 'M', u'ʈ'), + (0x1AF, 'M', u'ư'), + (0x1B0, 'V'), + (0x1B1, 'M', u'ʊ'), + (0x1B2, 'M', u'ʋ'), + (0x1B3, 'M', u'ƴ'), + (0x1B4, 'V'), + (0x1B5, 'M', u'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', u'ʒ'), + (0x1B8, 'M', u'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', u'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', u'dž'), + (0x1C7, 'M', u'lj'), + (0x1CA, 'M', u'nj'), + (0x1CD, 'M', u'ǎ'), + (0x1CE, 'V'), + (0x1CF, 'M', u'ǐ'), + (0x1D0, 'V'), + (0x1D1, 'M', u'ǒ'), + (0x1D2, 'V'), + (0x1D3, 'M', u'ǔ'), + (0x1D4, 'V'), + (0x1D5, 'M', u'ǖ'), + (0x1D6, 'V'), + (0x1D7, 'M', u'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', u'ǚ'), + (0x1DA, 'V'), + (0x1DB, 'M', u'ǜ'), + (0x1DC, 'V'), + (0x1DE, 'M', u'ǟ'), + (0x1DF, 'V'), + (0x1E0, 'M', u'ǡ'), + (0x1E1, 'V'), + (0x1E2, 'M', u'ǣ'), + (0x1E3, 'V'), + (0x1E4, 'M', u'ǥ'), + (0x1E5, 'V'), + (0x1E6, 'M', u'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', u'ǩ'), + (0x1E9, 'V'), + (0x1EA, 'M', u'ǫ'), + (0x1EB, 'V'), + (0x1EC, 'M', u'ǭ'), + (0x1ED, 'V'), + (0x1EE, 'M', u'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', u'dz'), + (0x1F4, 'M', u'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', u'ƕ'), + (0x1F7, 'M', u'ƿ'), + (0x1F8, 'M', u'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', u'ǻ'), + (0x1FB, 'V'), + (0x1FC, 'M', u'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', u'ǿ'), + (0x1FF, 'V'), + (0x200, 'M', u'ȁ'), + (0x201, 'V'), + (0x202, 'M', u'ȃ'), + (0x203, 'V'), + (0x204, 'M', u'ȅ'), + (0x205, 'V'), + (0x206, 'M', u'ȇ'), + (0x207, 'V'), + (0x208, 'M', u'ȉ'), + (0x209, 'V'), + (0x20A, 'M', u'ȋ'), + (0x20B, 'V'), + (0x20C, 'M', u'ȍ'), + ] + +def _seg_5(): + return [ + (0x20D, 'V'), + (0x20E, 'M', u'ȏ'), + (0x20F, 'V'), + (0x210, 'M', u'ȑ'), + (0x211, 'V'), + (0x212, 'M', u'ȓ'), + (0x213, 'V'), + (0x214, 'M', u'ȕ'), + (0x215, 'V'), + (0x216, 'M', u'ȗ'), + (0x217, 'V'), + (0x218, 'M', u'ș'), + (0x219, 'V'), + (0x21A, 'M', u'ț'), + (0x21B, 'V'), + (0x21C, 'M', u'ȝ'), + (0x21D, 'V'), + (0x21E, 'M', u'ȟ'), + (0x21F, 'V'), + (0x220, 'M', u'ƞ'), + (0x221, 'V'), + (0x222, 'M', u'ȣ'), + (0x223, 'V'), + (0x224, 'M', u'ȥ'), + (0x225, 'V'), + (0x226, 'M', u'ȧ'), + (0x227, 'V'), + (0x228, 'M', u'ȩ'), + (0x229, 'V'), + (0x22A, 'M', u'ȫ'), + (0x22B, 'V'), + (0x22C, 'M', u'ȭ'), + (0x22D, 'V'), + (0x22E, 'M', u'ȯ'), + (0x22F, 'V'), + (0x230, 'M', u'ȱ'), + (0x231, 'V'), + (0x232, 'M', u'ȳ'), + (0x233, 'V'), + (0x23A, 'M', u'ⱥ'), + (0x23B, 'M', u'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', u'ƚ'), + (0x23E, 'M', u'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', u'ɂ'), + (0x242, 'V'), + (0x243, 'M', u'ƀ'), + (0x244, 'M', u'ʉ'), + (0x245, 'M', u'ʌ'), + (0x246, 'M', u'ɇ'), + (0x247, 'V'), + (0x248, 'M', u'ɉ'), + (0x249, 'V'), + (0x24A, 'M', u'ɋ'), + (0x24B, 'V'), + (0x24C, 'M', u'ɍ'), + (0x24D, 'V'), + (0x24E, 'M', u'ɏ'), + (0x24F, 'V'), + (0x2B0, 'M', u'h'), + (0x2B1, 'M', u'ɦ'), + (0x2B2, 'M', u'j'), + (0x2B3, 'M', u'r'), + (0x2B4, 'M', u'ɹ'), + (0x2B5, 'M', u'ɻ'), + (0x2B6, 'M', u'ʁ'), + (0x2B7, 'M', u'w'), + (0x2B8, 'M', u'y'), + (0x2B9, 'V'), + (0x2D8, '3', u' ̆'), + (0x2D9, '3', u' ̇'), + (0x2DA, '3', u' ̊'), + (0x2DB, '3', u' ̨'), + (0x2DC, '3', u' ̃'), + (0x2DD, '3', u' ̋'), + (0x2DE, 'V'), + (0x2E0, 'M', u'ɣ'), + (0x2E1, 'M', u'l'), + (0x2E2, 'M', u's'), + (0x2E3, 'M', u'x'), + (0x2E4, 'M', u'ʕ'), + (0x2E5, 'V'), + (0x340, 'M', u'̀'), + (0x341, 'M', u'́'), + (0x342, 'V'), + (0x343, 'M', u'̓'), + (0x344, 'M', u'̈́'), + (0x345, 'M', u'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', u'ͱ'), + (0x371, 'V'), + (0x372, 'M', u'ͳ'), + (0x373, 'V'), + (0x374, 'M', u'ʹ'), + (0x375, 'V'), + (0x376, 'M', u'ͷ'), + (0x377, 'V'), + ] + +def _seg_6(): + return [ + (0x378, 'X'), + (0x37A, '3', u' ι'), + (0x37B, 'V'), + (0x37E, '3', u';'), + (0x37F, 'X'), + (0x384, '3', u' ́'), + (0x385, '3', u' ̈́'), + (0x386, 'M', u'ά'), + (0x387, 'M', u'·'), + (0x388, 'M', u'έ'), + (0x389, 'M', u'ή'), + (0x38A, 'M', u'ί'), + (0x38B, 'X'), + (0x38C, 'M', u'ό'), + (0x38D, 'X'), + (0x38E, 'M', u'ύ'), + (0x38F, 'M', u'ώ'), + (0x390, 'V'), + (0x391, 'M', u'α'), + (0x392, 'M', u'β'), + (0x393, 'M', u'γ'), + (0x394, 'M', u'δ'), + (0x395, 'M', u'ε'), + (0x396, 'M', u'ζ'), + (0x397, 'M', u'η'), + (0x398, 'M', u'θ'), + (0x399, 'M', u'ι'), + (0x39A, 'M', u'κ'), + (0x39B, 'M', u'λ'), + (0x39C, 'M', u'μ'), + (0x39D, 'M', u'ν'), + (0x39E, 'M', u'ξ'), + (0x39F, 'M', u'ο'), + (0x3A0, 'M', u'π'), + (0x3A1, 'M', u'ρ'), + (0x3A2, 'X'), + (0x3A3, 'M', u'σ'), + (0x3A4, 'M', u'τ'), + (0x3A5, 'M', u'υ'), + (0x3A6, 'M', u'φ'), + (0x3A7, 'M', u'χ'), + (0x3A8, 'M', u'ψ'), + (0x3A9, 'M', u'ω'), + (0x3AA, 'M', u'ϊ'), + (0x3AB, 'M', u'ϋ'), + (0x3AC, 'V'), + (0x3C2, 'D', u'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', u'ϗ'), + (0x3D0, 'M', u'β'), + (0x3D1, 'M', u'θ'), + (0x3D2, 'M', u'υ'), + (0x3D3, 'M', u'ύ'), + (0x3D4, 'M', u'ϋ'), + (0x3D5, 'M', u'φ'), + (0x3D6, 'M', u'π'), + (0x3D7, 'V'), + (0x3D8, 'M', u'ϙ'), + (0x3D9, 'V'), + (0x3DA, 'M', u'ϛ'), + (0x3DB, 'V'), + (0x3DC, 'M', u'ϝ'), + (0x3DD, 'V'), + (0x3DE, 'M', u'ϟ'), + (0x3DF, 'V'), + (0x3E0, 'M', u'ϡ'), + (0x3E1, 'V'), + (0x3E2, 'M', u'ϣ'), + (0x3E3, 'V'), + (0x3E4, 'M', u'ϥ'), + (0x3E5, 'V'), + (0x3E6, 'M', u'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', u'ϩ'), + (0x3E9, 'V'), + (0x3EA, 'M', u'ϫ'), + (0x3EB, 'V'), + (0x3EC, 'M', u'ϭ'), + (0x3ED, 'V'), + (0x3EE, 'M', u'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', u'κ'), + (0x3F1, 'M', u'ρ'), + (0x3F2, 'M', u'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', u'θ'), + (0x3F5, 'M', u'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', u'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', u'σ'), + (0x3FA, 'M', u'ϻ'), + (0x3FB, 'V'), + (0x3FD, 'M', u'ͻ'), + (0x3FE, 'M', u'ͼ'), + (0x3FF, 'M', u'ͽ'), + (0x400, 'M', u'ѐ'), + (0x401, 'M', u'ё'), + (0x402, 'M', u'ђ'), + (0x403, 'M', u'ѓ'), + ] + +def _seg_7(): + return [ + (0x404, 'M', u'є'), + (0x405, 'M', u'ѕ'), + (0x406, 'M', u'і'), + (0x407, 'M', u'ї'), + (0x408, 'M', u'ј'), + (0x409, 'M', u'љ'), + (0x40A, 'M', u'њ'), + (0x40B, 'M', u'ћ'), + (0x40C, 'M', u'ќ'), + (0x40D, 'M', u'ѝ'), + (0x40E, 'M', u'ў'), + (0x40F, 'M', u'џ'), + (0x410, 'M', u'а'), + (0x411, 'M', u'б'), + (0x412, 'M', u'в'), + (0x413, 'M', u'г'), + (0x414, 'M', u'д'), + (0x415, 'M', u'е'), + (0x416, 'M', u'ж'), + (0x417, 'M', u'з'), + (0x418, 'M', u'и'), + (0x419, 'M', u'й'), + (0x41A, 'M', u'к'), + (0x41B, 'M', u'л'), + (0x41C, 'M', u'м'), + (0x41D, 'M', u'н'), + (0x41E, 'M', u'о'), + (0x41F, 'M', u'п'), + (0x420, 'M', u'р'), + (0x421, 'M', u'с'), + (0x422, 'M', u'т'), + (0x423, 'M', u'у'), + (0x424, 'M', u'ф'), + (0x425, 'M', u'х'), + (0x426, 'M', u'ц'), + (0x427, 'M', u'ч'), + (0x428, 'M', u'ш'), + (0x429, 'M', u'щ'), + (0x42A, 'M', u'ъ'), + (0x42B, 'M', u'ы'), + (0x42C, 'M', u'ь'), + (0x42D, 'M', u'э'), + (0x42E, 'M', u'ю'), + (0x42F, 'M', u'я'), + (0x430, 'V'), + (0x460, 'M', u'ѡ'), + (0x461, 'V'), + (0x462, 'M', u'ѣ'), + (0x463, 'V'), + (0x464, 'M', u'ѥ'), + (0x465, 'V'), + (0x466, 'M', u'ѧ'), + (0x467, 'V'), + (0x468, 'M', u'ѩ'), + (0x469, 'V'), + (0x46A, 'M', u'ѫ'), + (0x46B, 'V'), + (0x46C, 'M', u'ѭ'), + (0x46D, 'V'), + (0x46E, 'M', u'ѯ'), + (0x46F, 'V'), + (0x470, 'M', u'ѱ'), + (0x471, 'V'), + (0x472, 'M', u'ѳ'), + (0x473, 'V'), + (0x474, 'M', u'ѵ'), + (0x475, 'V'), + (0x476, 'M', u'ѷ'), + (0x477, 'V'), + (0x478, 'M', u'ѹ'), + (0x479, 'V'), + (0x47A, 'M', u'ѻ'), + (0x47B, 'V'), + (0x47C, 'M', u'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', u'ѿ'), + (0x47F, 'V'), + (0x480, 'M', u'ҁ'), + (0x481, 'V'), + (0x48A, 'M', u'ҋ'), + (0x48B, 'V'), + (0x48C, 'M', u'ҍ'), + (0x48D, 'V'), + (0x48E, 'M', u'ҏ'), + (0x48F, 'V'), + (0x490, 'M', u'ґ'), + (0x491, 'V'), + (0x492, 'M', u'ғ'), + (0x493, 'V'), + (0x494, 'M', u'ҕ'), + (0x495, 'V'), + (0x496, 'M', u'җ'), + (0x497, 'V'), + (0x498, 'M', u'ҙ'), + (0x499, 'V'), + (0x49A, 'M', u'қ'), + (0x49B, 'V'), + (0x49C, 'M', u'ҝ'), + (0x49D, 'V'), + (0x49E, 'M', u'ҟ'), + ] + +def _seg_8(): + return [ + (0x49F, 'V'), + (0x4A0, 'M', u'ҡ'), + (0x4A1, 'V'), + (0x4A2, 'M', u'ң'), + (0x4A3, 'V'), + (0x4A4, 'M', u'ҥ'), + (0x4A5, 'V'), + (0x4A6, 'M', u'ҧ'), + (0x4A7, 'V'), + (0x4A8, 'M', u'ҩ'), + (0x4A9, 'V'), + (0x4AA, 'M', u'ҫ'), + (0x4AB, 'V'), + (0x4AC, 'M', u'ҭ'), + (0x4AD, 'V'), + (0x4AE, 'M', u'ү'), + (0x4AF, 'V'), + (0x4B0, 'M', u'ұ'), + (0x4B1, 'V'), + (0x4B2, 'M', u'ҳ'), + (0x4B3, 'V'), + (0x4B4, 'M', u'ҵ'), + (0x4B5, 'V'), + (0x4B6, 'M', u'ҷ'), + (0x4B7, 'V'), + (0x4B8, 'M', u'ҹ'), + (0x4B9, 'V'), + (0x4BA, 'M', u'һ'), + (0x4BB, 'V'), + (0x4BC, 'M', u'ҽ'), + (0x4BD, 'V'), + (0x4BE, 'M', u'ҿ'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', u'ӂ'), + (0x4C2, 'V'), + (0x4C3, 'M', u'ӄ'), + (0x4C4, 'V'), + (0x4C5, 'M', u'ӆ'), + (0x4C6, 'V'), + (0x4C7, 'M', u'ӈ'), + (0x4C8, 'V'), + (0x4C9, 'M', u'ӊ'), + (0x4CA, 'V'), + (0x4CB, 'M', u'ӌ'), + (0x4CC, 'V'), + (0x4CD, 'M', u'ӎ'), + (0x4CE, 'V'), + (0x4D0, 'M', u'ӑ'), + (0x4D1, 'V'), + (0x4D2, 'M', u'ӓ'), + (0x4D3, 'V'), + (0x4D4, 'M', u'ӕ'), + (0x4D5, 'V'), + (0x4D6, 'M', u'ӗ'), + (0x4D7, 'V'), + (0x4D8, 'M', u'ә'), + (0x4D9, 'V'), + (0x4DA, 'M', u'ӛ'), + (0x4DB, 'V'), + (0x4DC, 'M', u'ӝ'), + (0x4DD, 'V'), + (0x4DE, 'M', u'ӟ'), + (0x4DF, 'V'), + (0x4E0, 'M', u'ӡ'), + (0x4E1, 'V'), + (0x4E2, 'M', u'ӣ'), + (0x4E3, 'V'), + (0x4E4, 'M', u'ӥ'), + (0x4E5, 'V'), + (0x4E6, 'M', u'ӧ'), + (0x4E7, 'V'), + (0x4E8, 'M', u'ө'), + (0x4E9, 'V'), + (0x4EA, 'M', u'ӫ'), + (0x4EB, 'V'), + (0x4EC, 'M', u'ӭ'), + (0x4ED, 'V'), + (0x4EE, 'M', u'ӯ'), + (0x4EF, 'V'), + (0x4F0, 'M', u'ӱ'), + (0x4F1, 'V'), + (0x4F2, 'M', u'ӳ'), + (0x4F3, 'V'), + (0x4F4, 'M', u'ӵ'), + (0x4F5, 'V'), + (0x4F6, 'M', u'ӷ'), + (0x4F7, 'V'), + (0x4F8, 'M', u'ӹ'), + (0x4F9, 'V'), + (0x4FA, 'M', u'ӻ'), + (0x4FB, 'V'), + (0x4FC, 'M', u'ӽ'), + (0x4FD, 'V'), + (0x4FE, 'M', u'ӿ'), + (0x4FF, 'V'), + (0x500, 'M', u'ԁ'), + (0x501, 'V'), + (0x502, 'M', u'ԃ'), + (0x503, 'V'), + ] + +def _seg_9(): + return [ + (0x504, 'M', u'ԅ'), + (0x505, 'V'), + (0x506, 'M', u'ԇ'), + (0x507, 'V'), + (0x508, 'M', u'ԉ'), + (0x509, 'V'), + (0x50A, 'M', u'ԋ'), + (0x50B, 'V'), + (0x50C, 'M', u'ԍ'), + (0x50D, 'V'), + (0x50E, 'M', u'ԏ'), + (0x50F, 'V'), + (0x510, 'M', u'ԑ'), + (0x511, 'V'), + (0x512, 'M', u'ԓ'), + (0x513, 'V'), + (0x514, 'M', u'ԕ'), + (0x515, 'V'), + (0x516, 'M', u'ԗ'), + (0x517, 'V'), + (0x518, 'M', u'ԙ'), + (0x519, 'V'), + (0x51A, 'M', u'ԛ'), + (0x51B, 'V'), + (0x51C, 'M', u'ԝ'), + (0x51D, 'V'), + (0x51E, 'M', u'ԟ'), + (0x51F, 'V'), + (0x520, 'M', u'ԡ'), + (0x521, 'V'), + (0x522, 'M', u'ԣ'), + (0x523, 'V'), + (0x524, 'M', u'ԥ'), + (0x525, 'V'), + (0x526, 'M', u'ԧ'), + (0x527, 'V'), + (0x528, 'X'), + (0x531, 'M', u'ա'), + (0x532, 'M', u'բ'), + (0x533, 'M', u'գ'), + (0x534, 'M', u'դ'), + (0x535, 'M', u'ե'), + (0x536, 'M', u'զ'), + (0x537, 'M', u'է'), + (0x538, 'M', u'ը'), + (0x539, 'M', u'թ'), + (0x53A, 'M', u'ժ'), + (0x53B, 'M', u'ի'), + (0x53C, 'M', u'լ'), + (0x53D, 'M', u'խ'), + (0x53E, 'M', u'ծ'), + (0x53F, 'M', u'կ'), + (0x540, 'M', u'հ'), + (0x541, 'M', u'ձ'), + (0x542, 'M', u'ղ'), + (0x543, 'M', u'ճ'), + (0x544, 'M', u'մ'), + (0x545, 'M', u'յ'), + (0x546, 'M', u'ն'), + (0x547, 'M', u'շ'), + (0x548, 'M', u'ո'), + (0x549, 'M', u'չ'), + (0x54A, 'M', u'պ'), + (0x54B, 'M', u'ջ'), + (0x54C, 'M', u'ռ'), + (0x54D, 'M', u'ս'), + (0x54E, 'M', u'վ'), + (0x54F, 'M', u'տ'), + (0x550, 'M', u'ր'), + (0x551, 'M', u'ց'), + (0x552, 'M', u'ւ'), + (0x553, 'M', u'փ'), + (0x554, 'M', u'ք'), + (0x555, 'M', u'օ'), + (0x556, 'M', u'ֆ'), + (0x557, 'X'), + (0x559, 'V'), + (0x560, 'X'), + (0x561, 'V'), + (0x587, 'M', u'եւ'), + (0x588, 'X'), + (0x589, 'V'), + (0x58B, 'X'), + (0x58F, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5F0, 'V'), + (0x5F5, 'X'), + (0x606, 'V'), + (0x61C, 'X'), + (0x61E, 'V'), + (0x675, 'M', u'اٴ'), + (0x676, 'M', u'وٴ'), + (0x677, 'M', u'ۇٴ'), + (0x678, 'M', u'يٴ'), + (0x679, 'V'), + (0x6DD, 'X'), + ] + +def _seg_10(): + return [ + (0x6DE, 'V'), + (0x70E, 'X'), + (0x710, 'V'), + (0x74B, 'X'), + (0x74D, 'V'), + (0x7B2, 'X'), + (0x7C0, 'V'), + (0x7FB, 'X'), + (0x800, 'V'), + (0x82E, 'X'), + (0x830, 'V'), + (0x83F, 'X'), + (0x840, 'V'), + (0x85C, 'X'), + (0x85E, 'V'), + (0x85F, 'X'), + (0x8A0, 'V'), + (0x8A1, 'X'), + (0x8A2, 'V'), + (0x8AD, 'X'), + (0x8E4, 'V'), + (0x8FF, 'X'), + (0x900, 'V'), + (0x958, 'M', u'क़'), + (0x959, 'M', u'ख़'), + (0x95A, 'M', u'ग़'), + (0x95B, 'M', u'ज़'), + (0x95C, 'M', u'ड़'), + (0x95D, 'M', u'ढ़'), + (0x95E, 'M', u'फ़'), + (0x95F, 'M', u'य़'), + (0x960, 'V'), + (0x978, 'X'), + (0x979, 'V'), + (0x980, 'X'), + (0x981, 'V'), + (0x984, 'X'), + (0x985, 'V'), + (0x98D, 'X'), + (0x98F, 'V'), + (0x991, 'X'), + (0x993, 'V'), + (0x9A9, 'X'), + (0x9AA, 'V'), + (0x9B1, 'X'), + (0x9B2, 'V'), + (0x9B3, 'X'), + (0x9B6, 'V'), + (0x9BA, 'X'), + (0x9BC, 'V'), + (0x9C5, 'X'), + (0x9C7, 'V'), + (0x9C9, 'X'), + (0x9CB, 'V'), + (0x9CF, 'X'), + (0x9D7, 'V'), + (0x9D8, 'X'), + (0x9DC, 'M', u'ড়'), + (0x9DD, 'M', u'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', u'য়'), + (0x9E0, 'V'), + (0x9E4, 'X'), + (0x9E6, 'V'), + (0x9FC, 'X'), + (0xA01, 'V'), + (0xA04, 'X'), + (0xA05, 'V'), + (0xA0B, 'X'), + (0xA0F, 'V'), + (0xA11, 'X'), + (0xA13, 'V'), + (0xA29, 'X'), + (0xA2A, 'V'), + (0xA31, 'X'), + (0xA32, 'V'), + (0xA33, 'M', u'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', u'ਸ਼'), + (0xA37, 'X'), + (0xA38, 'V'), + (0xA3A, 'X'), + (0xA3C, 'V'), + (0xA3D, 'X'), + (0xA3E, 'V'), + (0xA43, 'X'), + (0xA47, 'V'), + (0xA49, 'X'), + (0xA4B, 'V'), + (0xA4E, 'X'), + (0xA51, 'V'), + (0xA52, 'X'), + (0xA59, 'M', u'ਖ਼'), + (0xA5A, 'M', u'ਗ਼'), + (0xA5B, 'M', u'ਜ਼'), + (0xA5C, 'V'), + (0xA5D, 'X'), + (0xA5E, 'M', u'ਫ਼'), + (0xA5F, 'X'), + ] + +def _seg_11(): + return [ + (0xA66, 'V'), + (0xA76, 'X'), + (0xA81, 'V'), + (0xA84, 'X'), + (0xA85, 'V'), + (0xA8E, 'X'), + (0xA8F, 'V'), + (0xA92, 'X'), + (0xA93, 'V'), + (0xAA9, 'X'), + (0xAAA, 'V'), + (0xAB1, 'X'), + (0xAB2, 'V'), + (0xAB4, 'X'), + (0xAB5, 'V'), + (0xABA, 'X'), + (0xABC, 'V'), + (0xAC6, 'X'), + (0xAC7, 'V'), + (0xACA, 'X'), + (0xACB, 'V'), + (0xACE, 'X'), + (0xAD0, 'V'), + (0xAD1, 'X'), + (0xAE0, 'V'), + (0xAE4, 'X'), + (0xAE6, 'V'), + (0xAF2, 'X'), + (0xB01, 'V'), + (0xB04, 'X'), + (0xB05, 'V'), + (0xB0D, 'X'), + (0xB0F, 'V'), + (0xB11, 'X'), + (0xB13, 'V'), + (0xB29, 'X'), + (0xB2A, 'V'), + (0xB31, 'X'), + (0xB32, 'V'), + (0xB34, 'X'), + (0xB35, 'V'), + (0xB3A, 'X'), + (0xB3C, 'V'), + (0xB45, 'X'), + (0xB47, 'V'), + (0xB49, 'X'), + (0xB4B, 'V'), + (0xB4E, 'X'), + (0xB56, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', u'ଡ଼'), + (0xB5D, 'M', u'ଢ଼'), + (0xB5E, 'X'), + (0xB5F, 'V'), + (0xB64, 'X'), + (0xB66, 'V'), + (0xB78, 'X'), + (0xB82, 'V'), + (0xB84, 'X'), + (0xB85, 'V'), + (0xB8B, 'X'), + (0xB8E, 'V'), + (0xB91, 'X'), + (0xB92, 'V'), + (0xB96, 'X'), + (0xB99, 'V'), + (0xB9B, 'X'), + (0xB9C, 'V'), + (0xB9D, 'X'), + (0xB9E, 'V'), + (0xBA0, 'X'), + (0xBA3, 'V'), + (0xBA5, 'X'), + (0xBA8, 'V'), + (0xBAB, 'X'), + (0xBAE, 'V'), + (0xBBA, 'X'), + (0xBBE, 'V'), + (0xBC3, 'X'), + (0xBC6, 'V'), + (0xBC9, 'X'), + (0xBCA, 'V'), + (0xBCE, 'X'), + (0xBD0, 'V'), + (0xBD1, 'X'), + (0xBD7, 'V'), + (0xBD8, 'X'), + (0xBE6, 'V'), + (0xBFB, 'X'), + (0xC01, 'V'), + (0xC04, 'X'), + (0xC05, 'V'), + (0xC0D, 'X'), + (0xC0E, 'V'), + (0xC11, 'X'), + (0xC12, 'V'), + (0xC29, 'X'), + (0xC2A, 'V'), + (0xC34, 'X'), + (0xC35, 'V'), + ] + +def _seg_12(): + return [ + (0xC3A, 'X'), + (0xC3D, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5A, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC78, 'V'), + (0xC80, 'X'), + (0xC82, 'V'), + (0xC84, 'X'), + (0xC85, 'V'), + (0xC8D, 'X'), + (0xC8E, 'V'), + (0xC91, 'X'), + (0xC92, 'V'), + (0xCA9, 'X'), + (0xCAA, 'V'), + (0xCB4, 'X'), + (0xCB5, 'V'), + (0xCBA, 'X'), + (0xCBC, 'V'), + (0xCC5, 'X'), + (0xCC6, 'V'), + (0xCC9, 'X'), + (0xCCA, 'V'), + (0xCCE, 'X'), + (0xCD5, 'V'), + (0xCD7, 'X'), + (0xCDE, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF3, 'X'), + (0xD02, 'V'), + (0xD04, 'X'), + (0xD05, 'V'), + (0xD0D, 'X'), + (0xD0E, 'V'), + (0xD11, 'X'), + (0xD12, 'V'), + (0xD3B, 'X'), + (0xD3D, 'V'), + (0xD45, 'X'), + (0xD46, 'V'), + (0xD49, 'X'), + (0xD4A, 'V'), + (0xD4F, 'X'), + (0xD57, 'V'), + (0xD58, 'X'), + (0xD60, 'V'), + (0xD64, 'X'), + (0xD66, 'V'), + (0xD76, 'X'), + (0xD79, 'V'), + (0xD80, 'X'), + (0xD82, 'V'), + (0xD84, 'X'), + (0xD85, 'V'), + (0xD97, 'X'), + (0xD9A, 'V'), + (0xDB2, 'X'), + (0xDB3, 'V'), + (0xDBC, 'X'), + (0xDBD, 'V'), + (0xDBE, 'X'), + (0xDC0, 'V'), + (0xDC7, 'X'), + (0xDCA, 'V'), + (0xDCB, 'X'), + (0xDCF, 'V'), + (0xDD5, 'X'), + (0xDD6, 'V'), + (0xDD7, 'X'), + (0xDD8, 'V'), + (0xDE0, 'X'), + (0xDF2, 'V'), + (0xDF5, 'X'), + (0xE01, 'V'), + (0xE33, 'M', u'ํา'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + (0xE87, 'V'), + ] + +def _seg_13(): + return [ + (0xE89, 'X'), + (0xE8A, 'V'), + (0xE8B, 'X'), + (0xE8D, 'V'), + (0xE8E, 'X'), + (0xE94, 'V'), + (0xE98, 'X'), + (0xE99, 'V'), + (0xEA0, 'X'), + (0xEA1, 'V'), + (0xEA4, 'X'), + (0xEA5, 'V'), + (0xEA6, 'X'), + (0xEA7, 'V'), + (0xEA8, 'X'), + (0xEAA, 'V'), + (0xEAC, 'X'), + (0xEAD, 'V'), + (0xEB3, 'M', u'ໍາ'), + (0xEB4, 'V'), + (0xEBA, 'X'), + (0xEBB, 'V'), + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECE, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', u'ຫນ'), + (0xEDD, 'M', u'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', u'་'), + (0xF0D, 'V'), + (0xF43, 'M', u'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', u'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', u'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', u'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', u'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', u'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', u'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', u'ཱུ'), + (0xF76, 'M', u'ྲྀ'), + (0xF77, 'M', u'ྲཱྀ'), + (0xF78, 'M', u'ླྀ'), + (0xF79, 'M', u'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', u'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', u'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', u'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', u'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', u'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', u'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', u'ྐྵ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', u'ⴧ'), + (0x10C8, 'X'), + (0x10CD, 'M', u'ⴭ'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', u'ნ'), + (0x10FD, 'V'), + (0x115F, 'X'), + (0x1161, 'V'), + (0x1249, 'X'), + (0x124A, 'V'), + (0x124E, 'X'), + (0x1250, 'V'), + (0x1257, 'X'), + (0x1258, 'V'), + ] + +def _seg_14(): + return [ + (0x1259, 'X'), + (0x125A, 'V'), + (0x125E, 'X'), + (0x1260, 'V'), + (0x1289, 'X'), + (0x128A, 'V'), + (0x128E, 'X'), + (0x1290, 'V'), + (0x12B1, 'X'), + (0x12B2, 'V'), + (0x12B6, 'X'), + (0x12B8, 'V'), + (0x12BF, 'X'), + (0x12C0, 'V'), + (0x12C1, 'X'), + (0x12C2, 'V'), + (0x12C6, 'X'), + (0x12C8, 'V'), + (0x12D7, 'X'), + (0x12D8, 'V'), + (0x1311, 'X'), + (0x1312, 'V'), + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F5, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F1, 'X'), + (0x1700, 'V'), + (0x170D, 'X'), + (0x170E, 'V'), + (0x1715, 'X'), + (0x1720, 'V'), + (0x1737, 'X'), + (0x1740, 'V'), + (0x1754, 'X'), + (0x1760, 'V'), + (0x176D, 'X'), + (0x176E, 'V'), + (0x1771, 'X'), + (0x1772, 'V'), + (0x1774, 'X'), + (0x1780, 'V'), + (0x17B4, 'X'), + (0x17B6, 'V'), + (0x17DE, 'X'), + (0x17E0, 'V'), + (0x17EA, 'X'), + (0x17F0, 'V'), + (0x17FA, 'X'), + (0x1800, 'V'), + (0x1806, 'X'), + (0x1807, 'V'), + (0x180B, 'I'), + (0x180E, 'X'), + (0x1810, 'V'), + (0x181A, 'X'), + (0x1820, 'V'), + (0x1878, 'X'), + (0x1880, 'V'), + (0x18AB, 'X'), + (0x18B0, 'V'), + (0x18F6, 'X'), + (0x1900, 'V'), + (0x191D, 'X'), + (0x1920, 'V'), + (0x192C, 'X'), + (0x1930, 'V'), + (0x193C, 'X'), + (0x1940, 'V'), + (0x1941, 'X'), + (0x1944, 'V'), + (0x196E, 'X'), + (0x1970, 'V'), + (0x1975, 'X'), + (0x1980, 'V'), + (0x19AC, 'X'), + (0x19B0, 'V'), + (0x19CA, 'X'), + (0x19D0, 'V'), + (0x19DB, 'X'), + (0x19DE, 'V'), + (0x1A1C, 'X'), + (0x1A1E, 'V'), + (0x1A5F, 'X'), + (0x1A60, 'V'), + (0x1A7D, 'X'), + (0x1A7F, 'V'), + (0x1A8A, 'X'), + (0x1A90, 'V'), + (0x1A9A, 'X'), + ] + +def _seg_15(): + return [ + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1B00, 'V'), + (0x1B4C, 'X'), + (0x1B50, 'V'), + (0x1B7D, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + (0x1C80, 'X'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CF7, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', u'a'), + (0x1D2D, 'M', u'æ'), + (0x1D2E, 'M', u'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', u'd'), + (0x1D31, 'M', u'e'), + (0x1D32, 'M', u'ǝ'), + (0x1D33, 'M', u'g'), + (0x1D34, 'M', u'h'), + (0x1D35, 'M', u'i'), + (0x1D36, 'M', u'j'), + (0x1D37, 'M', u'k'), + (0x1D38, 'M', u'l'), + (0x1D39, 'M', u'm'), + (0x1D3A, 'M', u'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', u'o'), + (0x1D3D, 'M', u'ȣ'), + (0x1D3E, 'M', u'p'), + (0x1D3F, 'M', u'r'), + (0x1D40, 'M', u't'), + (0x1D41, 'M', u'u'), + (0x1D42, 'M', u'w'), + (0x1D43, 'M', u'a'), + (0x1D44, 'M', u'ɐ'), + (0x1D45, 'M', u'ɑ'), + (0x1D46, 'M', u'ᴂ'), + (0x1D47, 'M', u'b'), + (0x1D48, 'M', u'd'), + (0x1D49, 'M', u'e'), + (0x1D4A, 'M', u'ə'), + (0x1D4B, 'M', u'ɛ'), + (0x1D4C, 'M', u'ɜ'), + (0x1D4D, 'M', u'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', u'k'), + (0x1D50, 'M', u'm'), + (0x1D51, 'M', u'ŋ'), + (0x1D52, 'M', u'o'), + (0x1D53, 'M', u'ɔ'), + (0x1D54, 'M', u'ᴖ'), + (0x1D55, 'M', u'ᴗ'), + (0x1D56, 'M', u'p'), + (0x1D57, 'M', u't'), + (0x1D58, 'M', u'u'), + (0x1D59, 'M', u'ᴝ'), + (0x1D5A, 'M', u'ɯ'), + (0x1D5B, 'M', u'v'), + (0x1D5C, 'M', u'ᴥ'), + (0x1D5D, 'M', u'β'), + (0x1D5E, 'M', u'γ'), + (0x1D5F, 'M', u'δ'), + (0x1D60, 'M', u'φ'), + (0x1D61, 'M', u'χ'), + (0x1D62, 'M', u'i'), + (0x1D63, 'M', u'r'), + (0x1D64, 'M', u'u'), + (0x1D65, 'M', u'v'), + (0x1D66, 'M', u'β'), + (0x1D67, 'M', u'γ'), + (0x1D68, 'M', u'ρ'), + (0x1D69, 'M', u'φ'), + (0x1D6A, 'M', u'χ'), + (0x1D6B, 'V'), + (0x1D78, 'M', u'н'), + (0x1D79, 'V'), + (0x1D9B, 'M', u'ɒ'), + (0x1D9C, 'M', u'c'), + (0x1D9D, 'M', u'ɕ'), + (0x1D9E, 'M', u'ð'), + (0x1D9F, 'M', u'ɜ'), + (0x1DA0, 'M', u'f'), + (0x1DA1, 'M', u'ɟ'), + (0x1DA2, 'M', u'ɡ'), + (0x1DA3, 'M', u'ɥ'), + (0x1DA4, 'M', u'ɨ'), + (0x1DA5, 'M', u'ɩ'), + (0x1DA6, 'M', u'ɪ'), + (0x1DA7, 'M', u'ᵻ'), + (0x1DA8, 'M', u'ʝ'), + (0x1DA9, 'M', u'ɭ'), + ] + +def _seg_16(): + return [ + (0x1DAA, 'M', u'ᶅ'), + (0x1DAB, 'M', u'ʟ'), + (0x1DAC, 'M', u'ɱ'), + (0x1DAD, 'M', u'ɰ'), + (0x1DAE, 'M', u'ɲ'), + (0x1DAF, 'M', u'ɳ'), + (0x1DB0, 'M', u'ɴ'), + (0x1DB1, 'M', u'ɵ'), + (0x1DB2, 'M', u'ɸ'), + (0x1DB3, 'M', u'ʂ'), + (0x1DB4, 'M', u'ʃ'), + (0x1DB5, 'M', u'ƫ'), + (0x1DB6, 'M', u'ʉ'), + (0x1DB7, 'M', u'ʊ'), + (0x1DB8, 'M', u'ᴜ'), + (0x1DB9, 'M', u'ʋ'), + (0x1DBA, 'M', u'ʌ'), + (0x1DBB, 'M', u'z'), + (0x1DBC, 'M', u'ʐ'), + (0x1DBD, 'M', u'ʑ'), + (0x1DBE, 'M', u'ʒ'), + (0x1DBF, 'M', u'θ'), + (0x1DC0, 'V'), + (0x1DE7, 'X'), + (0x1DFC, 'V'), + (0x1E00, 'M', u'ḁ'), + (0x1E01, 'V'), + (0x1E02, 'M', u'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', u'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', u'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', u'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', u'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', u'ḍ'), + (0x1E0D, 'V'), + (0x1E0E, 'M', u'ḏ'), + (0x1E0F, 'V'), + (0x1E10, 'M', u'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', u'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', u'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', u'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', u'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', u'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', u'ḝ'), + (0x1E1D, 'V'), + (0x1E1E, 'M', u'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', u'ḡ'), + (0x1E21, 'V'), + (0x1E22, 'M', u'ḣ'), + (0x1E23, 'V'), + (0x1E24, 'M', u'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', u'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', u'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', u'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', u'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', u'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', u'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', u'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', u'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', u'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', u'ḹ'), + (0x1E39, 'V'), + (0x1E3A, 'M', u'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', u'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', u'ḿ'), + (0x1E3F, 'V'), + (0x1E40, 'M', u'ṁ'), + (0x1E41, 'V'), + (0x1E42, 'M', u'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', u'ṅ'), + (0x1E45, 'V'), + (0x1E46, 'M', u'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', u'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', u'ṋ'), + ] + +def _seg_17(): + return [ + (0x1E4B, 'V'), + (0x1E4C, 'M', u'ṍ'), + (0x1E4D, 'V'), + (0x1E4E, 'M', u'ṏ'), + (0x1E4F, 'V'), + (0x1E50, 'M', u'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', u'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', u'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', u'ṗ'), + (0x1E57, 'V'), + (0x1E58, 'M', u'ṙ'), + (0x1E59, 'V'), + (0x1E5A, 'M', u'ṛ'), + (0x1E5B, 'V'), + (0x1E5C, 'M', u'ṝ'), + (0x1E5D, 'V'), + (0x1E5E, 'M', u'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', u'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', u'ṣ'), + (0x1E63, 'V'), + (0x1E64, 'M', u'ṥ'), + (0x1E65, 'V'), + (0x1E66, 'M', u'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', u'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', u'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', u'ṭ'), + (0x1E6D, 'V'), + (0x1E6E, 'M', u'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', u'ṱ'), + (0x1E71, 'V'), + (0x1E72, 'M', u'ṳ'), + (0x1E73, 'V'), + (0x1E74, 'M', u'ṵ'), + (0x1E75, 'V'), + (0x1E76, 'M', u'ṷ'), + (0x1E77, 'V'), + (0x1E78, 'M', u'ṹ'), + (0x1E79, 'V'), + (0x1E7A, 'M', u'ṻ'), + (0x1E7B, 'V'), + (0x1E7C, 'M', u'ṽ'), + (0x1E7D, 'V'), + (0x1E7E, 'M', u'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', u'ẁ'), + (0x1E81, 'V'), + (0x1E82, 'M', u'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', u'ẅ'), + (0x1E85, 'V'), + (0x1E86, 'M', u'ẇ'), + (0x1E87, 'V'), + (0x1E88, 'M', u'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', u'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', u'ẍ'), + (0x1E8D, 'V'), + (0x1E8E, 'M', u'ẏ'), + (0x1E8F, 'V'), + (0x1E90, 'M', u'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', u'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', u'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', u'aʾ'), + (0x1E9B, 'M', u'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', u'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', u'ạ'), + (0x1EA1, 'V'), + (0x1EA2, 'M', u'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', u'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', u'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', u'ẩ'), + (0x1EA9, 'V'), + (0x1EAA, 'M', u'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', u'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', u'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', u'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', u'ẳ'), + (0x1EB3, 'V'), + ] + +def _seg_18(): + return [ + (0x1EB4, 'M', u'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', u'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', u'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', u'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', u'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', u'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', u'ề'), + (0x1EC1, 'V'), + (0x1EC2, 'M', u'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', u'ễ'), + (0x1EC5, 'V'), + (0x1EC6, 'M', u'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', u'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', u'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', u'ọ'), + (0x1ECD, 'V'), + (0x1ECE, 'M', u'ỏ'), + (0x1ECF, 'V'), + (0x1ED0, 'M', u'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', u'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', u'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', u'ỗ'), + (0x1ED7, 'V'), + (0x1ED8, 'M', u'ộ'), + (0x1ED9, 'V'), + (0x1EDA, 'M', u'ớ'), + (0x1EDB, 'V'), + (0x1EDC, 'M', u'ờ'), + (0x1EDD, 'V'), + (0x1EDE, 'M', u'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', u'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', u'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', u'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', u'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', u'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', u'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', u'ử'), + (0x1EED, 'V'), + (0x1EEE, 'M', u'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', u'ự'), + (0x1EF1, 'V'), + (0x1EF2, 'M', u'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', u'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', u'ỷ'), + (0x1EF7, 'V'), + (0x1EF8, 'M', u'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', u'ỻ'), + (0x1EFB, 'V'), + (0x1EFC, 'M', u'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', u'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', u'ἀ'), + (0x1F09, 'M', u'ἁ'), + (0x1F0A, 'M', u'ἂ'), + (0x1F0B, 'M', u'ἃ'), + (0x1F0C, 'M', u'ἄ'), + (0x1F0D, 'M', u'ἅ'), + (0x1F0E, 'M', u'ἆ'), + (0x1F0F, 'M', u'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', u'ἐ'), + (0x1F19, 'M', u'ἑ'), + (0x1F1A, 'M', u'ἒ'), + (0x1F1B, 'M', u'ἓ'), + (0x1F1C, 'M', u'ἔ'), + (0x1F1D, 'M', u'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', u'ἠ'), + (0x1F29, 'M', u'ἡ'), + (0x1F2A, 'M', u'ἢ'), + (0x1F2B, 'M', u'ἣ'), + (0x1F2C, 'M', u'ἤ'), + (0x1F2D, 'M', u'ἥ'), + ] + +def _seg_19(): + return [ + (0x1F2E, 'M', u'ἦ'), + (0x1F2F, 'M', u'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', u'ἰ'), + (0x1F39, 'M', u'ἱ'), + (0x1F3A, 'M', u'ἲ'), + (0x1F3B, 'M', u'ἳ'), + (0x1F3C, 'M', u'ἴ'), + (0x1F3D, 'M', u'ἵ'), + (0x1F3E, 'M', u'ἶ'), + (0x1F3F, 'M', u'ἷ'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', u'ὀ'), + (0x1F49, 'M', u'ὁ'), + (0x1F4A, 'M', u'ὂ'), + (0x1F4B, 'M', u'ὃ'), + (0x1F4C, 'M', u'ὄ'), + (0x1F4D, 'M', u'ὅ'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', u'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', u'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', u'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', u'ὗ'), + (0x1F60, 'V'), + (0x1F68, 'M', u'ὠ'), + (0x1F69, 'M', u'ὡ'), + (0x1F6A, 'M', u'ὢ'), + (0x1F6B, 'M', u'ὣ'), + (0x1F6C, 'M', u'ὤ'), + (0x1F6D, 'M', u'ὥ'), + (0x1F6E, 'M', u'ὦ'), + (0x1F6F, 'M', u'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', u'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', u'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', u'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', u'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', u'ό'), + (0x1F7A, 'V'), + (0x1F7B, 'M', u'ύ'), + (0x1F7C, 'V'), + (0x1F7D, 'M', u'ώ'), + (0x1F7E, 'X'), + (0x1F80, 'M', u'ἀι'), + (0x1F81, 'M', u'ἁι'), + (0x1F82, 'M', u'ἂι'), + (0x1F83, 'M', u'ἃι'), + (0x1F84, 'M', u'ἄι'), + (0x1F85, 'M', u'ἅι'), + (0x1F86, 'M', u'ἆι'), + (0x1F87, 'M', u'ἇι'), + (0x1F88, 'M', u'ἀι'), + (0x1F89, 'M', u'ἁι'), + (0x1F8A, 'M', u'ἂι'), + (0x1F8B, 'M', u'ἃι'), + (0x1F8C, 'M', u'ἄι'), + (0x1F8D, 'M', u'ἅι'), + (0x1F8E, 'M', u'ἆι'), + (0x1F8F, 'M', u'ἇι'), + (0x1F90, 'M', u'ἠι'), + (0x1F91, 'M', u'ἡι'), + (0x1F92, 'M', u'ἢι'), + (0x1F93, 'M', u'ἣι'), + (0x1F94, 'M', u'ἤι'), + (0x1F95, 'M', u'ἥι'), + (0x1F96, 'M', u'ἦι'), + (0x1F97, 'M', u'ἧι'), + (0x1F98, 'M', u'ἠι'), + (0x1F99, 'M', u'ἡι'), + (0x1F9A, 'M', u'ἢι'), + (0x1F9B, 'M', u'ἣι'), + (0x1F9C, 'M', u'ἤι'), + (0x1F9D, 'M', u'ἥι'), + (0x1F9E, 'M', u'ἦι'), + (0x1F9F, 'M', u'ἧι'), + (0x1FA0, 'M', u'ὠι'), + (0x1FA1, 'M', u'ὡι'), + (0x1FA2, 'M', u'ὢι'), + (0x1FA3, 'M', u'ὣι'), + (0x1FA4, 'M', u'ὤι'), + (0x1FA5, 'M', u'ὥι'), + (0x1FA6, 'M', u'ὦι'), + (0x1FA7, 'M', u'ὧι'), + (0x1FA8, 'M', u'ὠι'), + (0x1FA9, 'M', u'ὡι'), + (0x1FAA, 'M', u'ὢι'), + (0x1FAB, 'M', u'ὣι'), + (0x1FAC, 'M', u'ὤι'), + (0x1FAD, 'M', u'ὥι'), + (0x1FAE, 'M', u'ὦι'), + ] + +def _seg_20(): + return [ + (0x1FAF, 'M', u'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', u'ὰι'), + (0x1FB3, 'M', u'αι'), + (0x1FB4, 'M', u'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', u'ᾶι'), + (0x1FB8, 'M', u'ᾰ'), + (0x1FB9, 'M', u'ᾱ'), + (0x1FBA, 'M', u'ὰ'), + (0x1FBB, 'M', u'ά'), + (0x1FBC, 'M', u'αι'), + (0x1FBD, '3', u' ̓'), + (0x1FBE, 'M', u'ι'), + (0x1FBF, '3', u' ̓'), + (0x1FC0, '3', u' ͂'), + (0x1FC1, '3', u' ̈͂'), + (0x1FC2, 'M', u'ὴι'), + (0x1FC3, 'M', u'ηι'), + (0x1FC4, 'M', u'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', u'ῆι'), + (0x1FC8, 'M', u'ὲ'), + (0x1FC9, 'M', u'έ'), + (0x1FCA, 'M', u'ὴ'), + (0x1FCB, 'M', u'ή'), + (0x1FCC, 'M', u'ηι'), + (0x1FCD, '3', u' ̓̀'), + (0x1FCE, '3', u' ̓́'), + (0x1FCF, '3', u' ̓͂'), + (0x1FD0, 'V'), + (0x1FD3, 'M', u'ΐ'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', u'ῐ'), + (0x1FD9, 'M', u'ῑ'), + (0x1FDA, 'M', u'ὶ'), + (0x1FDB, 'M', u'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', u' ̔̀'), + (0x1FDE, '3', u' ̔́'), + (0x1FDF, '3', u' ̔͂'), + (0x1FE0, 'V'), + (0x1FE3, 'M', u'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', u'ῠ'), + (0x1FE9, 'M', u'ῡ'), + (0x1FEA, 'M', u'ὺ'), + (0x1FEB, 'M', u'ύ'), + (0x1FEC, 'M', u'ῥ'), + (0x1FED, '3', u' ̈̀'), + (0x1FEE, '3', u' ̈́'), + (0x1FEF, '3', u'`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', u'ὼι'), + (0x1FF3, 'M', u'ωι'), + (0x1FF4, 'M', u'ώι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + (0x1FF7, 'M', u'ῶι'), + (0x1FF8, 'M', u'ὸ'), + (0x1FF9, 'M', u'ό'), + (0x1FFA, 'M', u'ὼ'), + (0x1FFB, 'M', u'ώ'), + (0x1FFC, 'M', u'ωι'), + (0x1FFD, '3', u' ́'), + (0x1FFE, '3', u' ̔'), + (0x1FFF, 'X'), + (0x2000, '3', u' '), + (0x200B, 'I'), + (0x200C, 'D', u''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', u'‐'), + (0x2012, 'V'), + (0x2017, '3', u' ̳'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + (0x202F, '3', u' '), + (0x2030, 'V'), + (0x2033, 'M', u'′′'), + (0x2034, 'M', u'′′′'), + (0x2035, 'V'), + (0x2036, 'M', u'‵‵'), + (0x2037, 'M', u'‵‵‵'), + (0x2038, 'V'), + (0x203C, '3', u'!!'), + (0x203D, 'V'), + (0x203E, '3', u' ̅'), + (0x203F, 'V'), + (0x2047, '3', u'??'), + (0x2048, '3', u'?!'), + (0x2049, '3', u'!?'), + (0x204A, 'V'), + (0x2057, 'M', u'′′′′'), + (0x2058, 'V'), + ] + +def _seg_21(): + return [ + (0x205F, '3', u' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', u'0'), + (0x2071, 'M', u'i'), + (0x2072, 'X'), + (0x2074, 'M', u'4'), + (0x2075, 'M', u'5'), + (0x2076, 'M', u'6'), + (0x2077, 'M', u'7'), + (0x2078, 'M', u'8'), + (0x2079, 'M', u'9'), + (0x207A, '3', u'+'), + (0x207B, 'M', u'−'), + (0x207C, '3', u'='), + (0x207D, '3', u'('), + (0x207E, '3', u')'), + (0x207F, 'M', u'n'), + (0x2080, 'M', u'0'), + (0x2081, 'M', u'1'), + (0x2082, 'M', u'2'), + (0x2083, 'M', u'3'), + (0x2084, 'M', u'4'), + (0x2085, 'M', u'5'), + (0x2086, 'M', u'6'), + (0x2087, 'M', u'7'), + (0x2088, 'M', u'8'), + (0x2089, 'M', u'9'), + (0x208A, '3', u'+'), + (0x208B, 'M', u'−'), + (0x208C, '3', u'='), + (0x208D, '3', u'('), + (0x208E, '3', u')'), + (0x208F, 'X'), + (0x2090, 'M', u'a'), + (0x2091, 'M', u'e'), + (0x2092, 'M', u'o'), + (0x2093, 'M', u'x'), + (0x2094, 'M', u'ə'), + (0x2095, 'M', u'h'), + (0x2096, 'M', u'k'), + (0x2097, 'M', u'l'), + (0x2098, 'M', u'm'), + (0x2099, 'M', u'n'), + (0x209A, 'M', u'p'), + (0x209B, 'M', u's'), + (0x209C, 'M', u't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', u'rs'), + (0x20A9, 'V'), + (0x20BB, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', u'a/c'), + (0x2101, '3', u'a/s'), + (0x2102, 'M', u'c'), + (0x2103, 'M', u'°c'), + (0x2104, 'V'), + (0x2105, '3', u'c/o'), + (0x2106, '3', u'c/u'), + (0x2107, 'M', u'ɛ'), + (0x2108, 'V'), + (0x2109, 'M', u'°f'), + (0x210A, 'M', u'g'), + (0x210B, 'M', u'h'), + (0x210F, 'M', u'ħ'), + (0x2110, 'M', u'i'), + (0x2112, 'M', u'l'), + (0x2114, 'V'), + (0x2115, 'M', u'n'), + (0x2116, 'M', u'no'), + (0x2117, 'V'), + (0x2119, 'M', u'p'), + (0x211A, 'M', u'q'), + (0x211B, 'M', u'r'), + (0x211E, 'V'), + (0x2120, 'M', u'sm'), + (0x2121, 'M', u'tel'), + (0x2122, 'M', u'tm'), + (0x2123, 'V'), + (0x2124, 'M', u'z'), + (0x2125, 'V'), + (0x2126, 'M', u'ω'), + (0x2127, 'V'), + (0x2128, 'M', u'z'), + (0x2129, 'V'), + (0x212A, 'M', u'k'), + (0x212B, 'M', u'å'), + (0x212C, 'M', u'b'), + (0x212D, 'M', u'c'), + (0x212E, 'V'), + (0x212F, 'M', u'e'), + (0x2131, 'M', u'f'), + (0x2132, 'X'), + (0x2133, 'M', u'm'), + (0x2134, 'M', u'o'), + (0x2135, 'M', u'א'), + ] + +def _seg_22(): + return [ + (0x2136, 'M', u'ב'), + (0x2137, 'M', u'ג'), + (0x2138, 'M', u'ד'), + (0x2139, 'M', u'i'), + (0x213A, 'V'), + (0x213B, 'M', u'fax'), + (0x213C, 'M', u'π'), + (0x213D, 'M', u'γ'), + (0x213F, 'M', u'π'), + (0x2140, 'M', u'∑'), + (0x2141, 'V'), + (0x2145, 'M', u'd'), + (0x2147, 'M', u'e'), + (0x2148, 'M', u'i'), + (0x2149, 'M', u'j'), + (0x214A, 'V'), + (0x2150, 'M', u'1⁄7'), + (0x2151, 'M', u'1⁄9'), + (0x2152, 'M', u'1⁄10'), + (0x2153, 'M', u'1⁄3'), + (0x2154, 'M', u'2⁄3'), + (0x2155, 'M', u'1⁄5'), + (0x2156, 'M', u'2⁄5'), + (0x2157, 'M', u'3⁄5'), + (0x2158, 'M', u'4⁄5'), + (0x2159, 'M', u'1⁄6'), + (0x215A, 'M', u'5⁄6'), + (0x215B, 'M', u'1⁄8'), + (0x215C, 'M', u'3⁄8'), + (0x215D, 'M', u'5⁄8'), + (0x215E, 'M', u'7⁄8'), + (0x215F, 'M', u'1⁄'), + (0x2160, 'M', u'i'), + (0x2161, 'M', u'ii'), + (0x2162, 'M', u'iii'), + (0x2163, 'M', u'iv'), + (0x2164, 'M', u'v'), + (0x2165, 'M', u'vi'), + (0x2166, 'M', u'vii'), + (0x2167, 'M', u'viii'), + (0x2168, 'M', u'ix'), + (0x2169, 'M', u'x'), + (0x216A, 'M', u'xi'), + (0x216B, 'M', u'xii'), + (0x216C, 'M', u'l'), + (0x216D, 'M', u'c'), + (0x216E, 'M', u'd'), + (0x216F, 'M', u'm'), + (0x2170, 'M', u'i'), + (0x2171, 'M', u'ii'), + (0x2172, 'M', u'iii'), + (0x2173, 'M', u'iv'), + (0x2174, 'M', u'v'), + (0x2175, 'M', u'vi'), + (0x2176, 'M', u'vii'), + (0x2177, 'M', u'viii'), + (0x2178, 'M', u'ix'), + (0x2179, 'M', u'x'), + (0x217A, 'M', u'xi'), + (0x217B, 'M', u'xii'), + (0x217C, 'M', u'l'), + (0x217D, 'M', u'c'), + (0x217E, 'M', u'd'), + (0x217F, 'M', u'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', u'0⁄3'), + (0x218A, 'X'), + (0x2190, 'V'), + (0x222C, 'M', u'∫∫'), + (0x222D, 'M', u'∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', u'∮∮'), + (0x2230, 'M', u'∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', u'〈'), + (0x232A, 'M', u'〉'), + (0x232B, 'V'), + (0x23F4, 'X'), + (0x2400, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', u'1'), + (0x2461, 'M', u'2'), + (0x2462, 'M', u'3'), + (0x2463, 'M', u'4'), + (0x2464, 'M', u'5'), + (0x2465, 'M', u'6'), + (0x2466, 'M', u'7'), + (0x2467, 'M', u'8'), + (0x2468, 'M', u'9'), + (0x2469, 'M', u'10'), + (0x246A, 'M', u'11'), + (0x246B, 'M', u'12'), + ] + +def _seg_23(): + return [ + (0x246C, 'M', u'13'), + (0x246D, 'M', u'14'), + (0x246E, 'M', u'15'), + (0x246F, 'M', u'16'), + (0x2470, 'M', u'17'), + (0x2471, 'M', u'18'), + (0x2472, 'M', u'19'), + (0x2473, 'M', u'20'), + (0x2474, '3', u'(1)'), + (0x2475, '3', u'(2)'), + (0x2476, '3', u'(3)'), + (0x2477, '3', u'(4)'), + (0x2478, '3', u'(5)'), + (0x2479, '3', u'(6)'), + (0x247A, '3', u'(7)'), + (0x247B, '3', u'(8)'), + (0x247C, '3', u'(9)'), + (0x247D, '3', u'(10)'), + (0x247E, '3', u'(11)'), + (0x247F, '3', u'(12)'), + (0x2480, '3', u'(13)'), + (0x2481, '3', u'(14)'), + (0x2482, '3', u'(15)'), + (0x2483, '3', u'(16)'), + (0x2484, '3', u'(17)'), + (0x2485, '3', u'(18)'), + (0x2486, '3', u'(19)'), + (0x2487, '3', u'(20)'), + (0x2488, 'X'), + (0x249C, '3', u'(a)'), + (0x249D, '3', u'(b)'), + (0x249E, '3', u'(c)'), + (0x249F, '3', u'(d)'), + (0x24A0, '3', u'(e)'), + (0x24A1, '3', u'(f)'), + (0x24A2, '3', u'(g)'), + (0x24A3, '3', u'(h)'), + (0x24A4, '3', u'(i)'), + (0x24A5, '3', u'(j)'), + (0x24A6, '3', u'(k)'), + (0x24A7, '3', u'(l)'), + (0x24A8, '3', u'(m)'), + (0x24A9, '3', u'(n)'), + (0x24AA, '3', u'(o)'), + (0x24AB, '3', u'(p)'), + (0x24AC, '3', u'(q)'), + (0x24AD, '3', u'(r)'), + (0x24AE, '3', u'(s)'), + (0x24AF, '3', u'(t)'), + (0x24B0, '3', u'(u)'), + (0x24B1, '3', u'(v)'), + (0x24B2, '3', u'(w)'), + (0x24B3, '3', u'(x)'), + (0x24B4, '3', u'(y)'), + (0x24B5, '3', u'(z)'), + (0x24B6, 'M', u'a'), + (0x24B7, 'M', u'b'), + (0x24B8, 'M', u'c'), + (0x24B9, 'M', u'd'), + (0x24BA, 'M', u'e'), + (0x24BB, 'M', u'f'), + (0x24BC, 'M', u'g'), + (0x24BD, 'M', u'h'), + (0x24BE, 'M', u'i'), + (0x24BF, 'M', u'j'), + (0x24C0, 'M', u'k'), + (0x24C1, 'M', u'l'), + (0x24C2, 'M', u'm'), + (0x24C3, 'M', u'n'), + (0x24C4, 'M', u'o'), + (0x24C5, 'M', u'p'), + (0x24C6, 'M', u'q'), + (0x24C7, 'M', u'r'), + (0x24C8, 'M', u's'), + (0x24C9, 'M', u't'), + (0x24CA, 'M', u'u'), + (0x24CB, 'M', u'v'), + (0x24CC, 'M', u'w'), + (0x24CD, 'M', u'x'), + (0x24CE, 'M', u'y'), + (0x24CF, 'M', u'z'), + (0x24D0, 'M', u'a'), + (0x24D1, 'M', u'b'), + (0x24D2, 'M', u'c'), + (0x24D3, 'M', u'd'), + (0x24D4, 'M', u'e'), + (0x24D5, 'M', u'f'), + (0x24D6, 'M', u'g'), + (0x24D7, 'M', u'h'), + (0x24D8, 'M', u'i'), + (0x24D9, 'M', u'j'), + (0x24DA, 'M', u'k'), + (0x24DB, 'M', u'l'), + (0x24DC, 'M', u'm'), + (0x24DD, 'M', u'n'), + (0x24DE, 'M', u'o'), + (0x24DF, 'M', u'p'), + (0x24E0, 'M', u'q'), + (0x24E1, 'M', u'r'), + (0x24E2, 'M', u's'), + ] + +def _seg_24(): + return [ + (0x24E3, 'M', u't'), + (0x24E4, 'M', u'u'), + (0x24E5, 'M', u'v'), + (0x24E6, 'M', u'w'), + (0x24E7, 'M', u'x'), + (0x24E8, 'M', u'y'), + (0x24E9, 'M', u'z'), + (0x24EA, 'M', u'0'), + (0x24EB, 'V'), + (0x2700, 'X'), + (0x2701, 'V'), + (0x2A0C, 'M', u'∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', u'::='), + (0x2A75, '3', u'=='), + (0x2A76, '3', u'==='), + (0x2A77, 'V'), + (0x2ADC, 'M', u'⫝̸'), + (0x2ADD, 'V'), + (0x2B4D, 'X'), + (0x2B50, 'V'), + (0x2B5A, 'X'), + (0x2C00, 'M', u'ⰰ'), + (0x2C01, 'M', u'ⰱ'), + (0x2C02, 'M', u'ⰲ'), + (0x2C03, 'M', u'ⰳ'), + (0x2C04, 'M', u'ⰴ'), + (0x2C05, 'M', u'ⰵ'), + (0x2C06, 'M', u'ⰶ'), + (0x2C07, 'M', u'ⰷ'), + (0x2C08, 'M', u'ⰸ'), + (0x2C09, 'M', u'ⰹ'), + (0x2C0A, 'M', u'ⰺ'), + (0x2C0B, 'M', u'ⰻ'), + (0x2C0C, 'M', u'ⰼ'), + (0x2C0D, 'M', u'ⰽ'), + (0x2C0E, 'M', u'ⰾ'), + (0x2C0F, 'M', u'ⰿ'), + (0x2C10, 'M', u'ⱀ'), + (0x2C11, 'M', u'ⱁ'), + (0x2C12, 'M', u'ⱂ'), + (0x2C13, 'M', u'ⱃ'), + (0x2C14, 'M', u'ⱄ'), + (0x2C15, 'M', u'ⱅ'), + (0x2C16, 'M', u'ⱆ'), + (0x2C17, 'M', u'ⱇ'), + (0x2C18, 'M', u'ⱈ'), + (0x2C19, 'M', u'ⱉ'), + (0x2C1A, 'M', u'ⱊ'), + (0x2C1B, 'M', u'ⱋ'), + (0x2C1C, 'M', u'ⱌ'), + (0x2C1D, 'M', u'ⱍ'), + (0x2C1E, 'M', u'ⱎ'), + (0x2C1F, 'M', u'ⱏ'), + (0x2C20, 'M', u'ⱐ'), + (0x2C21, 'M', u'ⱑ'), + (0x2C22, 'M', u'ⱒ'), + (0x2C23, 'M', u'ⱓ'), + (0x2C24, 'M', u'ⱔ'), + (0x2C25, 'M', u'ⱕ'), + (0x2C26, 'M', u'ⱖ'), + (0x2C27, 'M', u'ⱗ'), + (0x2C28, 'M', u'ⱘ'), + (0x2C29, 'M', u'ⱙ'), + (0x2C2A, 'M', u'ⱚ'), + (0x2C2B, 'M', u'ⱛ'), + (0x2C2C, 'M', u'ⱜ'), + (0x2C2D, 'M', u'ⱝ'), + (0x2C2E, 'M', u'ⱞ'), + (0x2C2F, 'X'), + (0x2C30, 'V'), + (0x2C5F, 'X'), + (0x2C60, 'M', u'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', u'ɫ'), + (0x2C63, 'M', u'ᵽ'), + (0x2C64, 'M', u'ɽ'), + (0x2C65, 'V'), + (0x2C67, 'M', u'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', u'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', u'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', u'ɑ'), + (0x2C6E, 'M', u'ɱ'), + (0x2C6F, 'M', u'ɐ'), + (0x2C70, 'M', u'ɒ'), + (0x2C71, 'V'), + (0x2C72, 'M', u'ⱳ'), + (0x2C73, 'V'), + (0x2C75, 'M', u'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', u'j'), + (0x2C7D, 'M', u'v'), + (0x2C7E, 'M', u'ȿ'), + (0x2C7F, 'M', u'ɀ'), + (0x2C80, 'M', u'ⲁ'), + (0x2C81, 'V'), + (0x2C82, 'M', u'ⲃ'), + ] + +def _seg_25(): + return [ + (0x2C83, 'V'), + (0x2C84, 'M', u'ⲅ'), + (0x2C85, 'V'), + (0x2C86, 'M', u'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', u'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', u'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', u'ⲍ'), + (0x2C8D, 'V'), + (0x2C8E, 'M', u'ⲏ'), + (0x2C8F, 'V'), + (0x2C90, 'M', u'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', u'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', u'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', u'ⲗ'), + (0x2C97, 'V'), + (0x2C98, 'M', u'ⲙ'), + (0x2C99, 'V'), + (0x2C9A, 'M', u'ⲛ'), + (0x2C9B, 'V'), + (0x2C9C, 'M', u'ⲝ'), + (0x2C9D, 'V'), + (0x2C9E, 'M', u'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', u'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', u'ⲣ'), + (0x2CA3, 'V'), + (0x2CA4, 'M', u'ⲥ'), + (0x2CA5, 'V'), + (0x2CA6, 'M', u'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', u'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', u'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', u'ⲭ'), + (0x2CAD, 'V'), + (0x2CAE, 'M', u'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', u'ⲱ'), + (0x2CB1, 'V'), + (0x2CB2, 'M', u'ⲳ'), + (0x2CB3, 'V'), + (0x2CB4, 'M', u'ⲵ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', u'ⲷ'), + (0x2CB7, 'V'), + (0x2CB8, 'M', u'ⲹ'), + (0x2CB9, 'V'), + (0x2CBA, 'M', u'ⲻ'), + (0x2CBB, 'V'), + (0x2CBC, 'M', u'ⲽ'), + (0x2CBD, 'V'), + (0x2CBE, 'M', u'ⲿ'), + (0x2CBF, 'V'), + (0x2CC0, 'M', u'ⳁ'), + (0x2CC1, 'V'), + (0x2CC2, 'M', u'ⳃ'), + (0x2CC3, 'V'), + (0x2CC4, 'M', u'ⳅ'), + (0x2CC5, 'V'), + (0x2CC6, 'M', u'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', u'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', u'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', u'ⳍ'), + (0x2CCD, 'V'), + (0x2CCE, 'M', u'ⳏ'), + (0x2CCF, 'V'), + (0x2CD0, 'M', u'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', u'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', u'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', u'ⳗ'), + (0x2CD7, 'V'), + (0x2CD8, 'M', u'ⳙ'), + (0x2CD9, 'V'), + (0x2CDA, 'M', u'ⳛ'), + (0x2CDB, 'V'), + (0x2CDC, 'M', u'ⳝ'), + (0x2CDD, 'V'), + (0x2CDE, 'M', u'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', u'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', u'ⳣ'), + (0x2CE3, 'V'), + (0x2CEB, 'M', u'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', u'ⳮ'), + ] + +def _seg_26(): + return [ + (0x2CEE, 'V'), + (0x2CF2, 'M', u'ⳳ'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', u'ⵡ'), + (0x2D70, 'V'), + (0x2D71, 'X'), + (0x2D7F, 'V'), + (0x2D97, 'X'), + (0x2DA0, 'V'), + (0x2DA7, 'X'), + (0x2DA8, 'V'), + (0x2DAF, 'X'), + (0x2DB0, 'V'), + (0x2DB7, 'X'), + (0x2DB8, 'V'), + (0x2DBF, 'X'), + (0x2DC0, 'V'), + (0x2DC7, 'X'), + (0x2DC8, 'V'), + (0x2DCF, 'X'), + (0x2DD0, 'V'), + (0x2DD7, 'X'), + (0x2DD8, 'V'), + (0x2DDF, 'X'), + (0x2DE0, 'V'), + (0x2E3C, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', u'母'), + (0x2EA0, 'V'), + (0x2EF3, 'M', u'龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', u'一'), + (0x2F01, 'M', u'丨'), + (0x2F02, 'M', u'丶'), + (0x2F03, 'M', u'丿'), + (0x2F04, 'M', u'乙'), + (0x2F05, 'M', u'亅'), + (0x2F06, 'M', u'二'), + (0x2F07, 'M', u'亠'), + (0x2F08, 'M', u'人'), + (0x2F09, 'M', u'儿'), + (0x2F0A, 'M', u'入'), + (0x2F0B, 'M', u'八'), + (0x2F0C, 'M', u'冂'), + (0x2F0D, 'M', u'冖'), + (0x2F0E, 'M', u'冫'), + (0x2F0F, 'M', u'几'), + (0x2F10, 'M', u'凵'), + (0x2F11, 'M', u'刀'), + (0x2F12, 'M', u'力'), + (0x2F13, 'M', u'勹'), + (0x2F14, 'M', u'匕'), + (0x2F15, 'M', u'匚'), + (0x2F16, 'M', u'匸'), + (0x2F17, 'M', u'十'), + (0x2F18, 'M', u'卜'), + (0x2F19, 'M', u'卩'), + (0x2F1A, 'M', u'厂'), + (0x2F1B, 'M', u'厶'), + (0x2F1C, 'M', u'又'), + (0x2F1D, 'M', u'口'), + (0x2F1E, 'M', u'囗'), + (0x2F1F, 'M', u'土'), + (0x2F20, 'M', u'士'), + (0x2F21, 'M', u'夂'), + (0x2F22, 'M', u'夊'), + (0x2F23, 'M', u'夕'), + (0x2F24, 'M', u'大'), + (0x2F25, 'M', u'女'), + (0x2F26, 'M', u'子'), + (0x2F27, 'M', u'宀'), + (0x2F28, 'M', u'寸'), + (0x2F29, 'M', u'小'), + (0x2F2A, 'M', u'尢'), + (0x2F2B, 'M', u'尸'), + (0x2F2C, 'M', u'屮'), + (0x2F2D, 'M', u'山'), + (0x2F2E, 'M', u'巛'), + (0x2F2F, 'M', u'工'), + (0x2F30, 'M', u'己'), + (0x2F31, 'M', u'巾'), + (0x2F32, 'M', u'干'), + (0x2F33, 'M', u'幺'), + (0x2F34, 'M', u'广'), + (0x2F35, 'M', u'廴'), + (0x2F36, 'M', u'廾'), + (0x2F37, 'M', u'弋'), + (0x2F38, 'M', u'弓'), + (0x2F39, 'M', u'彐'), + ] + +def _seg_27(): + return [ + (0x2F3A, 'M', u'彡'), + (0x2F3B, 'M', u'彳'), + (0x2F3C, 'M', u'心'), + (0x2F3D, 'M', u'戈'), + (0x2F3E, 'M', u'戶'), + (0x2F3F, 'M', u'手'), + (0x2F40, 'M', u'支'), + (0x2F41, 'M', u'攴'), + (0x2F42, 'M', u'文'), + (0x2F43, 'M', u'斗'), + (0x2F44, 'M', u'斤'), + (0x2F45, 'M', u'方'), + (0x2F46, 'M', u'无'), + (0x2F47, 'M', u'日'), + (0x2F48, 'M', u'曰'), + (0x2F49, 'M', u'月'), + (0x2F4A, 'M', u'木'), + (0x2F4B, 'M', u'欠'), + (0x2F4C, 'M', u'止'), + (0x2F4D, 'M', u'歹'), + (0x2F4E, 'M', u'殳'), + (0x2F4F, 'M', u'毋'), + (0x2F50, 'M', u'比'), + (0x2F51, 'M', u'毛'), + (0x2F52, 'M', u'氏'), + (0x2F53, 'M', u'气'), + (0x2F54, 'M', u'水'), + (0x2F55, 'M', u'火'), + (0x2F56, 'M', u'爪'), + (0x2F57, 'M', u'父'), + (0x2F58, 'M', u'爻'), + (0x2F59, 'M', u'爿'), + (0x2F5A, 'M', u'片'), + (0x2F5B, 'M', u'牙'), + (0x2F5C, 'M', u'牛'), + (0x2F5D, 'M', u'犬'), + (0x2F5E, 'M', u'玄'), + (0x2F5F, 'M', u'玉'), + (0x2F60, 'M', u'瓜'), + (0x2F61, 'M', u'瓦'), + (0x2F62, 'M', u'甘'), + (0x2F63, 'M', u'生'), + (0x2F64, 'M', u'用'), + (0x2F65, 'M', u'田'), + (0x2F66, 'M', u'疋'), + (0x2F67, 'M', u'疒'), + (0x2F68, 'M', u'癶'), + (0x2F69, 'M', u'白'), + (0x2F6A, 'M', u'皮'), + (0x2F6B, 'M', u'皿'), + (0x2F6C, 'M', u'目'), + (0x2F6D, 'M', u'矛'), + (0x2F6E, 'M', u'矢'), + (0x2F6F, 'M', u'石'), + (0x2F70, 'M', u'示'), + (0x2F71, 'M', u'禸'), + (0x2F72, 'M', u'禾'), + (0x2F73, 'M', u'穴'), + (0x2F74, 'M', u'立'), + (0x2F75, 'M', u'竹'), + (0x2F76, 'M', u'米'), + (0x2F77, 'M', u'糸'), + (0x2F78, 'M', u'缶'), + (0x2F79, 'M', u'网'), + (0x2F7A, 'M', u'羊'), + (0x2F7B, 'M', u'羽'), + (0x2F7C, 'M', u'老'), + (0x2F7D, 'M', u'而'), + (0x2F7E, 'M', u'耒'), + (0x2F7F, 'M', u'耳'), + (0x2F80, 'M', u'聿'), + (0x2F81, 'M', u'肉'), + (0x2F82, 'M', u'臣'), + (0x2F83, 'M', u'自'), + (0x2F84, 'M', u'至'), + (0x2F85, 'M', u'臼'), + (0x2F86, 'M', u'舌'), + (0x2F87, 'M', u'舛'), + (0x2F88, 'M', u'舟'), + (0x2F89, 'M', u'艮'), + (0x2F8A, 'M', u'色'), + (0x2F8B, 'M', u'艸'), + (0x2F8C, 'M', u'虍'), + (0x2F8D, 'M', u'虫'), + (0x2F8E, 'M', u'血'), + (0x2F8F, 'M', u'行'), + (0x2F90, 'M', u'衣'), + (0x2F91, 'M', u'襾'), + (0x2F92, 'M', u'見'), + (0x2F93, 'M', u'角'), + (0x2F94, 'M', u'言'), + (0x2F95, 'M', u'谷'), + (0x2F96, 'M', u'豆'), + (0x2F97, 'M', u'豕'), + (0x2F98, 'M', u'豸'), + (0x2F99, 'M', u'貝'), + (0x2F9A, 'M', u'赤'), + (0x2F9B, 'M', u'走'), + (0x2F9C, 'M', u'足'), + (0x2F9D, 'M', u'身'), + ] + +def _seg_28(): + return [ + (0x2F9E, 'M', u'車'), + (0x2F9F, 'M', u'辛'), + (0x2FA0, 'M', u'辰'), + (0x2FA1, 'M', u'辵'), + (0x2FA2, 'M', u'邑'), + (0x2FA3, 'M', u'酉'), + (0x2FA4, 'M', u'釆'), + (0x2FA5, 'M', u'里'), + (0x2FA6, 'M', u'金'), + (0x2FA7, 'M', u'長'), + (0x2FA8, 'M', u'門'), + (0x2FA9, 'M', u'阜'), + (0x2FAA, 'M', u'隶'), + (0x2FAB, 'M', u'隹'), + (0x2FAC, 'M', u'雨'), + (0x2FAD, 'M', u'靑'), + (0x2FAE, 'M', u'非'), + (0x2FAF, 'M', u'面'), + (0x2FB0, 'M', u'革'), + (0x2FB1, 'M', u'韋'), + (0x2FB2, 'M', u'韭'), + (0x2FB3, 'M', u'音'), + (0x2FB4, 'M', u'頁'), + (0x2FB5, 'M', u'風'), + (0x2FB6, 'M', u'飛'), + (0x2FB7, 'M', u'食'), + (0x2FB8, 'M', u'首'), + (0x2FB9, 'M', u'香'), + (0x2FBA, 'M', u'馬'), + (0x2FBB, 'M', u'骨'), + (0x2FBC, 'M', u'高'), + (0x2FBD, 'M', u'髟'), + (0x2FBE, 'M', u'鬥'), + (0x2FBF, 'M', u'鬯'), + (0x2FC0, 'M', u'鬲'), + (0x2FC1, 'M', u'鬼'), + (0x2FC2, 'M', u'魚'), + (0x2FC3, 'M', u'鳥'), + (0x2FC4, 'M', u'鹵'), + (0x2FC5, 'M', u'鹿'), + (0x2FC6, 'M', u'麥'), + (0x2FC7, 'M', u'麻'), + (0x2FC8, 'M', u'黃'), + (0x2FC9, 'M', u'黍'), + (0x2FCA, 'M', u'黑'), + (0x2FCB, 'M', u'黹'), + (0x2FCC, 'M', u'黽'), + (0x2FCD, 'M', u'鼎'), + (0x2FCE, 'M', u'鼓'), + (0x2FCF, 'M', u'鼠'), + (0x2FD0, 'M', u'鼻'), + (0x2FD1, 'M', u'齊'), + (0x2FD2, 'M', u'齒'), + (0x2FD3, 'M', u'龍'), + (0x2FD4, 'M', u'龜'), + (0x2FD5, 'M', u'龠'), + (0x2FD6, 'X'), + (0x3000, '3', u' '), + (0x3001, 'V'), + (0x3002, 'M', u'.'), + (0x3003, 'V'), + (0x3036, 'M', u'〒'), + (0x3037, 'V'), + (0x3038, 'M', u'十'), + (0x3039, 'M', u'卄'), + (0x303A, 'M', u'卅'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', u' ゙'), + (0x309C, '3', u' ゚'), + (0x309D, 'V'), + (0x309F, 'M', u'より'), + (0x30A0, 'V'), + (0x30FF, 'M', u'コト'), + (0x3100, 'X'), + (0x3105, 'V'), + (0x312E, 'X'), + (0x3131, 'M', u'ᄀ'), + (0x3132, 'M', u'ᄁ'), + (0x3133, 'M', u'ᆪ'), + (0x3134, 'M', u'ᄂ'), + (0x3135, 'M', u'ᆬ'), + (0x3136, 'M', u'ᆭ'), + (0x3137, 'M', u'ᄃ'), + (0x3138, 'M', u'ᄄ'), + (0x3139, 'M', u'ᄅ'), + (0x313A, 'M', u'ᆰ'), + (0x313B, 'M', u'ᆱ'), + (0x313C, 'M', u'ᆲ'), + (0x313D, 'M', u'ᆳ'), + (0x313E, 'M', u'ᆴ'), + (0x313F, 'M', u'ᆵ'), + (0x3140, 'M', u'ᄚ'), + (0x3141, 'M', u'ᄆ'), + (0x3142, 'M', u'ᄇ'), + (0x3143, 'M', u'ᄈ'), + (0x3144, 'M', u'ᄡ'), + ] + +def _seg_29(): + return [ + (0x3145, 'M', u'ᄉ'), + (0x3146, 'M', u'ᄊ'), + (0x3147, 'M', u'ᄋ'), + (0x3148, 'M', u'ᄌ'), + (0x3149, 'M', u'ᄍ'), + (0x314A, 'M', u'ᄎ'), + (0x314B, 'M', u'ᄏ'), + (0x314C, 'M', u'ᄐ'), + (0x314D, 'M', u'ᄑ'), + (0x314E, 'M', u'ᄒ'), + (0x314F, 'M', u'ᅡ'), + (0x3150, 'M', u'ᅢ'), + (0x3151, 'M', u'ᅣ'), + (0x3152, 'M', u'ᅤ'), + (0x3153, 'M', u'ᅥ'), + (0x3154, 'M', u'ᅦ'), + (0x3155, 'M', u'ᅧ'), + (0x3156, 'M', u'ᅨ'), + (0x3157, 'M', u'ᅩ'), + (0x3158, 'M', u'ᅪ'), + (0x3159, 'M', u'ᅫ'), + (0x315A, 'M', u'ᅬ'), + (0x315B, 'M', u'ᅭ'), + (0x315C, 'M', u'ᅮ'), + (0x315D, 'M', u'ᅯ'), + (0x315E, 'M', u'ᅰ'), + (0x315F, 'M', u'ᅱ'), + (0x3160, 'M', u'ᅲ'), + (0x3161, 'M', u'ᅳ'), + (0x3162, 'M', u'ᅴ'), + (0x3163, 'M', u'ᅵ'), + (0x3164, 'X'), + (0x3165, 'M', u'ᄔ'), + (0x3166, 'M', u'ᄕ'), + (0x3167, 'M', u'ᇇ'), + (0x3168, 'M', u'ᇈ'), + (0x3169, 'M', u'ᇌ'), + (0x316A, 'M', u'ᇎ'), + (0x316B, 'M', u'ᇓ'), + (0x316C, 'M', u'ᇗ'), + (0x316D, 'M', u'ᇙ'), + (0x316E, 'M', u'ᄜ'), + (0x316F, 'M', u'ᇝ'), + (0x3170, 'M', u'ᇟ'), + (0x3171, 'M', u'ᄝ'), + (0x3172, 'M', u'ᄞ'), + (0x3173, 'M', u'ᄠ'), + (0x3174, 'M', u'ᄢ'), + (0x3175, 'M', u'ᄣ'), + (0x3176, 'M', u'ᄧ'), + (0x3177, 'M', u'ᄩ'), + (0x3178, 'M', u'ᄫ'), + (0x3179, 'M', u'ᄬ'), + (0x317A, 'M', u'ᄭ'), + (0x317B, 'M', u'ᄮ'), + (0x317C, 'M', u'ᄯ'), + (0x317D, 'M', u'ᄲ'), + (0x317E, 'M', u'ᄶ'), + (0x317F, 'M', u'ᅀ'), + (0x3180, 'M', u'ᅇ'), + (0x3181, 'M', u'ᅌ'), + (0x3182, 'M', u'ᇱ'), + (0x3183, 'M', u'ᇲ'), + (0x3184, 'M', u'ᅗ'), + (0x3185, 'M', u'ᅘ'), + (0x3186, 'M', u'ᅙ'), + (0x3187, 'M', u'ᆄ'), + (0x3188, 'M', u'ᆅ'), + (0x3189, 'M', u'ᆈ'), + (0x318A, 'M', u'ᆑ'), + (0x318B, 'M', u'ᆒ'), + (0x318C, 'M', u'ᆔ'), + (0x318D, 'M', u'ᆞ'), + (0x318E, 'M', u'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', u'一'), + (0x3193, 'M', u'二'), + (0x3194, 'M', u'三'), + (0x3195, 'M', u'四'), + (0x3196, 'M', u'上'), + (0x3197, 'M', u'中'), + (0x3198, 'M', u'下'), + (0x3199, 'M', u'甲'), + (0x319A, 'M', u'乙'), + (0x319B, 'M', u'丙'), + (0x319C, 'M', u'丁'), + (0x319D, 'M', u'天'), + (0x319E, 'M', u'地'), + (0x319F, 'M', u'人'), + (0x31A0, 'V'), + (0x31BB, 'X'), + (0x31C0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', u'(ᄀ)'), + (0x3201, '3', u'(ᄂ)'), + (0x3202, '3', u'(ᄃ)'), + (0x3203, '3', u'(ᄅ)'), + (0x3204, '3', u'(ᄆ)'), + ] + +def _seg_30(): + return [ + (0x3205, '3', u'(ᄇ)'), + (0x3206, '3', u'(ᄉ)'), + (0x3207, '3', u'(ᄋ)'), + (0x3208, '3', u'(ᄌ)'), + (0x3209, '3', u'(ᄎ)'), + (0x320A, '3', u'(ᄏ)'), + (0x320B, '3', u'(ᄐ)'), + (0x320C, '3', u'(ᄑ)'), + (0x320D, '3', u'(ᄒ)'), + (0x320E, '3', u'(가)'), + (0x320F, '3', u'(나)'), + (0x3210, '3', u'(다)'), + (0x3211, '3', u'(라)'), + (0x3212, '3', u'(마)'), + (0x3213, '3', u'(바)'), + (0x3214, '3', u'(사)'), + (0x3215, '3', u'(아)'), + (0x3216, '3', u'(자)'), + (0x3217, '3', u'(차)'), + (0x3218, '3', u'(카)'), + (0x3219, '3', u'(타)'), + (0x321A, '3', u'(파)'), + (0x321B, '3', u'(하)'), + (0x321C, '3', u'(주)'), + (0x321D, '3', u'(오전)'), + (0x321E, '3', u'(오후)'), + (0x321F, 'X'), + (0x3220, '3', u'(一)'), + (0x3221, '3', u'(二)'), + (0x3222, '3', u'(三)'), + (0x3223, '3', u'(四)'), + (0x3224, '3', u'(五)'), + (0x3225, '3', u'(六)'), + (0x3226, '3', u'(七)'), + (0x3227, '3', u'(八)'), + (0x3228, '3', u'(九)'), + (0x3229, '3', u'(十)'), + (0x322A, '3', u'(月)'), + (0x322B, '3', u'(火)'), + (0x322C, '3', u'(水)'), + (0x322D, '3', u'(木)'), + (0x322E, '3', u'(金)'), + (0x322F, '3', u'(土)'), + (0x3230, '3', u'(日)'), + (0x3231, '3', u'(株)'), + (0x3232, '3', u'(有)'), + (0x3233, '3', u'(社)'), + (0x3234, '3', u'(名)'), + (0x3235, '3', u'(特)'), + (0x3236, '3', u'(財)'), + (0x3237, '3', u'(祝)'), + (0x3238, '3', u'(労)'), + (0x3239, '3', u'(代)'), + (0x323A, '3', u'(呼)'), + (0x323B, '3', u'(学)'), + (0x323C, '3', u'(監)'), + (0x323D, '3', u'(企)'), + (0x323E, '3', u'(資)'), + (0x323F, '3', u'(協)'), + (0x3240, '3', u'(祭)'), + (0x3241, '3', u'(休)'), + (0x3242, '3', u'(自)'), + (0x3243, '3', u'(至)'), + (0x3244, 'M', u'問'), + (0x3245, 'M', u'幼'), + (0x3246, 'M', u'文'), + (0x3247, 'M', u'箏'), + (0x3248, 'V'), + (0x3250, 'M', u'pte'), + (0x3251, 'M', u'21'), + (0x3252, 'M', u'22'), + (0x3253, 'M', u'23'), + (0x3254, 'M', u'24'), + (0x3255, 'M', u'25'), + (0x3256, 'M', u'26'), + (0x3257, 'M', u'27'), + (0x3258, 'M', u'28'), + (0x3259, 'M', u'29'), + (0x325A, 'M', u'30'), + (0x325B, 'M', u'31'), + (0x325C, 'M', u'32'), + (0x325D, 'M', u'33'), + (0x325E, 'M', u'34'), + (0x325F, 'M', u'35'), + (0x3260, 'M', u'ᄀ'), + (0x3261, 'M', u'ᄂ'), + (0x3262, 'M', u'ᄃ'), + (0x3263, 'M', u'ᄅ'), + (0x3264, 'M', u'ᄆ'), + (0x3265, 'M', u'ᄇ'), + (0x3266, 'M', u'ᄉ'), + (0x3267, 'M', u'ᄋ'), + (0x3268, 'M', u'ᄌ'), + (0x3269, 'M', u'ᄎ'), + (0x326A, 'M', u'ᄏ'), + (0x326B, 'M', u'ᄐ'), + (0x326C, 'M', u'ᄑ'), + (0x326D, 'M', u'ᄒ'), + (0x326E, 'M', u'가'), + (0x326F, 'M', u'나'), + ] + +def _seg_31(): + return [ + (0x3270, 'M', u'다'), + (0x3271, 'M', u'라'), + (0x3272, 'M', u'마'), + (0x3273, 'M', u'바'), + (0x3274, 'M', u'사'), + (0x3275, 'M', u'아'), + (0x3276, 'M', u'자'), + (0x3277, 'M', u'차'), + (0x3278, 'M', u'카'), + (0x3279, 'M', u'타'), + (0x327A, 'M', u'파'), + (0x327B, 'M', u'하'), + (0x327C, 'M', u'참고'), + (0x327D, 'M', u'주의'), + (0x327E, 'M', u'우'), + (0x327F, 'V'), + (0x3280, 'M', u'一'), + (0x3281, 'M', u'二'), + (0x3282, 'M', u'三'), + (0x3283, 'M', u'四'), + (0x3284, 'M', u'五'), + (0x3285, 'M', u'六'), + (0x3286, 'M', u'七'), + (0x3287, 'M', u'八'), + (0x3288, 'M', u'九'), + (0x3289, 'M', u'十'), + (0x328A, 'M', u'月'), + (0x328B, 'M', u'火'), + (0x328C, 'M', u'水'), + (0x328D, 'M', u'木'), + (0x328E, 'M', u'金'), + (0x328F, 'M', u'土'), + (0x3290, 'M', u'日'), + (0x3291, 'M', u'株'), + (0x3292, 'M', u'有'), + (0x3293, 'M', u'社'), + (0x3294, 'M', u'名'), + (0x3295, 'M', u'特'), + (0x3296, 'M', u'財'), + (0x3297, 'M', u'祝'), + (0x3298, 'M', u'労'), + (0x3299, 'M', u'秘'), + (0x329A, 'M', u'男'), + (0x329B, 'M', u'女'), + (0x329C, 'M', u'適'), + (0x329D, 'M', u'優'), + (0x329E, 'M', u'印'), + (0x329F, 'M', u'注'), + (0x32A0, 'M', u'項'), + (0x32A1, 'M', u'休'), + (0x32A2, 'M', u'写'), + (0x32A3, 'M', u'正'), + (0x32A4, 'M', u'上'), + (0x32A5, 'M', u'中'), + (0x32A6, 'M', u'下'), + (0x32A7, 'M', u'左'), + (0x32A8, 'M', u'右'), + (0x32A9, 'M', u'医'), + (0x32AA, 'M', u'宗'), + (0x32AB, 'M', u'学'), + (0x32AC, 'M', u'監'), + (0x32AD, 'M', u'企'), + (0x32AE, 'M', u'資'), + (0x32AF, 'M', u'協'), + (0x32B0, 'M', u'夜'), + (0x32B1, 'M', u'36'), + (0x32B2, 'M', u'37'), + (0x32B3, 'M', u'38'), + (0x32B4, 'M', u'39'), + (0x32B5, 'M', u'40'), + (0x32B6, 'M', u'41'), + (0x32B7, 'M', u'42'), + (0x32B8, 'M', u'43'), + (0x32B9, 'M', u'44'), + (0x32BA, 'M', u'45'), + (0x32BB, 'M', u'46'), + (0x32BC, 'M', u'47'), + (0x32BD, 'M', u'48'), + (0x32BE, 'M', u'49'), + (0x32BF, 'M', u'50'), + (0x32C0, 'M', u'1月'), + (0x32C1, 'M', u'2月'), + (0x32C2, 'M', u'3月'), + (0x32C3, 'M', u'4月'), + (0x32C4, 'M', u'5月'), + (0x32C5, 'M', u'6月'), + (0x32C6, 'M', u'7月'), + (0x32C7, 'M', u'8月'), + (0x32C8, 'M', u'9月'), + (0x32C9, 'M', u'10月'), + (0x32CA, 'M', u'11月'), + (0x32CB, 'M', u'12月'), + (0x32CC, 'M', u'hg'), + (0x32CD, 'M', u'erg'), + (0x32CE, 'M', u'ev'), + (0x32CF, 'M', u'ltd'), + (0x32D0, 'M', u'ア'), + (0x32D1, 'M', u'イ'), + (0x32D2, 'M', u'ウ'), + (0x32D3, 'M', u'エ'), + ] + +def _seg_32(): + return [ + (0x32D4, 'M', u'オ'), + (0x32D5, 'M', u'カ'), + (0x32D6, 'M', u'キ'), + (0x32D7, 'M', u'ク'), + (0x32D8, 'M', u'ケ'), + (0x32D9, 'M', u'コ'), + (0x32DA, 'M', u'サ'), + (0x32DB, 'M', u'シ'), + (0x32DC, 'M', u'ス'), + (0x32DD, 'M', u'セ'), + (0x32DE, 'M', u'ソ'), + (0x32DF, 'M', u'タ'), + (0x32E0, 'M', u'チ'), + (0x32E1, 'M', u'ツ'), + (0x32E2, 'M', u'テ'), + (0x32E3, 'M', u'ト'), + (0x32E4, 'M', u'ナ'), + (0x32E5, 'M', u'ニ'), + (0x32E6, 'M', u'ヌ'), + (0x32E7, 'M', u'ネ'), + (0x32E8, 'M', u'ノ'), + (0x32E9, 'M', u'ハ'), + (0x32EA, 'M', u'ヒ'), + (0x32EB, 'M', u'フ'), + (0x32EC, 'M', u'ヘ'), + (0x32ED, 'M', u'ホ'), + (0x32EE, 'M', u'マ'), + (0x32EF, 'M', u'ミ'), + (0x32F0, 'M', u'ム'), + (0x32F1, 'M', u'メ'), + (0x32F2, 'M', u'モ'), + (0x32F3, 'M', u'ヤ'), + (0x32F4, 'M', u'ユ'), + (0x32F5, 'M', u'ヨ'), + (0x32F6, 'M', u'ラ'), + (0x32F7, 'M', u'リ'), + (0x32F8, 'M', u'ル'), + (0x32F9, 'M', u'レ'), + (0x32FA, 'M', u'ロ'), + (0x32FB, 'M', u'ワ'), + (0x32FC, 'M', u'ヰ'), + (0x32FD, 'M', u'ヱ'), + (0x32FE, 'M', u'ヲ'), + (0x32FF, 'X'), + (0x3300, 'M', u'アパート'), + (0x3301, 'M', u'アルファ'), + (0x3302, 'M', u'アンペア'), + (0x3303, 'M', u'アール'), + (0x3304, 'M', u'イニング'), + (0x3305, 'M', u'インチ'), + (0x3306, 'M', u'ウォン'), + (0x3307, 'M', u'エスクード'), + (0x3308, 'M', u'エーカー'), + (0x3309, 'M', u'オンス'), + (0x330A, 'M', u'オーム'), + (0x330B, 'M', u'カイリ'), + (0x330C, 'M', u'カラット'), + (0x330D, 'M', u'カロリー'), + (0x330E, 'M', u'ガロン'), + (0x330F, 'M', u'ガンマ'), + (0x3310, 'M', u'ギガ'), + (0x3311, 'M', u'ギニー'), + (0x3312, 'M', u'キュリー'), + (0x3313, 'M', u'ギルダー'), + (0x3314, 'M', u'キロ'), + (0x3315, 'M', u'キログラム'), + (0x3316, 'M', u'キロメートル'), + (0x3317, 'M', u'キロワット'), + (0x3318, 'M', u'グラム'), + (0x3319, 'M', u'グラムトン'), + (0x331A, 'M', u'クルゼイロ'), + (0x331B, 'M', u'クローネ'), + (0x331C, 'M', u'ケース'), + (0x331D, 'M', u'コルナ'), + (0x331E, 'M', u'コーポ'), + (0x331F, 'M', u'サイクル'), + (0x3320, 'M', u'サンチーム'), + (0x3321, 'M', u'シリング'), + (0x3322, 'M', u'センチ'), + (0x3323, 'M', u'セント'), + (0x3324, 'M', u'ダース'), + (0x3325, 'M', u'デシ'), + (0x3326, 'M', u'ドル'), + (0x3327, 'M', u'トン'), + (0x3328, 'M', u'ナノ'), + (0x3329, 'M', u'ノット'), + (0x332A, 'M', u'ハイツ'), + (0x332B, 'M', u'パーセント'), + (0x332C, 'M', u'パーツ'), + (0x332D, 'M', u'バーレル'), + (0x332E, 'M', u'ピアストル'), + (0x332F, 'M', u'ピクル'), + (0x3330, 'M', u'ピコ'), + (0x3331, 'M', u'ビル'), + (0x3332, 'M', u'ファラッド'), + (0x3333, 'M', u'フィート'), + (0x3334, 'M', u'ブッシェル'), + (0x3335, 'M', u'フラン'), + (0x3336, 'M', u'ヘクタール'), + (0x3337, 'M', u'ペソ'), + ] + +def _seg_33(): + return [ + (0x3338, 'M', u'ペニヒ'), + (0x3339, 'M', u'ヘルツ'), + (0x333A, 'M', u'ペンス'), + (0x333B, 'M', u'ページ'), + (0x333C, 'M', u'ベータ'), + (0x333D, 'M', u'ポイント'), + (0x333E, 'M', u'ボルト'), + (0x333F, 'M', u'ホン'), + (0x3340, 'M', u'ポンド'), + (0x3341, 'M', u'ホール'), + (0x3342, 'M', u'ホーン'), + (0x3343, 'M', u'マイクロ'), + (0x3344, 'M', u'マイル'), + (0x3345, 'M', u'マッハ'), + (0x3346, 'M', u'マルク'), + (0x3347, 'M', u'マンション'), + (0x3348, 'M', u'ミクロン'), + (0x3349, 'M', u'ミリ'), + (0x334A, 'M', u'ミリバール'), + (0x334B, 'M', u'メガ'), + (0x334C, 'M', u'メガトン'), + (0x334D, 'M', u'メートル'), + (0x334E, 'M', u'ヤード'), + (0x334F, 'M', u'ヤール'), + (0x3350, 'M', u'ユアン'), + (0x3351, 'M', u'リットル'), + (0x3352, 'M', u'リラ'), + (0x3353, 'M', u'ルピー'), + (0x3354, 'M', u'ルーブル'), + (0x3355, 'M', u'レム'), + (0x3356, 'M', u'レントゲン'), + (0x3357, 'M', u'ワット'), + (0x3358, 'M', u'0点'), + (0x3359, 'M', u'1点'), + (0x335A, 'M', u'2点'), + (0x335B, 'M', u'3点'), + (0x335C, 'M', u'4点'), + (0x335D, 'M', u'5点'), + (0x335E, 'M', u'6点'), + (0x335F, 'M', u'7点'), + (0x3360, 'M', u'8点'), + (0x3361, 'M', u'9点'), + (0x3362, 'M', u'10点'), + (0x3363, 'M', u'11点'), + (0x3364, 'M', u'12点'), + (0x3365, 'M', u'13点'), + (0x3366, 'M', u'14点'), + (0x3367, 'M', u'15点'), + (0x3368, 'M', u'16点'), + (0x3369, 'M', u'17点'), + (0x336A, 'M', u'18点'), + (0x336B, 'M', u'19点'), + (0x336C, 'M', u'20点'), + (0x336D, 'M', u'21点'), + (0x336E, 'M', u'22点'), + (0x336F, 'M', u'23点'), + (0x3370, 'M', u'24点'), + (0x3371, 'M', u'hpa'), + (0x3372, 'M', u'da'), + (0x3373, 'M', u'au'), + (0x3374, 'M', u'bar'), + (0x3375, 'M', u'ov'), + (0x3376, 'M', u'pc'), + (0x3377, 'M', u'dm'), + (0x3378, 'M', u'dm2'), + (0x3379, 'M', u'dm3'), + (0x337A, 'M', u'iu'), + (0x337B, 'M', u'平成'), + (0x337C, 'M', u'昭和'), + (0x337D, 'M', u'大正'), + (0x337E, 'M', u'明治'), + (0x337F, 'M', u'株式会社'), + (0x3380, 'M', u'pa'), + (0x3381, 'M', u'na'), + (0x3382, 'M', u'μa'), + (0x3383, 'M', u'ma'), + (0x3384, 'M', u'ka'), + (0x3385, 'M', u'kb'), + (0x3386, 'M', u'mb'), + (0x3387, 'M', u'gb'), + (0x3388, 'M', u'cal'), + (0x3389, 'M', u'kcal'), + (0x338A, 'M', u'pf'), + (0x338B, 'M', u'nf'), + (0x338C, 'M', u'μf'), + (0x338D, 'M', u'μg'), + (0x338E, 'M', u'mg'), + (0x338F, 'M', u'kg'), + (0x3390, 'M', u'hz'), + (0x3391, 'M', u'khz'), + (0x3392, 'M', u'mhz'), + (0x3393, 'M', u'ghz'), + (0x3394, 'M', u'thz'), + (0x3395, 'M', u'μl'), + (0x3396, 'M', u'ml'), + (0x3397, 'M', u'dl'), + (0x3398, 'M', u'kl'), + (0x3399, 'M', u'fm'), + (0x339A, 'M', u'nm'), + (0x339B, 'M', u'μm'), + ] + +def _seg_34(): + return [ + (0x339C, 'M', u'mm'), + (0x339D, 'M', u'cm'), + (0x339E, 'M', u'km'), + (0x339F, 'M', u'mm2'), + (0x33A0, 'M', u'cm2'), + (0x33A1, 'M', u'm2'), + (0x33A2, 'M', u'km2'), + (0x33A3, 'M', u'mm3'), + (0x33A4, 'M', u'cm3'), + (0x33A5, 'M', u'm3'), + (0x33A6, 'M', u'km3'), + (0x33A7, 'M', u'm∕s'), + (0x33A8, 'M', u'm∕s2'), + (0x33A9, 'M', u'pa'), + (0x33AA, 'M', u'kpa'), + (0x33AB, 'M', u'mpa'), + (0x33AC, 'M', u'gpa'), + (0x33AD, 'M', u'rad'), + (0x33AE, 'M', u'rad∕s'), + (0x33AF, 'M', u'rad∕s2'), + (0x33B0, 'M', u'ps'), + (0x33B1, 'M', u'ns'), + (0x33B2, 'M', u'μs'), + (0x33B3, 'M', u'ms'), + (0x33B4, 'M', u'pv'), + (0x33B5, 'M', u'nv'), + (0x33B6, 'M', u'μv'), + (0x33B7, 'M', u'mv'), + (0x33B8, 'M', u'kv'), + (0x33B9, 'M', u'mv'), + (0x33BA, 'M', u'pw'), + (0x33BB, 'M', u'nw'), + (0x33BC, 'M', u'μw'), + (0x33BD, 'M', u'mw'), + (0x33BE, 'M', u'kw'), + (0x33BF, 'M', u'mw'), + (0x33C0, 'M', u'kω'), + (0x33C1, 'M', u'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', u'bq'), + (0x33C4, 'M', u'cc'), + (0x33C5, 'M', u'cd'), + (0x33C6, 'M', u'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', u'db'), + (0x33C9, 'M', u'gy'), + (0x33CA, 'M', u'ha'), + (0x33CB, 'M', u'hp'), + (0x33CC, 'M', u'in'), + (0x33CD, 'M', u'kk'), + (0x33CE, 'M', u'km'), + (0x33CF, 'M', u'kt'), + (0x33D0, 'M', u'lm'), + (0x33D1, 'M', u'ln'), + (0x33D2, 'M', u'log'), + (0x33D3, 'M', u'lx'), + (0x33D4, 'M', u'mb'), + (0x33D5, 'M', u'mil'), + (0x33D6, 'M', u'mol'), + (0x33D7, 'M', u'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', u'ppm'), + (0x33DA, 'M', u'pr'), + (0x33DB, 'M', u'sr'), + (0x33DC, 'M', u'sv'), + (0x33DD, 'M', u'wb'), + (0x33DE, 'M', u'v∕m'), + (0x33DF, 'M', u'a∕m'), + (0x33E0, 'M', u'1日'), + (0x33E1, 'M', u'2日'), + (0x33E2, 'M', u'3日'), + (0x33E3, 'M', u'4日'), + (0x33E4, 'M', u'5日'), + (0x33E5, 'M', u'6日'), + (0x33E6, 'M', u'7日'), + (0x33E7, 'M', u'8日'), + (0x33E8, 'M', u'9日'), + (0x33E9, 'M', u'10日'), + (0x33EA, 'M', u'11日'), + (0x33EB, 'M', u'12日'), + (0x33EC, 'M', u'13日'), + (0x33ED, 'M', u'14日'), + (0x33EE, 'M', u'15日'), + (0x33EF, 'M', u'16日'), + (0x33F0, 'M', u'17日'), + (0x33F1, 'M', u'18日'), + (0x33F2, 'M', u'19日'), + (0x33F3, 'M', u'20日'), + (0x33F4, 'M', u'21日'), + (0x33F5, 'M', u'22日'), + (0x33F6, 'M', u'23日'), + (0x33F7, 'M', u'24日'), + (0x33F8, 'M', u'25日'), + (0x33F9, 'M', u'26日'), + (0x33FA, 'M', u'27日'), + (0x33FB, 'M', u'28日'), + (0x33FC, 'M', u'29日'), + (0x33FD, 'M', u'30日'), + (0x33FE, 'M', u'31日'), + (0x33FF, 'M', u'gal'), + ] + +def _seg_35(): + return [ + (0x3400, 'V'), + (0x4DB6, 'X'), + (0x4DC0, 'V'), + (0x9FCD, 'X'), + (0xA000, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', u'ꙁ'), + (0xA641, 'V'), + (0xA642, 'M', u'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', u'ꙅ'), + (0xA645, 'V'), + (0xA646, 'M', u'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', u'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', u'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', u'ꙍ'), + (0xA64D, 'V'), + (0xA64E, 'M', u'ꙏ'), + (0xA64F, 'V'), + (0xA650, 'M', u'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', u'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', u'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', u'ꙗ'), + (0xA657, 'V'), + (0xA658, 'M', u'ꙙ'), + (0xA659, 'V'), + (0xA65A, 'M', u'ꙛ'), + (0xA65B, 'V'), + (0xA65C, 'M', u'ꙝ'), + (0xA65D, 'V'), + (0xA65E, 'M', u'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', u'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', u'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', u'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', u'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', u'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', u'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', u'ꙭ'), + (0xA66D, 'V'), + (0xA680, 'M', u'ꚁ'), + (0xA681, 'V'), + (0xA682, 'M', u'ꚃ'), + (0xA683, 'V'), + (0xA684, 'M', u'ꚅ'), + (0xA685, 'V'), + (0xA686, 'M', u'ꚇ'), + (0xA687, 'V'), + (0xA688, 'M', u'ꚉ'), + (0xA689, 'V'), + (0xA68A, 'M', u'ꚋ'), + (0xA68B, 'V'), + (0xA68C, 'M', u'ꚍ'), + (0xA68D, 'V'), + (0xA68E, 'M', u'ꚏ'), + (0xA68F, 'V'), + (0xA690, 'M', u'ꚑ'), + (0xA691, 'V'), + (0xA692, 'M', u'ꚓ'), + (0xA693, 'V'), + (0xA694, 'M', u'ꚕ'), + (0xA695, 'V'), + (0xA696, 'M', u'ꚗ'), + (0xA697, 'V'), + (0xA698, 'X'), + (0xA69F, 'V'), + (0xA6F8, 'X'), + (0xA700, 'V'), + (0xA722, 'M', u'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', u'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', u'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', u'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', u'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', u'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', u'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', u'ꜳ'), + (0xA733, 'V'), + ] + +def _seg_36(): + return [ + (0xA734, 'M', u'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', u'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', u'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', u'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', u'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', u'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', u'ꝁ'), + (0xA741, 'V'), + (0xA742, 'M', u'ꝃ'), + (0xA743, 'V'), + (0xA744, 'M', u'ꝅ'), + (0xA745, 'V'), + (0xA746, 'M', u'ꝇ'), + (0xA747, 'V'), + (0xA748, 'M', u'ꝉ'), + (0xA749, 'V'), + (0xA74A, 'M', u'ꝋ'), + (0xA74B, 'V'), + (0xA74C, 'M', u'ꝍ'), + (0xA74D, 'V'), + (0xA74E, 'M', u'ꝏ'), + (0xA74F, 'V'), + (0xA750, 'M', u'ꝑ'), + (0xA751, 'V'), + (0xA752, 'M', u'ꝓ'), + (0xA753, 'V'), + (0xA754, 'M', u'ꝕ'), + (0xA755, 'V'), + (0xA756, 'M', u'ꝗ'), + (0xA757, 'V'), + (0xA758, 'M', u'ꝙ'), + (0xA759, 'V'), + (0xA75A, 'M', u'ꝛ'), + (0xA75B, 'V'), + (0xA75C, 'M', u'ꝝ'), + (0xA75D, 'V'), + (0xA75E, 'M', u'ꝟ'), + (0xA75F, 'V'), + (0xA760, 'M', u'ꝡ'), + (0xA761, 'V'), + (0xA762, 'M', u'ꝣ'), + (0xA763, 'V'), + (0xA764, 'M', u'ꝥ'), + (0xA765, 'V'), + (0xA766, 'M', u'ꝧ'), + (0xA767, 'V'), + (0xA768, 'M', u'ꝩ'), + (0xA769, 'V'), + (0xA76A, 'M', u'ꝫ'), + (0xA76B, 'V'), + (0xA76C, 'M', u'ꝭ'), + (0xA76D, 'V'), + (0xA76E, 'M', u'ꝯ'), + (0xA76F, 'V'), + (0xA770, 'M', u'ꝯ'), + (0xA771, 'V'), + (0xA779, 'M', u'ꝺ'), + (0xA77A, 'V'), + (0xA77B, 'M', u'ꝼ'), + (0xA77C, 'V'), + (0xA77D, 'M', u'ᵹ'), + (0xA77E, 'M', u'ꝿ'), + (0xA77F, 'V'), + (0xA780, 'M', u'ꞁ'), + (0xA781, 'V'), + (0xA782, 'M', u'ꞃ'), + (0xA783, 'V'), + (0xA784, 'M', u'ꞅ'), + (0xA785, 'V'), + (0xA786, 'M', u'ꞇ'), + (0xA787, 'V'), + (0xA78B, 'M', u'ꞌ'), + (0xA78C, 'V'), + (0xA78D, 'M', u'ɥ'), + (0xA78E, 'V'), + (0xA78F, 'X'), + (0xA790, 'M', u'ꞑ'), + (0xA791, 'V'), + (0xA792, 'M', u'ꞓ'), + (0xA793, 'V'), + (0xA794, 'X'), + (0xA7A0, 'M', u'ꞡ'), + (0xA7A1, 'V'), + (0xA7A2, 'M', u'ꞣ'), + (0xA7A3, 'V'), + (0xA7A4, 'M', u'ꞥ'), + (0xA7A5, 'V'), + (0xA7A6, 'M', u'ꞧ'), + (0xA7A7, 'V'), + (0xA7A8, 'M', u'ꞩ'), + (0xA7A9, 'V'), + (0xA7AA, 'M', u'ɦ'), + (0xA7AB, 'X'), + (0xA7F8, 'M', u'ħ'), + ] + +def _seg_37(): + return [ + (0xA7F9, 'M', u'œ'), + (0xA7FA, 'V'), + (0xA82C, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C5, 'X'), + (0xA8CE, 'V'), + (0xA8DA, 'X'), + (0xA8E0, 'V'), + (0xA8FC, 'X'), + (0xA900, 'V'), + (0xA954, 'X'), + (0xA95F, 'V'), + (0xA97D, 'X'), + (0xA980, 'V'), + (0xA9CE, 'X'), + (0xA9CF, 'V'), + (0xA9DA, 'X'), + (0xA9DE, 'V'), + (0xA9E0, 'X'), + (0xAA00, 'V'), + (0xAA37, 'X'), + (0xAA40, 'V'), + (0xAA4E, 'X'), + (0xAA50, 'V'), + (0xAA5A, 'X'), + (0xAA5C, 'V'), + (0xAA7C, 'X'), + (0xAA80, 'V'), + (0xAAC3, 'X'), + (0xAADB, 'V'), + (0xAAF7, 'X'), + (0xAB01, 'V'), + (0xAB07, 'X'), + (0xAB09, 'V'), + (0xAB0F, 'X'), + (0xAB11, 'V'), + (0xAB17, 'X'), + (0xAB20, 'V'), + (0xAB27, 'X'), + (0xAB28, 'V'), + (0xAB2F, 'X'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', u'豈'), + (0xF901, 'M', u'更'), + (0xF902, 'M', u'車'), + (0xF903, 'M', u'賈'), + (0xF904, 'M', u'滑'), + (0xF905, 'M', u'串'), + (0xF906, 'M', u'句'), + (0xF907, 'M', u'龜'), + (0xF909, 'M', u'契'), + (0xF90A, 'M', u'金'), + (0xF90B, 'M', u'喇'), + (0xF90C, 'M', u'奈'), + (0xF90D, 'M', u'懶'), + (0xF90E, 'M', u'癩'), + (0xF90F, 'M', u'羅'), + (0xF910, 'M', u'蘿'), + (0xF911, 'M', u'螺'), + (0xF912, 'M', u'裸'), + (0xF913, 'M', u'邏'), + (0xF914, 'M', u'樂'), + (0xF915, 'M', u'洛'), + (0xF916, 'M', u'烙'), + (0xF917, 'M', u'珞'), + (0xF918, 'M', u'落'), + (0xF919, 'M', u'酪'), + (0xF91A, 'M', u'駱'), + (0xF91B, 'M', u'亂'), + (0xF91C, 'M', u'卵'), + (0xF91D, 'M', u'欄'), + (0xF91E, 'M', u'爛'), + (0xF91F, 'M', u'蘭'), + (0xF920, 'M', u'鸞'), + (0xF921, 'M', u'嵐'), + (0xF922, 'M', u'濫'), + (0xF923, 'M', u'藍'), + (0xF924, 'M', u'襤'), + (0xF925, 'M', u'拉'), + (0xF926, 'M', u'臘'), + (0xF927, 'M', u'蠟'), + (0xF928, 'M', u'廊'), + (0xF929, 'M', u'朗'), + (0xF92A, 'M', u'浪'), + (0xF92B, 'M', u'狼'), + (0xF92C, 'M', u'郎'), + (0xF92D, 'M', u'來'), + ] + +def _seg_38(): + return [ + (0xF92E, 'M', u'冷'), + (0xF92F, 'M', u'勞'), + (0xF930, 'M', u'擄'), + (0xF931, 'M', u'櫓'), + (0xF932, 'M', u'爐'), + (0xF933, 'M', u'盧'), + (0xF934, 'M', u'老'), + (0xF935, 'M', u'蘆'), + (0xF936, 'M', u'虜'), + (0xF937, 'M', u'路'), + (0xF938, 'M', u'露'), + (0xF939, 'M', u'魯'), + (0xF93A, 'M', u'鷺'), + (0xF93B, 'M', u'碌'), + (0xF93C, 'M', u'祿'), + (0xF93D, 'M', u'綠'), + (0xF93E, 'M', u'菉'), + (0xF93F, 'M', u'錄'), + (0xF940, 'M', u'鹿'), + (0xF941, 'M', u'論'), + (0xF942, 'M', u'壟'), + (0xF943, 'M', u'弄'), + (0xF944, 'M', u'籠'), + (0xF945, 'M', u'聾'), + (0xF946, 'M', u'牢'), + (0xF947, 'M', u'磊'), + (0xF948, 'M', u'賂'), + (0xF949, 'M', u'雷'), + (0xF94A, 'M', u'壘'), + (0xF94B, 'M', u'屢'), + (0xF94C, 'M', u'樓'), + (0xF94D, 'M', u'淚'), + (0xF94E, 'M', u'漏'), + (0xF94F, 'M', u'累'), + (0xF950, 'M', u'縷'), + (0xF951, 'M', u'陋'), + (0xF952, 'M', u'勒'), + (0xF953, 'M', u'肋'), + (0xF954, 'M', u'凜'), + (0xF955, 'M', u'凌'), + (0xF956, 'M', u'稜'), + (0xF957, 'M', u'綾'), + (0xF958, 'M', u'菱'), + (0xF959, 'M', u'陵'), + (0xF95A, 'M', u'讀'), + (0xF95B, 'M', u'拏'), + (0xF95C, 'M', u'樂'), + (0xF95D, 'M', u'諾'), + (0xF95E, 'M', u'丹'), + (0xF95F, 'M', u'寧'), + (0xF960, 'M', u'怒'), + (0xF961, 'M', u'率'), + (0xF962, 'M', u'異'), + (0xF963, 'M', u'北'), + (0xF964, 'M', u'磻'), + (0xF965, 'M', u'便'), + (0xF966, 'M', u'復'), + (0xF967, 'M', u'不'), + (0xF968, 'M', u'泌'), + (0xF969, 'M', u'數'), + (0xF96A, 'M', u'索'), + (0xF96B, 'M', u'參'), + (0xF96C, 'M', u'塞'), + (0xF96D, 'M', u'省'), + (0xF96E, 'M', u'葉'), + (0xF96F, 'M', u'說'), + (0xF970, 'M', u'殺'), + (0xF971, 'M', u'辰'), + (0xF972, 'M', u'沈'), + (0xF973, 'M', u'拾'), + (0xF974, 'M', u'若'), + (0xF975, 'M', u'掠'), + (0xF976, 'M', u'略'), + (0xF977, 'M', u'亮'), + (0xF978, 'M', u'兩'), + (0xF979, 'M', u'凉'), + (0xF97A, 'M', u'梁'), + (0xF97B, 'M', u'糧'), + (0xF97C, 'M', u'良'), + (0xF97D, 'M', u'諒'), + (0xF97E, 'M', u'量'), + (0xF97F, 'M', u'勵'), + (0xF980, 'M', u'呂'), + (0xF981, 'M', u'女'), + (0xF982, 'M', u'廬'), + (0xF983, 'M', u'旅'), + (0xF984, 'M', u'濾'), + (0xF985, 'M', u'礪'), + (0xF986, 'M', u'閭'), + (0xF987, 'M', u'驪'), + (0xF988, 'M', u'麗'), + (0xF989, 'M', u'黎'), + (0xF98A, 'M', u'力'), + (0xF98B, 'M', u'曆'), + (0xF98C, 'M', u'歷'), + (0xF98D, 'M', u'轢'), + (0xF98E, 'M', u'年'), + (0xF98F, 'M', u'憐'), + (0xF990, 'M', u'戀'), + (0xF991, 'M', u'撚'), + ] + +def _seg_39(): + return [ + (0xF992, 'M', u'漣'), + (0xF993, 'M', u'煉'), + (0xF994, 'M', u'璉'), + (0xF995, 'M', u'秊'), + (0xF996, 'M', u'練'), + (0xF997, 'M', u'聯'), + (0xF998, 'M', u'輦'), + (0xF999, 'M', u'蓮'), + (0xF99A, 'M', u'連'), + (0xF99B, 'M', u'鍊'), + (0xF99C, 'M', u'列'), + (0xF99D, 'M', u'劣'), + (0xF99E, 'M', u'咽'), + (0xF99F, 'M', u'烈'), + (0xF9A0, 'M', u'裂'), + (0xF9A1, 'M', u'說'), + (0xF9A2, 'M', u'廉'), + (0xF9A3, 'M', u'念'), + (0xF9A4, 'M', u'捻'), + (0xF9A5, 'M', u'殮'), + (0xF9A6, 'M', u'簾'), + (0xF9A7, 'M', u'獵'), + (0xF9A8, 'M', u'令'), + (0xF9A9, 'M', u'囹'), + (0xF9AA, 'M', u'寧'), + (0xF9AB, 'M', u'嶺'), + (0xF9AC, 'M', u'怜'), + (0xF9AD, 'M', u'玲'), + (0xF9AE, 'M', u'瑩'), + (0xF9AF, 'M', u'羚'), + (0xF9B0, 'M', u'聆'), + (0xF9B1, 'M', u'鈴'), + (0xF9B2, 'M', u'零'), + (0xF9B3, 'M', u'靈'), + (0xF9B4, 'M', u'領'), + (0xF9B5, 'M', u'例'), + (0xF9B6, 'M', u'禮'), + (0xF9B7, 'M', u'醴'), + (0xF9B8, 'M', u'隸'), + (0xF9B9, 'M', u'惡'), + (0xF9BA, 'M', u'了'), + (0xF9BB, 'M', u'僚'), + (0xF9BC, 'M', u'寮'), + (0xF9BD, 'M', u'尿'), + (0xF9BE, 'M', u'料'), + (0xF9BF, 'M', u'樂'), + (0xF9C0, 'M', u'燎'), + (0xF9C1, 'M', u'療'), + (0xF9C2, 'M', u'蓼'), + (0xF9C3, 'M', u'遼'), + (0xF9C4, 'M', u'龍'), + (0xF9C5, 'M', u'暈'), + (0xF9C6, 'M', u'阮'), + (0xF9C7, 'M', u'劉'), + (0xF9C8, 'M', u'杻'), + (0xF9C9, 'M', u'柳'), + (0xF9CA, 'M', u'流'), + (0xF9CB, 'M', u'溜'), + (0xF9CC, 'M', u'琉'), + (0xF9CD, 'M', u'留'), + (0xF9CE, 'M', u'硫'), + (0xF9CF, 'M', u'紐'), + (0xF9D0, 'M', u'類'), + (0xF9D1, 'M', u'六'), + (0xF9D2, 'M', u'戮'), + (0xF9D3, 'M', u'陸'), + (0xF9D4, 'M', u'倫'), + (0xF9D5, 'M', u'崙'), + (0xF9D6, 'M', u'淪'), + (0xF9D7, 'M', u'輪'), + (0xF9D8, 'M', u'律'), + (0xF9D9, 'M', u'慄'), + (0xF9DA, 'M', u'栗'), + (0xF9DB, 'M', u'率'), + (0xF9DC, 'M', u'隆'), + (0xF9DD, 'M', u'利'), + (0xF9DE, 'M', u'吏'), + (0xF9DF, 'M', u'履'), + (0xF9E0, 'M', u'易'), + (0xF9E1, 'M', u'李'), + (0xF9E2, 'M', u'梨'), + (0xF9E3, 'M', u'泥'), + (0xF9E4, 'M', u'理'), + (0xF9E5, 'M', u'痢'), + (0xF9E6, 'M', u'罹'), + (0xF9E7, 'M', u'裏'), + (0xF9E8, 'M', u'裡'), + (0xF9E9, 'M', u'里'), + (0xF9EA, 'M', u'離'), + (0xF9EB, 'M', u'匿'), + (0xF9EC, 'M', u'溺'), + (0xF9ED, 'M', u'吝'), + (0xF9EE, 'M', u'燐'), + (0xF9EF, 'M', u'璘'), + (0xF9F0, 'M', u'藺'), + (0xF9F1, 'M', u'隣'), + (0xF9F2, 'M', u'鱗'), + (0xF9F3, 'M', u'麟'), + (0xF9F4, 'M', u'林'), + (0xF9F5, 'M', u'淋'), + ] + +def _seg_40(): + return [ + (0xF9F6, 'M', u'臨'), + (0xF9F7, 'M', u'立'), + (0xF9F8, 'M', u'笠'), + (0xF9F9, 'M', u'粒'), + (0xF9FA, 'M', u'狀'), + (0xF9FB, 'M', u'炙'), + (0xF9FC, 'M', u'識'), + (0xF9FD, 'M', u'什'), + (0xF9FE, 'M', u'茶'), + (0xF9FF, 'M', u'刺'), + (0xFA00, 'M', u'切'), + (0xFA01, 'M', u'度'), + (0xFA02, 'M', u'拓'), + (0xFA03, 'M', u'糖'), + (0xFA04, 'M', u'宅'), + (0xFA05, 'M', u'洞'), + (0xFA06, 'M', u'暴'), + (0xFA07, 'M', u'輻'), + (0xFA08, 'M', u'行'), + (0xFA09, 'M', u'降'), + (0xFA0A, 'M', u'見'), + (0xFA0B, 'M', u'廓'), + (0xFA0C, 'M', u'兀'), + (0xFA0D, 'M', u'嗀'), + (0xFA0E, 'V'), + (0xFA10, 'M', u'塚'), + (0xFA11, 'V'), + (0xFA12, 'M', u'晴'), + (0xFA13, 'V'), + (0xFA15, 'M', u'凞'), + (0xFA16, 'M', u'猪'), + (0xFA17, 'M', u'益'), + (0xFA18, 'M', u'礼'), + (0xFA19, 'M', u'神'), + (0xFA1A, 'M', u'祥'), + (0xFA1B, 'M', u'福'), + (0xFA1C, 'M', u'靖'), + (0xFA1D, 'M', u'精'), + (0xFA1E, 'M', u'羽'), + (0xFA1F, 'V'), + (0xFA20, 'M', u'蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', u'諸'), + (0xFA23, 'V'), + (0xFA25, 'M', u'逸'), + (0xFA26, 'M', u'都'), + (0xFA27, 'V'), + (0xFA2A, 'M', u'飯'), + (0xFA2B, 'M', u'飼'), + (0xFA2C, 'M', u'館'), + (0xFA2D, 'M', u'鶴'), + (0xFA2E, 'M', u'郞'), + (0xFA2F, 'M', u'隷'), + (0xFA30, 'M', u'侮'), + (0xFA31, 'M', u'僧'), + (0xFA32, 'M', u'免'), + (0xFA33, 'M', u'勉'), + (0xFA34, 'M', u'勤'), + (0xFA35, 'M', u'卑'), + (0xFA36, 'M', u'喝'), + (0xFA37, 'M', u'嘆'), + (0xFA38, 'M', u'器'), + (0xFA39, 'M', u'塀'), + (0xFA3A, 'M', u'墨'), + (0xFA3B, 'M', u'層'), + (0xFA3C, 'M', u'屮'), + (0xFA3D, 'M', u'悔'), + (0xFA3E, 'M', u'慨'), + (0xFA3F, 'M', u'憎'), + (0xFA40, 'M', u'懲'), + (0xFA41, 'M', u'敏'), + (0xFA42, 'M', u'既'), + (0xFA43, 'M', u'暑'), + (0xFA44, 'M', u'梅'), + (0xFA45, 'M', u'海'), + (0xFA46, 'M', u'渚'), + (0xFA47, 'M', u'漢'), + (0xFA48, 'M', u'煮'), + (0xFA49, 'M', u'爫'), + (0xFA4A, 'M', u'琢'), + (0xFA4B, 'M', u'碑'), + (0xFA4C, 'M', u'社'), + (0xFA4D, 'M', u'祉'), + (0xFA4E, 'M', u'祈'), + (0xFA4F, 'M', u'祐'), + (0xFA50, 'M', u'祖'), + (0xFA51, 'M', u'祝'), + (0xFA52, 'M', u'禍'), + (0xFA53, 'M', u'禎'), + (0xFA54, 'M', u'穀'), + (0xFA55, 'M', u'突'), + (0xFA56, 'M', u'節'), + (0xFA57, 'M', u'練'), + (0xFA58, 'M', u'縉'), + (0xFA59, 'M', u'繁'), + (0xFA5A, 'M', u'署'), + (0xFA5B, 'M', u'者'), + (0xFA5C, 'M', u'臭'), + (0xFA5D, 'M', u'艹'), + (0xFA5F, 'M', u'著'), + ] + +def _seg_41(): + return [ + (0xFA60, 'M', u'褐'), + (0xFA61, 'M', u'視'), + (0xFA62, 'M', u'謁'), + (0xFA63, 'M', u'謹'), + (0xFA64, 'M', u'賓'), + (0xFA65, 'M', u'贈'), + (0xFA66, 'M', u'辶'), + (0xFA67, 'M', u'逸'), + (0xFA68, 'M', u'難'), + (0xFA69, 'M', u'響'), + (0xFA6A, 'M', u'頻'), + (0xFA6B, 'M', u'恵'), + (0xFA6C, 'M', u'𤋮'), + (0xFA6D, 'M', u'舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', u'並'), + (0xFA71, 'M', u'况'), + (0xFA72, 'M', u'全'), + (0xFA73, 'M', u'侀'), + (0xFA74, 'M', u'充'), + (0xFA75, 'M', u'冀'), + (0xFA76, 'M', u'勇'), + (0xFA77, 'M', u'勺'), + (0xFA78, 'M', u'喝'), + (0xFA79, 'M', u'啕'), + (0xFA7A, 'M', u'喙'), + (0xFA7B, 'M', u'嗢'), + (0xFA7C, 'M', u'塚'), + (0xFA7D, 'M', u'墳'), + (0xFA7E, 'M', u'奄'), + (0xFA7F, 'M', u'奔'), + (0xFA80, 'M', u'婢'), + (0xFA81, 'M', u'嬨'), + (0xFA82, 'M', u'廒'), + (0xFA83, 'M', u'廙'), + (0xFA84, 'M', u'彩'), + (0xFA85, 'M', u'徭'), + (0xFA86, 'M', u'惘'), + (0xFA87, 'M', u'慎'), + (0xFA88, 'M', u'愈'), + (0xFA89, 'M', u'憎'), + (0xFA8A, 'M', u'慠'), + (0xFA8B, 'M', u'懲'), + (0xFA8C, 'M', u'戴'), + (0xFA8D, 'M', u'揄'), + (0xFA8E, 'M', u'搜'), + (0xFA8F, 'M', u'摒'), + (0xFA90, 'M', u'敖'), + (0xFA91, 'M', u'晴'), + (0xFA92, 'M', u'朗'), + (0xFA93, 'M', u'望'), + (0xFA94, 'M', u'杖'), + (0xFA95, 'M', u'歹'), + (0xFA96, 'M', u'殺'), + (0xFA97, 'M', u'流'), + (0xFA98, 'M', u'滛'), + (0xFA99, 'M', u'滋'), + (0xFA9A, 'M', u'漢'), + (0xFA9B, 'M', u'瀞'), + (0xFA9C, 'M', u'煮'), + (0xFA9D, 'M', u'瞧'), + (0xFA9E, 'M', u'爵'), + (0xFA9F, 'M', u'犯'), + (0xFAA0, 'M', u'猪'), + (0xFAA1, 'M', u'瑱'), + (0xFAA2, 'M', u'甆'), + (0xFAA3, 'M', u'画'), + (0xFAA4, 'M', u'瘝'), + (0xFAA5, 'M', u'瘟'), + (0xFAA6, 'M', u'益'), + (0xFAA7, 'M', u'盛'), + (0xFAA8, 'M', u'直'), + (0xFAA9, 'M', u'睊'), + (0xFAAA, 'M', u'着'), + (0xFAAB, 'M', u'磌'), + (0xFAAC, 'M', u'窱'), + (0xFAAD, 'M', u'節'), + (0xFAAE, 'M', u'类'), + (0xFAAF, 'M', u'絛'), + (0xFAB0, 'M', u'練'), + (0xFAB1, 'M', u'缾'), + (0xFAB2, 'M', u'者'), + (0xFAB3, 'M', u'荒'), + (0xFAB4, 'M', u'華'), + (0xFAB5, 'M', u'蝹'), + (0xFAB6, 'M', u'襁'), + (0xFAB7, 'M', u'覆'), + (0xFAB8, 'M', u'視'), + (0xFAB9, 'M', u'調'), + (0xFABA, 'M', u'諸'), + (0xFABB, 'M', u'請'), + (0xFABC, 'M', u'謁'), + (0xFABD, 'M', u'諾'), + (0xFABE, 'M', u'諭'), + (0xFABF, 'M', u'謹'), + (0xFAC0, 'M', u'變'), + (0xFAC1, 'M', u'贈'), + (0xFAC2, 'M', u'輸'), + (0xFAC3, 'M', u'遲'), + (0xFAC4, 'M', u'醙'), + ] + +def _seg_42(): + return [ + (0xFAC5, 'M', u'鉶'), + (0xFAC6, 'M', u'陼'), + (0xFAC7, 'M', u'難'), + (0xFAC8, 'M', u'靖'), + (0xFAC9, 'M', u'韛'), + (0xFACA, 'M', u'響'), + (0xFACB, 'M', u'頋'), + (0xFACC, 'M', u'頻'), + (0xFACD, 'M', u'鬒'), + (0xFACE, 'M', u'龜'), + (0xFACF, 'M', u'𢡊'), + (0xFAD0, 'M', u'𢡄'), + (0xFAD1, 'M', u'𣏕'), + (0xFAD2, 'M', u'㮝'), + (0xFAD3, 'M', u'䀘'), + (0xFAD4, 'M', u'䀹'), + (0xFAD5, 'M', u'𥉉'), + (0xFAD6, 'M', u'𥳐'), + (0xFAD7, 'M', u'𧻓'), + (0xFAD8, 'M', u'齃'), + (0xFAD9, 'M', u'龎'), + (0xFADA, 'X'), + (0xFB00, 'M', u'ff'), + (0xFB01, 'M', u'fi'), + (0xFB02, 'M', u'fl'), + (0xFB03, 'M', u'ffi'), + (0xFB04, 'M', u'ffl'), + (0xFB05, 'M', u'st'), + (0xFB07, 'X'), + (0xFB13, 'M', u'մն'), + (0xFB14, 'M', u'մե'), + (0xFB15, 'M', u'մի'), + (0xFB16, 'M', u'վն'), + (0xFB17, 'M', u'մխ'), + (0xFB18, 'X'), + (0xFB1D, 'M', u'יִ'), + (0xFB1E, 'V'), + (0xFB1F, 'M', u'ײַ'), + (0xFB20, 'M', u'ע'), + (0xFB21, 'M', u'א'), + (0xFB22, 'M', u'ד'), + (0xFB23, 'M', u'ה'), + (0xFB24, 'M', u'כ'), + (0xFB25, 'M', u'ל'), + (0xFB26, 'M', u'ם'), + (0xFB27, 'M', u'ר'), + (0xFB28, 'M', u'ת'), + (0xFB29, '3', u'+'), + (0xFB2A, 'M', u'שׁ'), + (0xFB2B, 'M', u'שׂ'), + (0xFB2C, 'M', u'שּׁ'), + (0xFB2D, 'M', u'שּׂ'), + (0xFB2E, 'M', u'אַ'), + (0xFB2F, 'M', u'אָ'), + (0xFB30, 'M', u'אּ'), + (0xFB31, 'M', u'בּ'), + (0xFB32, 'M', u'גּ'), + (0xFB33, 'M', u'דּ'), + (0xFB34, 'M', u'הּ'), + (0xFB35, 'M', u'וּ'), + (0xFB36, 'M', u'זּ'), + (0xFB37, 'X'), + (0xFB38, 'M', u'טּ'), + (0xFB39, 'M', u'יּ'), + (0xFB3A, 'M', u'ךּ'), + (0xFB3B, 'M', u'כּ'), + (0xFB3C, 'M', u'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', u'מּ'), + (0xFB3F, 'X'), + (0xFB40, 'M', u'נּ'), + (0xFB41, 'M', u'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', u'ףּ'), + (0xFB44, 'M', u'פּ'), + (0xFB45, 'X'), + (0xFB46, 'M', u'צּ'), + (0xFB47, 'M', u'קּ'), + (0xFB48, 'M', u'רּ'), + (0xFB49, 'M', u'שּ'), + (0xFB4A, 'M', u'תּ'), + (0xFB4B, 'M', u'וֹ'), + (0xFB4C, 'M', u'בֿ'), + (0xFB4D, 'M', u'כֿ'), + (0xFB4E, 'M', u'פֿ'), + (0xFB4F, 'M', u'אל'), + (0xFB50, 'M', u'ٱ'), + (0xFB52, 'M', u'ٻ'), + (0xFB56, 'M', u'پ'), + (0xFB5A, 'M', u'ڀ'), + (0xFB5E, 'M', u'ٺ'), + (0xFB62, 'M', u'ٿ'), + (0xFB66, 'M', u'ٹ'), + (0xFB6A, 'M', u'ڤ'), + (0xFB6E, 'M', u'ڦ'), + (0xFB72, 'M', u'ڄ'), + (0xFB76, 'M', u'ڃ'), + (0xFB7A, 'M', u'چ'), + (0xFB7E, 'M', u'ڇ'), + (0xFB82, 'M', u'ڍ'), + ] + +def _seg_43(): + return [ + (0xFB84, 'M', u'ڌ'), + (0xFB86, 'M', u'ڎ'), + (0xFB88, 'M', u'ڈ'), + (0xFB8A, 'M', u'ژ'), + (0xFB8C, 'M', u'ڑ'), + (0xFB8E, 'M', u'ک'), + (0xFB92, 'M', u'گ'), + (0xFB96, 'M', u'ڳ'), + (0xFB9A, 'M', u'ڱ'), + (0xFB9E, 'M', u'ں'), + (0xFBA0, 'M', u'ڻ'), + (0xFBA4, 'M', u'ۀ'), + (0xFBA6, 'M', u'ہ'), + (0xFBAA, 'M', u'ھ'), + (0xFBAE, 'M', u'ے'), + (0xFBB0, 'M', u'ۓ'), + (0xFBB2, 'V'), + (0xFBC2, 'X'), + (0xFBD3, 'M', u'ڭ'), + (0xFBD7, 'M', u'ۇ'), + (0xFBD9, 'M', u'ۆ'), + (0xFBDB, 'M', u'ۈ'), + (0xFBDD, 'M', u'ۇٴ'), + (0xFBDE, 'M', u'ۋ'), + (0xFBE0, 'M', u'ۅ'), + (0xFBE2, 'M', u'ۉ'), + (0xFBE4, 'M', u'ې'), + (0xFBE8, 'M', u'ى'), + (0xFBEA, 'M', u'ئا'), + (0xFBEC, 'M', u'ئە'), + (0xFBEE, 'M', u'ئو'), + (0xFBF0, 'M', u'ئۇ'), + (0xFBF2, 'M', u'ئۆ'), + (0xFBF4, 'M', u'ئۈ'), + (0xFBF6, 'M', u'ئې'), + (0xFBF9, 'M', u'ئى'), + (0xFBFC, 'M', u'ی'), + (0xFC00, 'M', u'ئج'), + (0xFC01, 'M', u'ئح'), + (0xFC02, 'M', u'ئم'), + (0xFC03, 'M', u'ئى'), + (0xFC04, 'M', u'ئي'), + (0xFC05, 'M', u'بج'), + (0xFC06, 'M', u'بح'), + (0xFC07, 'M', u'بخ'), + (0xFC08, 'M', u'بم'), + (0xFC09, 'M', u'بى'), + (0xFC0A, 'M', u'بي'), + (0xFC0B, 'M', u'تج'), + (0xFC0C, 'M', u'تح'), + (0xFC0D, 'M', u'تخ'), + (0xFC0E, 'M', u'تم'), + (0xFC0F, 'M', u'تى'), + (0xFC10, 'M', u'تي'), + (0xFC11, 'M', u'ثج'), + (0xFC12, 'M', u'ثم'), + (0xFC13, 'M', u'ثى'), + (0xFC14, 'M', u'ثي'), + (0xFC15, 'M', u'جح'), + (0xFC16, 'M', u'جم'), + (0xFC17, 'M', u'حج'), + (0xFC18, 'M', u'حم'), + (0xFC19, 'M', u'خج'), + (0xFC1A, 'M', u'خح'), + (0xFC1B, 'M', u'خم'), + (0xFC1C, 'M', u'سج'), + (0xFC1D, 'M', u'سح'), + (0xFC1E, 'M', u'سخ'), + (0xFC1F, 'M', u'سم'), + (0xFC20, 'M', u'صح'), + (0xFC21, 'M', u'صم'), + (0xFC22, 'M', u'ضج'), + (0xFC23, 'M', u'ضح'), + (0xFC24, 'M', u'ضخ'), + (0xFC25, 'M', u'ضم'), + (0xFC26, 'M', u'طح'), + (0xFC27, 'M', u'طم'), + (0xFC28, 'M', u'ظم'), + (0xFC29, 'M', u'عج'), + (0xFC2A, 'M', u'عم'), + (0xFC2B, 'M', u'غج'), + (0xFC2C, 'M', u'غم'), + (0xFC2D, 'M', u'فج'), + (0xFC2E, 'M', u'فح'), + (0xFC2F, 'M', u'فخ'), + (0xFC30, 'M', u'فم'), + (0xFC31, 'M', u'فى'), + (0xFC32, 'M', u'في'), + (0xFC33, 'M', u'قح'), + (0xFC34, 'M', u'قم'), + (0xFC35, 'M', u'قى'), + (0xFC36, 'M', u'قي'), + (0xFC37, 'M', u'كا'), + (0xFC38, 'M', u'كج'), + (0xFC39, 'M', u'كح'), + (0xFC3A, 'M', u'كخ'), + (0xFC3B, 'M', u'كل'), + (0xFC3C, 'M', u'كم'), + (0xFC3D, 'M', u'كى'), + (0xFC3E, 'M', u'كي'), + ] + +def _seg_44(): + return [ + (0xFC3F, 'M', u'لج'), + (0xFC40, 'M', u'لح'), + (0xFC41, 'M', u'لخ'), + (0xFC42, 'M', u'لم'), + (0xFC43, 'M', u'لى'), + (0xFC44, 'M', u'لي'), + (0xFC45, 'M', u'مج'), + (0xFC46, 'M', u'مح'), + (0xFC47, 'M', u'مخ'), + (0xFC48, 'M', u'مم'), + (0xFC49, 'M', u'مى'), + (0xFC4A, 'M', u'مي'), + (0xFC4B, 'M', u'نج'), + (0xFC4C, 'M', u'نح'), + (0xFC4D, 'M', u'نخ'), + (0xFC4E, 'M', u'نم'), + (0xFC4F, 'M', u'نى'), + (0xFC50, 'M', u'ني'), + (0xFC51, 'M', u'هج'), + (0xFC52, 'M', u'هم'), + (0xFC53, 'M', u'هى'), + (0xFC54, 'M', u'هي'), + (0xFC55, 'M', u'يج'), + (0xFC56, 'M', u'يح'), + (0xFC57, 'M', u'يخ'), + (0xFC58, 'M', u'يم'), + (0xFC59, 'M', u'يى'), + (0xFC5A, 'M', u'يي'), + (0xFC5B, 'M', u'ذٰ'), + (0xFC5C, 'M', u'رٰ'), + (0xFC5D, 'M', u'ىٰ'), + (0xFC5E, '3', u' ٌّ'), + (0xFC5F, '3', u' ٍّ'), + (0xFC60, '3', u' َّ'), + (0xFC61, '3', u' ُّ'), + (0xFC62, '3', u' ِّ'), + (0xFC63, '3', u' ّٰ'), + (0xFC64, 'M', u'ئر'), + (0xFC65, 'M', u'ئز'), + (0xFC66, 'M', u'ئم'), + (0xFC67, 'M', u'ئن'), + (0xFC68, 'M', u'ئى'), + (0xFC69, 'M', u'ئي'), + (0xFC6A, 'M', u'بر'), + (0xFC6B, 'M', u'بز'), + (0xFC6C, 'M', u'بم'), + (0xFC6D, 'M', u'بن'), + (0xFC6E, 'M', u'بى'), + (0xFC6F, 'M', u'بي'), + (0xFC70, 'M', u'تر'), + (0xFC71, 'M', u'تز'), + (0xFC72, 'M', u'تم'), + (0xFC73, 'M', u'تن'), + (0xFC74, 'M', u'تى'), + (0xFC75, 'M', u'تي'), + (0xFC76, 'M', u'ثر'), + (0xFC77, 'M', u'ثز'), + (0xFC78, 'M', u'ثم'), + (0xFC79, 'M', u'ثن'), + (0xFC7A, 'M', u'ثى'), + (0xFC7B, 'M', u'ثي'), + (0xFC7C, 'M', u'فى'), + (0xFC7D, 'M', u'في'), + (0xFC7E, 'M', u'قى'), + (0xFC7F, 'M', u'قي'), + (0xFC80, 'M', u'كا'), + (0xFC81, 'M', u'كل'), + (0xFC82, 'M', u'كم'), + (0xFC83, 'M', u'كى'), + (0xFC84, 'M', u'كي'), + (0xFC85, 'M', u'لم'), + (0xFC86, 'M', u'لى'), + (0xFC87, 'M', u'لي'), + (0xFC88, 'M', u'ما'), + (0xFC89, 'M', u'مم'), + (0xFC8A, 'M', u'نر'), + (0xFC8B, 'M', u'نز'), + (0xFC8C, 'M', u'نم'), + (0xFC8D, 'M', u'نن'), + (0xFC8E, 'M', u'نى'), + (0xFC8F, 'M', u'ني'), + (0xFC90, 'M', u'ىٰ'), + (0xFC91, 'M', u'ير'), + (0xFC92, 'M', u'يز'), + (0xFC93, 'M', u'يم'), + (0xFC94, 'M', u'ين'), + (0xFC95, 'M', u'يى'), + (0xFC96, 'M', u'يي'), + (0xFC97, 'M', u'ئج'), + (0xFC98, 'M', u'ئح'), + (0xFC99, 'M', u'ئخ'), + (0xFC9A, 'M', u'ئم'), + (0xFC9B, 'M', u'ئه'), + (0xFC9C, 'M', u'بج'), + (0xFC9D, 'M', u'بح'), + (0xFC9E, 'M', u'بخ'), + (0xFC9F, 'M', u'بم'), + (0xFCA0, 'M', u'به'), + (0xFCA1, 'M', u'تج'), + (0xFCA2, 'M', u'تح'), + ] + +def _seg_45(): + return [ + (0xFCA3, 'M', u'تخ'), + (0xFCA4, 'M', u'تم'), + (0xFCA5, 'M', u'ته'), + (0xFCA6, 'M', u'ثم'), + (0xFCA7, 'M', u'جح'), + (0xFCA8, 'M', u'جم'), + (0xFCA9, 'M', u'حج'), + (0xFCAA, 'M', u'حم'), + (0xFCAB, 'M', u'خج'), + (0xFCAC, 'M', u'خم'), + (0xFCAD, 'M', u'سج'), + (0xFCAE, 'M', u'سح'), + (0xFCAF, 'M', u'سخ'), + (0xFCB0, 'M', u'سم'), + (0xFCB1, 'M', u'صح'), + (0xFCB2, 'M', u'صخ'), + (0xFCB3, 'M', u'صم'), + (0xFCB4, 'M', u'ضج'), + (0xFCB5, 'M', u'ضح'), + (0xFCB6, 'M', u'ضخ'), + (0xFCB7, 'M', u'ضم'), + (0xFCB8, 'M', u'طح'), + (0xFCB9, 'M', u'ظم'), + (0xFCBA, 'M', u'عج'), + (0xFCBB, 'M', u'عم'), + (0xFCBC, 'M', u'غج'), + (0xFCBD, 'M', u'غم'), + (0xFCBE, 'M', u'فج'), + (0xFCBF, 'M', u'فح'), + (0xFCC0, 'M', u'فخ'), + (0xFCC1, 'M', u'فم'), + (0xFCC2, 'M', u'قح'), + (0xFCC3, 'M', u'قم'), + (0xFCC4, 'M', u'كج'), + (0xFCC5, 'M', u'كح'), + (0xFCC6, 'M', u'كخ'), + (0xFCC7, 'M', u'كل'), + (0xFCC8, 'M', u'كم'), + (0xFCC9, 'M', u'لج'), + (0xFCCA, 'M', u'لح'), + (0xFCCB, 'M', u'لخ'), + (0xFCCC, 'M', u'لم'), + (0xFCCD, 'M', u'له'), + (0xFCCE, 'M', u'مج'), + (0xFCCF, 'M', u'مح'), + (0xFCD0, 'M', u'مخ'), + (0xFCD1, 'M', u'مم'), + (0xFCD2, 'M', u'نج'), + (0xFCD3, 'M', u'نح'), + (0xFCD4, 'M', u'نخ'), + (0xFCD5, 'M', u'نم'), + (0xFCD6, 'M', u'نه'), + (0xFCD7, 'M', u'هج'), + (0xFCD8, 'M', u'هم'), + (0xFCD9, 'M', u'هٰ'), + (0xFCDA, 'M', u'يج'), + (0xFCDB, 'M', u'يح'), + (0xFCDC, 'M', u'يخ'), + (0xFCDD, 'M', u'يم'), + (0xFCDE, 'M', u'يه'), + (0xFCDF, 'M', u'ئم'), + (0xFCE0, 'M', u'ئه'), + (0xFCE1, 'M', u'بم'), + (0xFCE2, 'M', u'به'), + (0xFCE3, 'M', u'تم'), + (0xFCE4, 'M', u'ته'), + (0xFCE5, 'M', u'ثم'), + (0xFCE6, 'M', u'ثه'), + (0xFCE7, 'M', u'سم'), + (0xFCE8, 'M', u'سه'), + (0xFCE9, 'M', u'شم'), + (0xFCEA, 'M', u'شه'), + (0xFCEB, 'M', u'كل'), + (0xFCEC, 'M', u'كم'), + (0xFCED, 'M', u'لم'), + (0xFCEE, 'M', u'نم'), + (0xFCEF, 'M', u'نه'), + (0xFCF0, 'M', u'يم'), + (0xFCF1, 'M', u'يه'), + (0xFCF2, 'M', u'ـَّ'), + (0xFCF3, 'M', u'ـُّ'), + (0xFCF4, 'M', u'ـِّ'), + (0xFCF5, 'M', u'طى'), + (0xFCF6, 'M', u'طي'), + (0xFCF7, 'M', u'عى'), + (0xFCF8, 'M', u'عي'), + (0xFCF9, 'M', u'غى'), + (0xFCFA, 'M', u'غي'), + (0xFCFB, 'M', u'سى'), + (0xFCFC, 'M', u'سي'), + (0xFCFD, 'M', u'شى'), + (0xFCFE, 'M', u'شي'), + (0xFCFF, 'M', u'حى'), + (0xFD00, 'M', u'حي'), + (0xFD01, 'M', u'جى'), + (0xFD02, 'M', u'جي'), + (0xFD03, 'M', u'خى'), + (0xFD04, 'M', u'خي'), + (0xFD05, 'M', u'صى'), + (0xFD06, 'M', u'صي'), + ] + +def _seg_46(): + return [ + (0xFD07, 'M', u'ضى'), + (0xFD08, 'M', u'ضي'), + (0xFD09, 'M', u'شج'), + (0xFD0A, 'M', u'شح'), + (0xFD0B, 'M', u'شخ'), + (0xFD0C, 'M', u'شم'), + (0xFD0D, 'M', u'شر'), + (0xFD0E, 'M', u'سر'), + (0xFD0F, 'M', u'صر'), + (0xFD10, 'M', u'ضر'), + (0xFD11, 'M', u'طى'), + (0xFD12, 'M', u'طي'), + (0xFD13, 'M', u'عى'), + (0xFD14, 'M', u'عي'), + (0xFD15, 'M', u'غى'), + (0xFD16, 'M', u'غي'), + (0xFD17, 'M', u'سى'), + (0xFD18, 'M', u'سي'), + (0xFD19, 'M', u'شى'), + (0xFD1A, 'M', u'شي'), + (0xFD1B, 'M', u'حى'), + (0xFD1C, 'M', u'حي'), + (0xFD1D, 'M', u'جى'), + (0xFD1E, 'M', u'جي'), + (0xFD1F, 'M', u'خى'), + (0xFD20, 'M', u'خي'), + (0xFD21, 'M', u'صى'), + (0xFD22, 'M', u'صي'), + (0xFD23, 'M', u'ضى'), + (0xFD24, 'M', u'ضي'), + (0xFD25, 'M', u'شج'), + (0xFD26, 'M', u'شح'), + (0xFD27, 'M', u'شخ'), + (0xFD28, 'M', u'شم'), + (0xFD29, 'M', u'شر'), + (0xFD2A, 'M', u'سر'), + (0xFD2B, 'M', u'صر'), + (0xFD2C, 'M', u'ضر'), + (0xFD2D, 'M', u'شج'), + (0xFD2E, 'M', u'شح'), + (0xFD2F, 'M', u'شخ'), + (0xFD30, 'M', u'شم'), + (0xFD31, 'M', u'سه'), + (0xFD32, 'M', u'شه'), + (0xFD33, 'M', u'طم'), + (0xFD34, 'M', u'سج'), + (0xFD35, 'M', u'سح'), + (0xFD36, 'M', u'سخ'), + (0xFD37, 'M', u'شج'), + (0xFD38, 'M', u'شح'), + (0xFD39, 'M', u'شخ'), + (0xFD3A, 'M', u'طم'), + (0xFD3B, 'M', u'ظم'), + (0xFD3C, 'M', u'اً'), + (0xFD3E, 'V'), + (0xFD40, 'X'), + (0xFD50, 'M', u'تجم'), + (0xFD51, 'M', u'تحج'), + (0xFD53, 'M', u'تحم'), + (0xFD54, 'M', u'تخم'), + (0xFD55, 'M', u'تمج'), + (0xFD56, 'M', u'تمح'), + (0xFD57, 'M', u'تمخ'), + (0xFD58, 'M', u'جمح'), + (0xFD5A, 'M', u'حمي'), + (0xFD5B, 'M', u'حمى'), + (0xFD5C, 'M', u'سحج'), + (0xFD5D, 'M', u'سجح'), + (0xFD5E, 'M', u'سجى'), + (0xFD5F, 'M', u'سمح'), + (0xFD61, 'M', u'سمج'), + (0xFD62, 'M', u'سمم'), + (0xFD64, 'M', u'صحح'), + (0xFD66, 'M', u'صمم'), + (0xFD67, 'M', u'شحم'), + (0xFD69, 'M', u'شجي'), + (0xFD6A, 'M', u'شمخ'), + (0xFD6C, 'M', u'شمم'), + (0xFD6E, 'M', u'ضحى'), + (0xFD6F, 'M', u'ضخم'), + (0xFD71, 'M', u'طمح'), + (0xFD73, 'M', u'طمم'), + (0xFD74, 'M', u'طمي'), + (0xFD75, 'M', u'عجم'), + (0xFD76, 'M', u'عمم'), + (0xFD78, 'M', u'عمى'), + (0xFD79, 'M', u'غمم'), + (0xFD7A, 'M', u'غمي'), + (0xFD7B, 'M', u'غمى'), + (0xFD7C, 'M', u'فخم'), + (0xFD7E, 'M', u'قمح'), + (0xFD7F, 'M', u'قمم'), + (0xFD80, 'M', u'لحم'), + (0xFD81, 'M', u'لحي'), + (0xFD82, 'M', u'لحى'), + (0xFD83, 'M', u'لجج'), + (0xFD85, 'M', u'لخم'), + (0xFD87, 'M', u'لمح'), + (0xFD89, 'M', u'محج'), + (0xFD8A, 'M', u'محم'), + ] + +def _seg_47(): + return [ + (0xFD8B, 'M', u'محي'), + (0xFD8C, 'M', u'مجح'), + (0xFD8D, 'M', u'مجم'), + (0xFD8E, 'M', u'مخج'), + (0xFD8F, 'M', u'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', u'مجخ'), + (0xFD93, 'M', u'همج'), + (0xFD94, 'M', u'همم'), + (0xFD95, 'M', u'نحم'), + (0xFD96, 'M', u'نحى'), + (0xFD97, 'M', u'نجم'), + (0xFD99, 'M', u'نجى'), + (0xFD9A, 'M', u'نمي'), + (0xFD9B, 'M', u'نمى'), + (0xFD9C, 'M', u'يمم'), + (0xFD9E, 'M', u'بخي'), + (0xFD9F, 'M', u'تجي'), + (0xFDA0, 'M', u'تجى'), + (0xFDA1, 'M', u'تخي'), + (0xFDA2, 'M', u'تخى'), + (0xFDA3, 'M', u'تمي'), + (0xFDA4, 'M', u'تمى'), + (0xFDA5, 'M', u'جمي'), + (0xFDA6, 'M', u'جحى'), + (0xFDA7, 'M', u'جمى'), + (0xFDA8, 'M', u'سخى'), + (0xFDA9, 'M', u'صحي'), + (0xFDAA, 'M', u'شحي'), + (0xFDAB, 'M', u'ضحي'), + (0xFDAC, 'M', u'لجي'), + (0xFDAD, 'M', u'لمي'), + (0xFDAE, 'M', u'يحي'), + (0xFDAF, 'M', u'يجي'), + (0xFDB0, 'M', u'يمي'), + (0xFDB1, 'M', u'ممي'), + (0xFDB2, 'M', u'قمي'), + (0xFDB3, 'M', u'نحي'), + (0xFDB4, 'M', u'قمح'), + (0xFDB5, 'M', u'لحم'), + (0xFDB6, 'M', u'عمي'), + (0xFDB7, 'M', u'كمي'), + (0xFDB8, 'M', u'نجح'), + (0xFDB9, 'M', u'مخي'), + (0xFDBA, 'M', u'لجم'), + (0xFDBB, 'M', u'كمم'), + (0xFDBC, 'M', u'لجم'), + (0xFDBD, 'M', u'نجح'), + (0xFDBE, 'M', u'جحي'), + (0xFDBF, 'M', u'حجي'), + (0xFDC0, 'M', u'مجي'), + (0xFDC1, 'M', u'فمي'), + (0xFDC2, 'M', u'بحي'), + (0xFDC3, 'M', u'كمم'), + (0xFDC4, 'M', u'عجم'), + (0xFDC5, 'M', u'صمم'), + (0xFDC6, 'M', u'سخي'), + (0xFDC7, 'M', u'نجي'), + (0xFDC8, 'X'), + (0xFDF0, 'M', u'صلے'), + (0xFDF1, 'M', u'قلے'), + (0xFDF2, 'M', u'الله'), + (0xFDF3, 'M', u'اكبر'), + (0xFDF4, 'M', u'محمد'), + (0xFDF5, 'M', u'صلعم'), + (0xFDF6, 'M', u'رسول'), + (0xFDF7, 'M', u'عليه'), + (0xFDF8, 'M', u'وسلم'), + (0xFDF9, 'M', u'صلى'), + (0xFDFA, '3', u'صلى الله عليه وسلم'), + (0xFDFB, '3', u'جل جلاله'), + (0xFDFC, 'M', u'ریال'), + (0xFDFD, 'V'), + (0xFDFE, 'X'), + (0xFE00, 'I'), + (0xFE10, '3', u','), + (0xFE11, 'M', u'、'), + (0xFE12, 'X'), + (0xFE13, '3', u':'), + (0xFE14, '3', u';'), + (0xFE15, '3', u'!'), + (0xFE16, '3', u'?'), + (0xFE17, 'M', u'〖'), + (0xFE18, 'M', u'〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE27, 'X'), + (0xFE31, 'M', u'—'), + (0xFE32, 'M', u'–'), + (0xFE33, '3', u'_'), + (0xFE35, '3', u'('), + (0xFE36, '3', u')'), + (0xFE37, '3', u'{'), + (0xFE38, '3', u'}'), + (0xFE39, 'M', u'〔'), + (0xFE3A, 'M', u'〕'), + (0xFE3B, 'M', u'【'), + (0xFE3C, 'M', u'】'), + (0xFE3D, 'M', u'《'), + (0xFE3E, 'M', u'》'), + ] + +def _seg_48(): + return [ + (0xFE3F, 'M', u'〈'), + (0xFE40, 'M', u'〉'), + (0xFE41, 'M', u'「'), + (0xFE42, 'M', u'」'), + (0xFE43, 'M', u'『'), + (0xFE44, 'M', u'』'), + (0xFE45, 'V'), + (0xFE47, '3', u'['), + (0xFE48, '3', u']'), + (0xFE49, '3', u' ̅'), + (0xFE4D, '3', u'_'), + (0xFE50, '3', u','), + (0xFE51, 'M', u'、'), + (0xFE52, 'X'), + (0xFE54, '3', u';'), + (0xFE55, '3', u':'), + (0xFE56, '3', u'?'), + (0xFE57, '3', u'!'), + (0xFE58, 'M', u'—'), + (0xFE59, '3', u'('), + (0xFE5A, '3', u')'), + (0xFE5B, '3', u'{'), + (0xFE5C, '3', u'}'), + (0xFE5D, 'M', u'〔'), + (0xFE5E, 'M', u'〕'), + (0xFE5F, '3', u'#'), + (0xFE60, '3', u'&'), + (0xFE61, '3', u'*'), + (0xFE62, '3', u'+'), + (0xFE63, 'M', u'-'), + (0xFE64, '3', u'<'), + (0xFE65, '3', u'>'), + (0xFE66, '3', u'='), + (0xFE67, 'X'), + (0xFE68, '3', u'\\'), + (0xFE69, '3', u'$'), + (0xFE6A, '3', u'%'), + (0xFE6B, '3', u'@'), + (0xFE6C, 'X'), + (0xFE70, '3', u' ً'), + (0xFE71, 'M', u'ـً'), + (0xFE72, '3', u' ٌ'), + (0xFE73, 'V'), + (0xFE74, '3', u' ٍ'), + (0xFE75, 'X'), + (0xFE76, '3', u' َ'), + (0xFE77, 'M', u'ـَ'), + (0xFE78, '3', u' ُ'), + (0xFE79, 'M', u'ـُ'), + (0xFE7A, '3', u' ِ'), + (0xFE7B, 'M', u'ـِ'), + (0xFE7C, '3', u' ّ'), + (0xFE7D, 'M', u'ـّ'), + (0xFE7E, '3', u' ْ'), + (0xFE7F, 'M', u'ـْ'), + (0xFE80, 'M', u'ء'), + (0xFE81, 'M', u'آ'), + (0xFE83, 'M', u'أ'), + (0xFE85, 'M', u'ؤ'), + (0xFE87, 'M', u'إ'), + (0xFE89, 'M', u'ئ'), + (0xFE8D, 'M', u'ا'), + (0xFE8F, 'M', u'ب'), + (0xFE93, 'M', u'ة'), + (0xFE95, 'M', u'ت'), + (0xFE99, 'M', u'ث'), + (0xFE9D, 'M', u'ج'), + (0xFEA1, 'M', u'ح'), + (0xFEA5, 'M', u'خ'), + (0xFEA9, 'M', u'د'), + (0xFEAB, 'M', u'ذ'), + (0xFEAD, 'M', u'ر'), + (0xFEAF, 'M', u'ز'), + (0xFEB1, 'M', u'س'), + (0xFEB5, 'M', u'ش'), + (0xFEB9, 'M', u'ص'), + (0xFEBD, 'M', u'ض'), + (0xFEC1, 'M', u'ط'), + (0xFEC5, 'M', u'ظ'), + (0xFEC9, 'M', u'ع'), + (0xFECD, 'M', u'غ'), + (0xFED1, 'M', u'ف'), + (0xFED5, 'M', u'ق'), + (0xFED9, 'M', u'ك'), + (0xFEDD, 'M', u'ل'), + (0xFEE1, 'M', u'م'), + (0xFEE5, 'M', u'ن'), + (0xFEE9, 'M', u'ه'), + (0xFEED, 'M', u'و'), + (0xFEEF, 'M', u'ى'), + (0xFEF1, 'M', u'ي'), + (0xFEF5, 'M', u'لآ'), + (0xFEF7, 'M', u'لأ'), + (0xFEF9, 'M', u'لإ'), + (0xFEFB, 'M', u'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', u'!'), + (0xFF02, '3', u'"'), + ] + +def _seg_49(): + return [ + (0xFF03, '3', u'#'), + (0xFF04, '3', u'$'), + (0xFF05, '3', u'%'), + (0xFF06, '3', u'&'), + (0xFF07, '3', u'\''), + (0xFF08, '3', u'('), + (0xFF09, '3', u')'), + (0xFF0A, '3', u'*'), + (0xFF0B, '3', u'+'), + (0xFF0C, '3', u','), + (0xFF0D, 'M', u'-'), + (0xFF0E, 'M', u'.'), + (0xFF0F, '3', u'/'), + (0xFF10, 'M', u'0'), + (0xFF11, 'M', u'1'), + (0xFF12, 'M', u'2'), + (0xFF13, 'M', u'3'), + (0xFF14, 'M', u'4'), + (0xFF15, 'M', u'5'), + (0xFF16, 'M', u'6'), + (0xFF17, 'M', u'7'), + (0xFF18, 'M', u'8'), + (0xFF19, 'M', u'9'), + (0xFF1A, '3', u':'), + (0xFF1B, '3', u';'), + (0xFF1C, '3', u'<'), + (0xFF1D, '3', u'='), + (0xFF1E, '3', u'>'), + (0xFF1F, '3', u'?'), + (0xFF20, '3', u'@'), + (0xFF21, 'M', u'a'), + (0xFF22, 'M', u'b'), + (0xFF23, 'M', u'c'), + (0xFF24, 'M', u'd'), + (0xFF25, 'M', u'e'), + (0xFF26, 'M', u'f'), + (0xFF27, 'M', u'g'), + (0xFF28, 'M', u'h'), + (0xFF29, 'M', u'i'), + (0xFF2A, 'M', u'j'), + (0xFF2B, 'M', u'k'), + (0xFF2C, 'M', u'l'), + (0xFF2D, 'M', u'm'), + (0xFF2E, 'M', u'n'), + (0xFF2F, 'M', u'o'), + (0xFF30, 'M', u'p'), + (0xFF31, 'M', u'q'), + (0xFF32, 'M', u'r'), + (0xFF33, 'M', u's'), + (0xFF34, 'M', u't'), + (0xFF35, 'M', u'u'), + (0xFF36, 'M', u'v'), + (0xFF37, 'M', u'w'), + (0xFF38, 'M', u'x'), + (0xFF39, 'M', u'y'), + (0xFF3A, 'M', u'z'), + (0xFF3B, '3', u'['), + (0xFF3C, '3', u'\\'), + (0xFF3D, '3', u']'), + (0xFF3E, '3', u'^'), + (0xFF3F, '3', u'_'), + (0xFF40, '3', u'`'), + (0xFF41, 'M', u'a'), + (0xFF42, 'M', u'b'), + (0xFF43, 'M', u'c'), + (0xFF44, 'M', u'd'), + (0xFF45, 'M', u'e'), + (0xFF46, 'M', u'f'), + (0xFF47, 'M', u'g'), + (0xFF48, 'M', u'h'), + (0xFF49, 'M', u'i'), + (0xFF4A, 'M', u'j'), + (0xFF4B, 'M', u'k'), + (0xFF4C, 'M', u'l'), + (0xFF4D, 'M', u'm'), + (0xFF4E, 'M', u'n'), + (0xFF4F, 'M', u'o'), + (0xFF50, 'M', u'p'), + (0xFF51, 'M', u'q'), + (0xFF52, 'M', u'r'), + (0xFF53, 'M', u's'), + (0xFF54, 'M', u't'), + (0xFF55, 'M', u'u'), + (0xFF56, 'M', u'v'), + (0xFF57, 'M', u'w'), + (0xFF58, 'M', u'x'), + (0xFF59, 'M', u'y'), + (0xFF5A, 'M', u'z'), + (0xFF5B, '3', u'{'), + (0xFF5C, '3', u'|'), + (0xFF5D, '3', u'}'), + (0xFF5E, '3', u'~'), + (0xFF5F, 'M', u'⦅'), + (0xFF60, 'M', u'⦆'), + (0xFF61, 'M', u'.'), + (0xFF62, 'M', u'「'), + (0xFF63, 'M', u'」'), + (0xFF64, 'M', u'、'), + (0xFF65, 'M', u'・'), + (0xFF66, 'M', u'ヲ'), + ] + +def _seg_50(): + return [ + (0xFF67, 'M', u'ァ'), + (0xFF68, 'M', u'ィ'), + (0xFF69, 'M', u'ゥ'), + (0xFF6A, 'M', u'ェ'), + (0xFF6B, 'M', u'ォ'), + (0xFF6C, 'M', u'ャ'), + (0xFF6D, 'M', u'ュ'), + (0xFF6E, 'M', u'ョ'), + (0xFF6F, 'M', u'ッ'), + (0xFF70, 'M', u'ー'), + (0xFF71, 'M', u'ア'), + (0xFF72, 'M', u'イ'), + (0xFF73, 'M', u'ウ'), + (0xFF74, 'M', u'エ'), + (0xFF75, 'M', u'オ'), + (0xFF76, 'M', u'カ'), + (0xFF77, 'M', u'キ'), + (0xFF78, 'M', u'ク'), + (0xFF79, 'M', u'ケ'), + (0xFF7A, 'M', u'コ'), + (0xFF7B, 'M', u'サ'), + (0xFF7C, 'M', u'シ'), + (0xFF7D, 'M', u'ス'), + (0xFF7E, 'M', u'セ'), + (0xFF7F, 'M', u'ソ'), + (0xFF80, 'M', u'タ'), + (0xFF81, 'M', u'チ'), + (0xFF82, 'M', u'ツ'), + (0xFF83, 'M', u'テ'), + (0xFF84, 'M', u'ト'), + (0xFF85, 'M', u'ナ'), + (0xFF86, 'M', u'ニ'), + (0xFF87, 'M', u'ヌ'), + (0xFF88, 'M', u'ネ'), + (0xFF89, 'M', u'ノ'), + (0xFF8A, 'M', u'ハ'), + (0xFF8B, 'M', u'ヒ'), + (0xFF8C, 'M', u'フ'), + (0xFF8D, 'M', u'ヘ'), + (0xFF8E, 'M', u'ホ'), + (0xFF8F, 'M', u'マ'), + (0xFF90, 'M', u'ミ'), + (0xFF91, 'M', u'ム'), + (0xFF92, 'M', u'メ'), + (0xFF93, 'M', u'モ'), + (0xFF94, 'M', u'ヤ'), + (0xFF95, 'M', u'ユ'), + (0xFF96, 'M', u'ヨ'), + (0xFF97, 'M', u'ラ'), + (0xFF98, 'M', u'リ'), + (0xFF99, 'M', u'ル'), + (0xFF9A, 'M', u'レ'), + (0xFF9B, 'M', u'ロ'), + (0xFF9C, 'M', u'ワ'), + (0xFF9D, 'M', u'ン'), + (0xFF9E, 'M', u'゙'), + (0xFF9F, 'M', u'゚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', u'ᄀ'), + (0xFFA2, 'M', u'ᄁ'), + (0xFFA3, 'M', u'ᆪ'), + (0xFFA4, 'M', u'ᄂ'), + (0xFFA5, 'M', u'ᆬ'), + (0xFFA6, 'M', u'ᆭ'), + (0xFFA7, 'M', u'ᄃ'), + (0xFFA8, 'M', u'ᄄ'), + (0xFFA9, 'M', u'ᄅ'), + (0xFFAA, 'M', u'ᆰ'), + (0xFFAB, 'M', u'ᆱ'), + (0xFFAC, 'M', u'ᆲ'), + (0xFFAD, 'M', u'ᆳ'), + (0xFFAE, 'M', u'ᆴ'), + (0xFFAF, 'M', u'ᆵ'), + (0xFFB0, 'M', u'ᄚ'), + (0xFFB1, 'M', u'ᄆ'), + (0xFFB2, 'M', u'ᄇ'), + (0xFFB3, 'M', u'ᄈ'), + (0xFFB4, 'M', u'ᄡ'), + (0xFFB5, 'M', u'ᄉ'), + (0xFFB6, 'M', u'ᄊ'), + (0xFFB7, 'M', u'ᄋ'), + (0xFFB8, 'M', u'ᄌ'), + (0xFFB9, 'M', u'ᄍ'), + (0xFFBA, 'M', u'ᄎ'), + (0xFFBB, 'M', u'ᄏ'), + (0xFFBC, 'M', u'ᄐ'), + (0xFFBD, 'M', u'ᄑ'), + (0xFFBE, 'M', u'ᄒ'), + (0xFFBF, 'X'), + (0xFFC2, 'M', u'ᅡ'), + (0xFFC3, 'M', u'ᅢ'), + (0xFFC4, 'M', u'ᅣ'), + (0xFFC5, 'M', u'ᅤ'), + (0xFFC6, 'M', u'ᅥ'), + (0xFFC7, 'M', u'ᅦ'), + (0xFFC8, 'X'), + (0xFFCA, 'M', u'ᅧ'), + (0xFFCB, 'M', u'ᅨ'), + (0xFFCC, 'M', u'ᅩ'), + (0xFFCD, 'M', u'ᅪ'), + ] + +def _seg_51(): + return [ + (0xFFCE, 'M', u'ᅫ'), + (0xFFCF, 'M', u'ᅬ'), + (0xFFD0, 'X'), + (0xFFD2, 'M', u'ᅭ'), + (0xFFD3, 'M', u'ᅮ'), + (0xFFD4, 'M', u'ᅯ'), + (0xFFD5, 'M', u'ᅰ'), + (0xFFD6, 'M', u'ᅱ'), + (0xFFD7, 'M', u'ᅲ'), + (0xFFD8, 'X'), + (0xFFDA, 'M', u'ᅳ'), + (0xFFDB, 'M', u'ᅴ'), + (0xFFDC, 'M', u'ᅵ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', u'¢'), + (0xFFE1, 'M', u'£'), + (0xFFE2, 'M', u'¬'), + (0xFFE3, '3', u' ̄'), + (0xFFE4, 'M', u'¦'), + (0xFFE5, 'M', u'¥'), + (0xFFE6, 'M', u'₩'), + (0xFFE7, 'X'), + (0xFFE8, 'M', u'│'), + (0xFFE9, 'M', u'←'), + (0xFFEA, 'M', u'↑'), + (0xFFEB, 'M', u'→'), + (0xFFEC, 'M', u'↓'), + (0xFFED, 'M', u'■'), + (0xFFEE, 'M', u'○'), + (0xFFEF, 'X'), + (0x10000, 'V'), + (0x1000C, 'X'), + (0x1000D, 'V'), + (0x10027, 'X'), + (0x10028, 'V'), + (0x1003B, 'X'), + (0x1003C, 'V'), + (0x1003E, 'X'), + (0x1003F, 'V'), + (0x1004E, 'X'), + (0x10050, 'V'), + (0x1005E, 'X'), + (0x10080, 'V'), + (0x100FB, 'X'), + (0x10100, 'V'), + (0x10103, 'X'), + (0x10107, 'V'), + (0x10134, 'X'), + (0x10137, 'V'), + (0x1018B, 'X'), + (0x10190, 'V'), + (0x1019C, 'X'), + (0x101D0, 'V'), + (0x101FE, 'X'), + (0x10280, 'V'), + (0x1029D, 'X'), + (0x102A0, 'V'), + (0x102D1, 'X'), + (0x10300, 'V'), + (0x1031F, 'X'), + (0x10320, 'V'), + (0x10324, 'X'), + (0x10330, 'V'), + (0x1034B, 'X'), + (0x10380, 'V'), + (0x1039E, 'X'), + (0x1039F, 'V'), + (0x103C4, 'X'), + (0x103C8, 'V'), + (0x103D6, 'X'), + (0x10400, 'M', u'𐐨'), + (0x10401, 'M', u'𐐩'), + (0x10402, 'M', u'𐐪'), + (0x10403, 'M', u'𐐫'), + (0x10404, 'M', u'𐐬'), + (0x10405, 'M', u'𐐭'), + (0x10406, 'M', u'𐐮'), + (0x10407, 'M', u'𐐯'), + (0x10408, 'M', u'𐐰'), + (0x10409, 'M', u'𐐱'), + (0x1040A, 'M', u'𐐲'), + (0x1040B, 'M', u'𐐳'), + (0x1040C, 'M', u'𐐴'), + (0x1040D, 'M', u'𐐵'), + (0x1040E, 'M', u'𐐶'), + (0x1040F, 'M', u'𐐷'), + (0x10410, 'M', u'𐐸'), + (0x10411, 'M', u'𐐹'), + (0x10412, 'M', u'𐐺'), + (0x10413, 'M', u'𐐻'), + (0x10414, 'M', u'𐐼'), + (0x10415, 'M', u'𐐽'), + (0x10416, 'M', u'𐐾'), + (0x10417, 'M', u'𐐿'), + (0x10418, 'M', u'𐑀'), + (0x10419, 'M', u'𐑁'), + (0x1041A, 'M', u'𐑂'), + (0x1041B, 'M', u'𐑃'), + (0x1041C, 'M', u'𐑄'), + (0x1041D, 'M', u'𐑅'), + ] + +def _seg_52(): + return [ + (0x1041E, 'M', u'𐑆'), + (0x1041F, 'M', u'𐑇'), + (0x10420, 'M', u'𐑈'), + (0x10421, 'M', u'𐑉'), + (0x10422, 'M', u'𐑊'), + (0x10423, 'M', u'𐑋'), + (0x10424, 'M', u'𐑌'), + (0x10425, 'M', u'𐑍'), + (0x10426, 'M', u'𐑎'), + (0x10427, 'M', u'𐑏'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + (0x10839, 'X'), + (0x1083C, 'V'), + (0x1083D, 'X'), + (0x1083F, 'V'), + (0x10856, 'X'), + (0x10857, 'V'), + (0x10860, 'X'), + (0x10900, 'V'), + (0x1091C, 'X'), + (0x1091F, 'V'), + (0x1093A, 'X'), + (0x1093F, 'V'), + (0x10940, 'X'), + (0x10980, 'V'), + (0x109B8, 'X'), + (0x109BE, 'V'), + (0x109C0, 'X'), + (0x10A00, 'V'), + (0x10A04, 'X'), + (0x10A05, 'V'), + (0x10A07, 'X'), + (0x10A0C, 'V'), + (0x10A14, 'X'), + (0x10A15, 'V'), + (0x10A18, 'X'), + (0x10A19, 'V'), + (0x10A34, 'X'), + (0x10A38, 'V'), + (0x10A3B, 'X'), + (0x10A3F, 'V'), + (0x10A48, 'X'), + (0x10A50, 'V'), + (0x10A59, 'X'), + (0x10A60, 'V'), + (0x10A80, 'X'), + (0x10B00, 'V'), + (0x10B36, 'X'), + (0x10B39, 'V'), + (0x10B56, 'X'), + (0x10B58, 'V'), + (0x10B73, 'X'), + (0x10B78, 'V'), + (0x10B80, 'X'), + (0x10C00, 'V'), + (0x10C49, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11070, 'X'), + (0x11080, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + (0x110C2, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11144, 'X'), + (0x11180, 'V'), + (0x111C9, 'X'), + (0x111D0, 'V'), + (0x111DA, 'X'), + (0x11680, 'V'), + (0x116B8, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x12000, 'V'), + (0x1236F, 'X'), + (0x12400, 'V'), + (0x12463, 'X'), + (0x12470, 'V'), + (0x12474, 'X'), + (0x13000, 'V'), + (0x1342F, 'X'), + ] + +def _seg_53(): + return [ + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16F00, 'V'), + (0x16F45, 'X'), + (0x16F50, 'V'), + (0x16F7F, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x1B000, 'V'), + (0x1B002, 'X'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', u'𝅗𝅥'), + (0x1D15F, 'M', u'𝅘𝅥'), + (0x1D160, 'M', u'𝅘𝅥𝅮'), + (0x1D161, 'M', u'𝅘𝅥𝅯'), + (0x1D162, 'M', u'𝅘𝅥𝅰'), + (0x1D163, 'M', u'𝅘𝅥𝅱'), + (0x1D164, 'M', u'𝅘𝅥𝅲'), + (0x1D165, 'V'), + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', u'𝆹𝅥'), + (0x1D1BC, 'M', u'𝆺𝅥'), + (0x1D1BD, 'M', u'𝆹𝅥𝅮'), + (0x1D1BE, 'M', u'𝆺𝅥𝅮'), + (0x1D1BF, 'M', u'𝆹𝅥𝅯'), + (0x1D1C0, 'M', u'𝆺𝅥𝅯'), + (0x1D1C1, 'V'), + (0x1D1DE, 'X'), + (0x1D200, 'V'), + (0x1D246, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D372, 'X'), + (0x1D400, 'M', u'a'), + (0x1D401, 'M', u'b'), + (0x1D402, 'M', u'c'), + (0x1D403, 'M', u'd'), + (0x1D404, 'M', u'e'), + (0x1D405, 'M', u'f'), + (0x1D406, 'M', u'g'), + (0x1D407, 'M', u'h'), + (0x1D408, 'M', u'i'), + (0x1D409, 'M', u'j'), + (0x1D40A, 'M', u'k'), + (0x1D40B, 'M', u'l'), + (0x1D40C, 'M', u'm'), + (0x1D40D, 'M', u'n'), + (0x1D40E, 'M', u'o'), + (0x1D40F, 'M', u'p'), + (0x1D410, 'M', u'q'), + (0x1D411, 'M', u'r'), + (0x1D412, 'M', u's'), + (0x1D413, 'M', u't'), + (0x1D414, 'M', u'u'), + (0x1D415, 'M', u'v'), + (0x1D416, 'M', u'w'), + (0x1D417, 'M', u'x'), + (0x1D418, 'M', u'y'), + (0x1D419, 'M', u'z'), + (0x1D41A, 'M', u'a'), + (0x1D41B, 'M', u'b'), + (0x1D41C, 'M', u'c'), + (0x1D41D, 'M', u'd'), + (0x1D41E, 'M', u'e'), + (0x1D41F, 'M', u'f'), + (0x1D420, 'M', u'g'), + (0x1D421, 'M', u'h'), + (0x1D422, 'M', u'i'), + (0x1D423, 'M', u'j'), + (0x1D424, 'M', u'k'), + (0x1D425, 'M', u'l'), + (0x1D426, 'M', u'm'), + (0x1D427, 'M', u'n'), + (0x1D428, 'M', u'o'), + (0x1D429, 'M', u'p'), + (0x1D42A, 'M', u'q'), + (0x1D42B, 'M', u'r'), + (0x1D42C, 'M', u's'), + (0x1D42D, 'M', u't'), + (0x1D42E, 'M', u'u'), + (0x1D42F, 'M', u'v'), + (0x1D430, 'M', u'w'), + (0x1D431, 'M', u'x'), + (0x1D432, 'M', u'y'), + (0x1D433, 'M', u'z'), + (0x1D434, 'M', u'a'), + (0x1D435, 'M', u'b'), + (0x1D436, 'M', u'c'), + (0x1D437, 'M', u'd'), + (0x1D438, 'M', u'e'), + (0x1D439, 'M', u'f'), + (0x1D43A, 'M', u'g'), + (0x1D43B, 'M', u'h'), + (0x1D43C, 'M', u'i'), + ] + +def _seg_54(): + return [ + (0x1D43D, 'M', u'j'), + (0x1D43E, 'M', u'k'), + (0x1D43F, 'M', u'l'), + (0x1D440, 'M', u'm'), + (0x1D441, 'M', u'n'), + (0x1D442, 'M', u'o'), + (0x1D443, 'M', u'p'), + (0x1D444, 'M', u'q'), + (0x1D445, 'M', u'r'), + (0x1D446, 'M', u's'), + (0x1D447, 'M', u't'), + (0x1D448, 'M', u'u'), + (0x1D449, 'M', u'v'), + (0x1D44A, 'M', u'w'), + (0x1D44B, 'M', u'x'), + (0x1D44C, 'M', u'y'), + (0x1D44D, 'M', u'z'), + (0x1D44E, 'M', u'a'), + (0x1D44F, 'M', u'b'), + (0x1D450, 'M', u'c'), + (0x1D451, 'M', u'd'), + (0x1D452, 'M', u'e'), + (0x1D453, 'M', u'f'), + (0x1D454, 'M', u'g'), + (0x1D455, 'X'), + (0x1D456, 'M', u'i'), + (0x1D457, 'M', u'j'), + (0x1D458, 'M', u'k'), + (0x1D459, 'M', u'l'), + (0x1D45A, 'M', u'm'), + (0x1D45B, 'M', u'n'), + (0x1D45C, 'M', u'o'), + (0x1D45D, 'M', u'p'), + (0x1D45E, 'M', u'q'), + (0x1D45F, 'M', u'r'), + (0x1D460, 'M', u's'), + (0x1D461, 'M', u't'), + (0x1D462, 'M', u'u'), + (0x1D463, 'M', u'v'), + (0x1D464, 'M', u'w'), + (0x1D465, 'M', u'x'), + (0x1D466, 'M', u'y'), + (0x1D467, 'M', u'z'), + (0x1D468, 'M', u'a'), + (0x1D469, 'M', u'b'), + (0x1D46A, 'M', u'c'), + (0x1D46B, 'M', u'd'), + (0x1D46C, 'M', u'e'), + (0x1D46D, 'M', u'f'), + (0x1D46E, 'M', u'g'), + (0x1D46F, 'M', u'h'), + (0x1D470, 'M', u'i'), + (0x1D471, 'M', u'j'), + (0x1D472, 'M', u'k'), + (0x1D473, 'M', u'l'), + (0x1D474, 'M', u'm'), + (0x1D475, 'M', u'n'), + (0x1D476, 'M', u'o'), + (0x1D477, 'M', u'p'), + (0x1D478, 'M', u'q'), + (0x1D479, 'M', u'r'), + (0x1D47A, 'M', u's'), + (0x1D47B, 'M', u't'), + (0x1D47C, 'M', u'u'), + (0x1D47D, 'M', u'v'), + (0x1D47E, 'M', u'w'), + (0x1D47F, 'M', u'x'), + (0x1D480, 'M', u'y'), + (0x1D481, 'M', u'z'), + (0x1D482, 'M', u'a'), + (0x1D483, 'M', u'b'), + (0x1D484, 'M', u'c'), + (0x1D485, 'M', u'd'), + (0x1D486, 'M', u'e'), + (0x1D487, 'M', u'f'), + (0x1D488, 'M', u'g'), + (0x1D489, 'M', u'h'), + (0x1D48A, 'M', u'i'), + (0x1D48B, 'M', u'j'), + (0x1D48C, 'M', u'k'), + (0x1D48D, 'M', u'l'), + (0x1D48E, 'M', u'm'), + (0x1D48F, 'M', u'n'), + (0x1D490, 'M', u'o'), + (0x1D491, 'M', u'p'), + (0x1D492, 'M', u'q'), + (0x1D493, 'M', u'r'), + (0x1D494, 'M', u's'), + (0x1D495, 'M', u't'), + (0x1D496, 'M', u'u'), + (0x1D497, 'M', u'v'), + (0x1D498, 'M', u'w'), + (0x1D499, 'M', u'x'), + (0x1D49A, 'M', u'y'), + (0x1D49B, 'M', u'z'), + (0x1D49C, 'M', u'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', u'c'), + (0x1D49F, 'M', u'd'), + (0x1D4A0, 'X'), + ] + +def _seg_55(): + return [ + (0x1D4A2, 'M', u'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', u'j'), + (0x1D4A6, 'M', u'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', u'n'), + (0x1D4AA, 'M', u'o'), + (0x1D4AB, 'M', u'p'), + (0x1D4AC, 'M', u'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', u's'), + (0x1D4AF, 'M', u't'), + (0x1D4B0, 'M', u'u'), + (0x1D4B1, 'M', u'v'), + (0x1D4B2, 'M', u'w'), + (0x1D4B3, 'M', u'x'), + (0x1D4B4, 'M', u'y'), + (0x1D4B5, 'M', u'z'), + (0x1D4B6, 'M', u'a'), + (0x1D4B7, 'M', u'b'), + (0x1D4B8, 'M', u'c'), + (0x1D4B9, 'M', u'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', u'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', u'h'), + (0x1D4BE, 'M', u'i'), + (0x1D4BF, 'M', u'j'), + (0x1D4C0, 'M', u'k'), + (0x1D4C1, 'M', u'l'), + (0x1D4C2, 'M', u'm'), + (0x1D4C3, 'M', u'n'), + (0x1D4C4, 'X'), + (0x1D4C5, 'M', u'p'), + (0x1D4C6, 'M', u'q'), + (0x1D4C7, 'M', u'r'), + (0x1D4C8, 'M', u's'), + (0x1D4C9, 'M', u't'), + (0x1D4CA, 'M', u'u'), + (0x1D4CB, 'M', u'v'), + (0x1D4CC, 'M', u'w'), + (0x1D4CD, 'M', u'x'), + (0x1D4CE, 'M', u'y'), + (0x1D4CF, 'M', u'z'), + (0x1D4D0, 'M', u'a'), + (0x1D4D1, 'M', u'b'), + (0x1D4D2, 'M', u'c'), + (0x1D4D3, 'M', u'd'), + (0x1D4D4, 'M', u'e'), + (0x1D4D5, 'M', u'f'), + (0x1D4D6, 'M', u'g'), + (0x1D4D7, 'M', u'h'), + (0x1D4D8, 'M', u'i'), + (0x1D4D9, 'M', u'j'), + (0x1D4DA, 'M', u'k'), + (0x1D4DB, 'M', u'l'), + (0x1D4DC, 'M', u'm'), + (0x1D4DD, 'M', u'n'), + (0x1D4DE, 'M', u'o'), + (0x1D4DF, 'M', u'p'), + (0x1D4E0, 'M', u'q'), + (0x1D4E1, 'M', u'r'), + (0x1D4E2, 'M', u's'), + (0x1D4E3, 'M', u't'), + (0x1D4E4, 'M', u'u'), + (0x1D4E5, 'M', u'v'), + (0x1D4E6, 'M', u'w'), + (0x1D4E7, 'M', u'x'), + (0x1D4E8, 'M', u'y'), + (0x1D4E9, 'M', u'z'), + (0x1D4EA, 'M', u'a'), + (0x1D4EB, 'M', u'b'), + (0x1D4EC, 'M', u'c'), + (0x1D4ED, 'M', u'd'), + (0x1D4EE, 'M', u'e'), + (0x1D4EF, 'M', u'f'), + (0x1D4F0, 'M', u'g'), + (0x1D4F1, 'M', u'h'), + (0x1D4F2, 'M', u'i'), + (0x1D4F3, 'M', u'j'), + (0x1D4F4, 'M', u'k'), + (0x1D4F5, 'M', u'l'), + (0x1D4F6, 'M', u'm'), + (0x1D4F7, 'M', u'n'), + (0x1D4F8, 'M', u'o'), + (0x1D4F9, 'M', u'p'), + (0x1D4FA, 'M', u'q'), + (0x1D4FB, 'M', u'r'), + (0x1D4FC, 'M', u's'), + (0x1D4FD, 'M', u't'), + (0x1D4FE, 'M', u'u'), + (0x1D4FF, 'M', u'v'), + (0x1D500, 'M', u'w'), + (0x1D501, 'M', u'x'), + (0x1D502, 'M', u'y'), + (0x1D503, 'M', u'z'), + (0x1D504, 'M', u'a'), + (0x1D505, 'M', u'b'), + (0x1D506, 'X'), + (0x1D507, 'M', u'd'), + ] + +def _seg_56(): + return [ + (0x1D508, 'M', u'e'), + (0x1D509, 'M', u'f'), + (0x1D50A, 'M', u'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', u'j'), + (0x1D50E, 'M', u'k'), + (0x1D50F, 'M', u'l'), + (0x1D510, 'M', u'm'), + (0x1D511, 'M', u'n'), + (0x1D512, 'M', u'o'), + (0x1D513, 'M', u'p'), + (0x1D514, 'M', u'q'), + (0x1D515, 'X'), + (0x1D516, 'M', u's'), + (0x1D517, 'M', u't'), + (0x1D518, 'M', u'u'), + (0x1D519, 'M', u'v'), + (0x1D51A, 'M', u'w'), + (0x1D51B, 'M', u'x'), + (0x1D51C, 'M', u'y'), + (0x1D51D, 'X'), + (0x1D51E, 'M', u'a'), + (0x1D51F, 'M', u'b'), + (0x1D520, 'M', u'c'), + (0x1D521, 'M', u'd'), + (0x1D522, 'M', u'e'), + (0x1D523, 'M', u'f'), + (0x1D524, 'M', u'g'), + (0x1D525, 'M', u'h'), + (0x1D526, 'M', u'i'), + (0x1D527, 'M', u'j'), + (0x1D528, 'M', u'k'), + (0x1D529, 'M', u'l'), + (0x1D52A, 'M', u'm'), + (0x1D52B, 'M', u'n'), + (0x1D52C, 'M', u'o'), + (0x1D52D, 'M', u'p'), + (0x1D52E, 'M', u'q'), + (0x1D52F, 'M', u'r'), + (0x1D530, 'M', u's'), + (0x1D531, 'M', u't'), + (0x1D532, 'M', u'u'), + (0x1D533, 'M', u'v'), + (0x1D534, 'M', u'w'), + (0x1D535, 'M', u'x'), + (0x1D536, 'M', u'y'), + (0x1D537, 'M', u'z'), + (0x1D538, 'M', u'a'), + (0x1D539, 'M', u'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', u'd'), + (0x1D53C, 'M', u'e'), + (0x1D53D, 'M', u'f'), + (0x1D53E, 'M', u'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', u'i'), + (0x1D541, 'M', u'j'), + (0x1D542, 'M', u'k'), + (0x1D543, 'M', u'l'), + (0x1D544, 'M', u'm'), + (0x1D545, 'X'), + (0x1D546, 'M', u'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', u's'), + (0x1D54B, 'M', u't'), + (0x1D54C, 'M', u'u'), + (0x1D54D, 'M', u'v'), + (0x1D54E, 'M', u'w'), + (0x1D54F, 'M', u'x'), + (0x1D550, 'M', u'y'), + (0x1D551, 'X'), + (0x1D552, 'M', u'a'), + (0x1D553, 'M', u'b'), + (0x1D554, 'M', u'c'), + (0x1D555, 'M', u'd'), + (0x1D556, 'M', u'e'), + (0x1D557, 'M', u'f'), + (0x1D558, 'M', u'g'), + (0x1D559, 'M', u'h'), + (0x1D55A, 'M', u'i'), + (0x1D55B, 'M', u'j'), + (0x1D55C, 'M', u'k'), + (0x1D55D, 'M', u'l'), + (0x1D55E, 'M', u'm'), + (0x1D55F, 'M', u'n'), + (0x1D560, 'M', u'o'), + (0x1D561, 'M', u'p'), + (0x1D562, 'M', u'q'), + (0x1D563, 'M', u'r'), + (0x1D564, 'M', u's'), + (0x1D565, 'M', u't'), + (0x1D566, 'M', u'u'), + (0x1D567, 'M', u'v'), + (0x1D568, 'M', u'w'), + (0x1D569, 'M', u'x'), + (0x1D56A, 'M', u'y'), + (0x1D56B, 'M', u'z'), + (0x1D56C, 'M', u'a'), + (0x1D56D, 'M', u'b'), + (0x1D56E, 'M', u'c'), + ] + +def _seg_57(): + return [ + (0x1D56F, 'M', u'd'), + (0x1D570, 'M', u'e'), + (0x1D571, 'M', u'f'), + (0x1D572, 'M', u'g'), + (0x1D573, 'M', u'h'), + (0x1D574, 'M', u'i'), + (0x1D575, 'M', u'j'), + (0x1D576, 'M', u'k'), + (0x1D577, 'M', u'l'), + (0x1D578, 'M', u'm'), + (0x1D579, 'M', u'n'), + (0x1D57A, 'M', u'o'), + (0x1D57B, 'M', u'p'), + (0x1D57C, 'M', u'q'), + (0x1D57D, 'M', u'r'), + (0x1D57E, 'M', u's'), + (0x1D57F, 'M', u't'), + (0x1D580, 'M', u'u'), + (0x1D581, 'M', u'v'), + (0x1D582, 'M', u'w'), + (0x1D583, 'M', u'x'), + (0x1D584, 'M', u'y'), + (0x1D585, 'M', u'z'), + (0x1D586, 'M', u'a'), + (0x1D587, 'M', u'b'), + (0x1D588, 'M', u'c'), + (0x1D589, 'M', u'd'), + (0x1D58A, 'M', u'e'), + (0x1D58B, 'M', u'f'), + (0x1D58C, 'M', u'g'), + (0x1D58D, 'M', u'h'), + (0x1D58E, 'M', u'i'), + (0x1D58F, 'M', u'j'), + (0x1D590, 'M', u'k'), + (0x1D591, 'M', u'l'), + (0x1D592, 'M', u'm'), + (0x1D593, 'M', u'n'), + (0x1D594, 'M', u'o'), + (0x1D595, 'M', u'p'), + (0x1D596, 'M', u'q'), + (0x1D597, 'M', u'r'), + (0x1D598, 'M', u's'), + (0x1D599, 'M', u't'), + (0x1D59A, 'M', u'u'), + (0x1D59B, 'M', u'v'), + (0x1D59C, 'M', u'w'), + (0x1D59D, 'M', u'x'), + (0x1D59E, 'M', u'y'), + (0x1D59F, 'M', u'z'), + (0x1D5A0, 'M', u'a'), + (0x1D5A1, 'M', u'b'), + (0x1D5A2, 'M', u'c'), + (0x1D5A3, 'M', u'd'), + (0x1D5A4, 'M', u'e'), + (0x1D5A5, 'M', u'f'), + (0x1D5A6, 'M', u'g'), + (0x1D5A7, 'M', u'h'), + (0x1D5A8, 'M', u'i'), + (0x1D5A9, 'M', u'j'), + (0x1D5AA, 'M', u'k'), + (0x1D5AB, 'M', u'l'), + (0x1D5AC, 'M', u'm'), + (0x1D5AD, 'M', u'n'), + (0x1D5AE, 'M', u'o'), + (0x1D5AF, 'M', u'p'), + (0x1D5B0, 'M', u'q'), + (0x1D5B1, 'M', u'r'), + (0x1D5B2, 'M', u's'), + (0x1D5B3, 'M', u't'), + (0x1D5B4, 'M', u'u'), + (0x1D5B5, 'M', u'v'), + (0x1D5B6, 'M', u'w'), + (0x1D5B7, 'M', u'x'), + (0x1D5B8, 'M', u'y'), + (0x1D5B9, 'M', u'z'), + (0x1D5BA, 'M', u'a'), + (0x1D5BB, 'M', u'b'), + (0x1D5BC, 'M', u'c'), + (0x1D5BD, 'M', u'd'), + (0x1D5BE, 'M', u'e'), + (0x1D5BF, 'M', u'f'), + (0x1D5C0, 'M', u'g'), + (0x1D5C1, 'M', u'h'), + (0x1D5C2, 'M', u'i'), + (0x1D5C3, 'M', u'j'), + (0x1D5C4, 'M', u'k'), + (0x1D5C5, 'M', u'l'), + (0x1D5C6, 'M', u'm'), + (0x1D5C7, 'M', u'n'), + (0x1D5C8, 'M', u'o'), + (0x1D5C9, 'M', u'p'), + (0x1D5CA, 'M', u'q'), + (0x1D5CB, 'M', u'r'), + (0x1D5CC, 'M', u's'), + (0x1D5CD, 'M', u't'), + (0x1D5CE, 'M', u'u'), + (0x1D5CF, 'M', u'v'), + (0x1D5D0, 'M', u'w'), + (0x1D5D1, 'M', u'x'), + (0x1D5D2, 'M', u'y'), + ] + +def _seg_58(): + return [ + (0x1D5D3, 'M', u'z'), + (0x1D5D4, 'M', u'a'), + (0x1D5D5, 'M', u'b'), + (0x1D5D6, 'M', u'c'), + (0x1D5D7, 'M', u'd'), + (0x1D5D8, 'M', u'e'), + (0x1D5D9, 'M', u'f'), + (0x1D5DA, 'M', u'g'), + (0x1D5DB, 'M', u'h'), + (0x1D5DC, 'M', u'i'), + (0x1D5DD, 'M', u'j'), + (0x1D5DE, 'M', u'k'), + (0x1D5DF, 'M', u'l'), + (0x1D5E0, 'M', u'm'), + (0x1D5E1, 'M', u'n'), + (0x1D5E2, 'M', u'o'), + (0x1D5E3, 'M', u'p'), + (0x1D5E4, 'M', u'q'), + (0x1D5E5, 'M', u'r'), + (0x1D5E6, 'M', u's'), + (0x1D5E7, 'M', u't'), + (0x1D5E8, 'M', u'u'), + (0x1D5E9, 'M', u'v'), + (0x1D5EA, 'M', u'w'), + (0x1D5EB, 'M', u'x'), + (0x1D5EC, 'M', u'y'), + (0x1D5ED, 'M', u'z'), + (0x1D5EE, 'M', u'a'), + (0x1D5EF, 'M', u'b'), + (0x1D5F0, 'M', u'c'), + (0x1D5F1, 'M', u'd'), + (0x1D5F2, 'M', u'e'), + (0x1D5F3, 'M', u'f'), + (0x1D5F4, 'M', u'g'), + (0x1D5F5, 'M', u'h'), + (0x1D5F6, 'M', u'i'), + (0x1D5F7, 'M', u'j'), + (0x1D5F8, 'M', u'k'), + (0x1D5F9, 'M', u'l'), + (0x1D5FA, 'M', u'm'), + (0x1D5FB, 'M', u'n'), + (0x1D5FC, 'M', u'o'), + (0x1D5FD, 'M', u'p'), + (0x1D5FE, 'M', u'q'), + (0x1D5FF, 'M', u'r'), + (0x1D600, 'M', u's'), + (0x1D601, 'M', u't'), + (0x1D602, 'M', u'u'), + (0x1D603, 'M', u'v'), + (0x1D604, 'M', u'w'), + (0x1D605, 'M', u'x'), + (0x1D606, 'M', u'y'), + (0x1D607, 'M', u'z'), + (0x1D608, 'M', u'a'), + (0x1D609, 'M', u'b'), + (0x1D60A, 'M', u'c'), + (0x1D60B, 'M', u'd'), + (0x1D60C, 'M', u'e'), + (0x1D60D, 'M', u'f'), + (0x1D60E, 'M', u'g'), + (0x1D60F, 'M', u'h'), + (0x1D610, 'M', u'i'), + (0x1D611, 'M', u'j'), + (0x1D612, 'M', u'k'), + (0x1D613, 'M', u'l'), + (0x1D614, 'M', u'm'), + (0x1D615, 'M', u'n'), + (0x1D616, 'M', u'o'), + (0x1D617, 'M', u'p'), + (0x1D618, 'M', u'q'), + (0x1D619, 'M', u'r'), + (0x1D61A, 'M', u's'), + (0x1D61B, 'M', u't'), + (0x1D61C, 'M', u'u'), + (0x1D61D, 'M', u'v'), + (0x1D61E, 'M', u'w'), + (0x1D61F, 'M', u'x'), + (0x1D620, 'M', u'y'), + (0x1D621, 'M', u'z'), + (0x1D622, 'M', u'a'), + (0x1D623, 'M', u'b'), + (0x1D624, 'M', u'c'), + (0x1D625, 'M', u'd'), + (0x1D626, 'M', u'e'), + (0x1D627, 'M', u'f'), + (0x1D628, 'M', u'g'), + (0x1D629, 'M', u'h'), + (0x1D62A, 'M', u'i'), + (0x1D62B, 'M', u'j'), + (0x1D62C, 'M', u'k'), + (0x1D62D, 'M', u'l'), + (0x1D62E, 'M', u'm'), + (0x1D62F, 'M', u'n'), + (0x1D630, 'M', u'o'), + (0x1D631, 'M', u'p'), + (0x1D632, 'M', u'q'), + (0x1D633, 'M', u'r'), + (0x1D634, 'M', u's'), + (0x1D635, 'M', u't'), + (0x1D636, 'M', u'u'), + ] + +def _seg_59(): + return [ + (0x1D637, 'M', u'v'), + (0x1D638, 'M', u'w'), + (0x1D639, 'M', u'x'), + (0x1D63A, 'M', u'y'), + (0x1D63B, 'M', u'z'), + (0x1D63C, 'M', u'a'), + (0x1D63D, 'M', u'b'), + (0x1D63E, 'M', u'c'), + (0x1D63F, 'M', u'd'), + (0x1D640, 'M', u'e'), + (0x1D641, 'M', u'f'), + (0x1D642, 'M', u'g'), + (0x1D643, 'M', u'h'), + (0x1D644, 'M', u'i'), + (0x1D645, 'M', u'j'), + (0x1D646, 'M', u'k'), + (0x1D647, 'M', u'l'), + (0x1D648, 'M', u'm'), + (0x1D649, 'M', u'n'), + (0x1D64A, 'M', u'o'), + (0x1D64B, 'M', u'p'), + (0x1D64C, 'M', u'q'), + (0x1D64D, 'M', u'r'), + (0x1D64E, 'M', u's'), + (0x1D64F, 'M', u't'), + (0x1D650, 'M', u'u'), + (0x1D651, 'M', u'v'), + (0x1D652, 'M', u'w'), + (0x1D653, 'M', u'x'), + (0x1D654, 'M', u'y'), + (0x1D655, 'M', u'z'), + (0x1D656, 'M', u'a'), + (0x1D657, 'M', u'b'), + (0x1D658, 'M', u'c'), + (0x1D659, 'M', u'd'), + (0x1D65A, 'M', u'e'), + (0x1D65B, 'M', u'f'), + (0x1D65C, 'M', u'g'), + (0x1D65D, 'M', u'h'), + (0x1D65E, 'M', u'i'), + (0x1D65F, 'M', u'j'), + (0x1D660, 'M', u'k'), + (0x1D661, 'M', u'l'), + (0x1D662, 'M', u'm'), + (0x1D663, 'M', u'n'), + (0x1D664, 'M', u'o'), + (0x1D665, 'M', u'p'), + (0x1D666, 'M', u'q'), + (0x1D667, 'M', u'r'), + (0x1D668, 'M', u's'), + (0x1D669, 'M', u't'), + (0x1D66A, 'M', u'u'), + (0x1D66B, 'M', u'v'), + (0x1D66C, 'M', u'w'), + (0x1D66D, 'M', u'x'), + (0x1D66E, 'M', u'y'), + (0x1D66F, 'M', u'z'), + (0x1D670, 'M', u'a'), + (0x1D671, 'M', u'b'), + (0x1D672, 'M', u'c'), + (0x1D673, 'M', u'd'), + (0x1D674, 'M', u'e'), + (0x1D675, 'M', u'f'), + (0x1D676, 'M', u'g'), + (0x1D677, 'M', u'h'), + (0x1D678, 'M', u'i'), + (0x1D679, 'M', u'j'), + (0x1D67A, 'M', u'k'), + (0x1D67B, 'M', u'l'), + (0x1D67C, 'M', u'm'), + (0x1D67D, 'M', u'n'), + (0x1D67E, 'M', u'o'), + (0x1D67F, 'M', u'p'), + (0x1D680, 'M', u'q'), + (0x1D681, 'M', u'r'), + (0x1D682, 'M', u's'), + (0x1D683, 'M', u't'), + (0x1D684, 'M', u'u'), + (0x1D685, 'M', u'v'), + (0x1D686, 'M', u'w'), + (0x1D687, 'M', u'x'), + (0x1D688, 'M', u'y'), + (0x1D689, 'M', u'z'), + (0x1D68A, 'M', u'a'), + (0x1D68B, 'M', u'b'), + (0x1D68C, 'M', u'c'), + (0x1D68D, 'M', u'd'), + (0x1D68E, 'M', u'e'), + (0x1D68F, 'M', u'f'), + (0x1D690, 'M', u'g'), + (0x1D691, 'M', u'h'), + (0x1D692, 'M', u'i'), + (0x1D693, 'M', u'j'), + (0x1D694, 'M', u'k'), + (0x1D695, 'M', u'l'), + (0x1D696, 'M', u'm'), + (0x1D697, 'M', u'n'), + (0x1D698, 'M', u'o'), + (0x1D699, 'M', u'p'), + (0x1D69A, 'M', u'q'), + ] + +def _seg_60(): + return [ + (0x1D69B, 'M', u'r'), + (0x1D69C, 'M', u's'), + (0x1D69D, 'M', u't'), + (0x1D69E, 'M', u'u'), + (0x1D69F, 'M', u'v'), + (0x1D6A0, 'M', u'w'), + (0x1D6A1, 'M', u'x'), + (0x1D6A2, 'M', u'y'), + (0x1D6A3, 'M', u'z'), + (0x1D6A4, 'M', u'ı'), + (0x1D6A5, 'M', u'ȷ'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', u'α'), + (0x1D6A9, 'M', u'β'), + (0x1D6AA, 'M', u'γ'), + (0x1D6AB, 'M', u'δ'), + (0x1D6AC, 'M', u'ε'), + (0x1D6AD, 'M', u'ζ'), + (0x1D6AE, 'M', u'η'), + (0x1D6AF, 'M', u'θ'), + (0x1D6B0, 'M', u'ι'), + (0x1D6B1, 'M', u'κ'), + (0x1D6B2, 'M', u'λ'), + (0x1D6B3, 'M', u'μ'), + (0x1D6B4, 'M', u'ν'), + (0x1D6B5, 'M', u'ξ'), + (0x1D6B6, 'M', u'ο'), + (0x1D6B7, 'M', u'π'), + (0x1D6B8, 'M', u'ρ'), + (0x1D6B9, 'M', u'θ'), + (0x1D6BA, 'M', u'σ'), + (0x1D6BB, 'M', u'τ'), + (0x1D6BC, 'M', u'υ'), + (0x1D6BD, 'M', u'φ'), + (0x1D6BE, 'M', u'χ'), + (0x1D6BF, 'M', u'ψ'), + (0x1D6C0, 'M', u'ω'), + (0x1D6C1, 'M', u'∇'), + (0x1D6C2, 'M', u'α'), + (0x1D6C3, 'M', u'β'), + (0x1D6C4, 'M', u'γ'), + (0x1D6C5, 'M', u'δ'), + (0x1D6C6, 'M', u'ε'), + (0x1D6C7, 'M', u'ζ'), + (0x1D6C8, 'M', u'η'), + (0x1D6C9, 'M', u'θ'), + (0x1D6CA, 'M', u'ι'), + (0x1D6CB, 'M', u'κ'), + (0x1D6CC, 'M', u'λ'), + (0x1D6CD, 'M', u'μ'), + (0x1D6CE, 'M', u'ν'), + (0x1D6CF, 'M', u'ξ'), + (0x1D6D0, 'M', u'ο'), + (0x1D6D1, 'M', u'π'), + (0x1D6D2, 'M', u'ρ'), + (0x1D6D3, 'M', u'σ'), + (0x1D6D5, 'M', u'τ'), + (0x1D6D6, 'M', u'υ'), + (0x1D6D7, 'M', u'φ'), + (0x1D6D8, 'M', u'χ'), + (0x1D6D9, 'M', u'ψ'), + (0x1D6DA, 'M', u'ω'), + (0x1D6DB, 'M', u'∂'), + (0x1D6DC, 'M', u'ε'), + (0x1D6DD, 'M', u'θ'), + (0x1D6DE, 'M', u'κ'), + (0x1D6DF, 'M', u'φ'), + (0x1D6E0, 'M', u'ρ'), + (0x1D6E1, 'M', u'π'), + (0x1D6E2, 'M', u'α'), + (0x1D6E3, 'M', u'β'), + (0x1D6E4, 'M', u'γ'), + (0x1D6E5, 'M', u'δ'), + (0x1D6E6, 'M', u'ε'), + (0x1D6E7, 'M', u'ζ'), + (0x1D6E8, 'M', u'η'), + (0x1D6E9, 'M', u'θ'), + (0x1D6EA, 'M', u'ι'), + (0x1D6EB, 'M', u'κ'), + (0x1D6EC, 'M', u'λ'), + (0x1D6ED, 'M', u'μ'), + (0x1D6EE, 'M', u'ν'), + (0x1D6EF, 'M', u'ξ'), + (0x1D6F0, 'M', u'ο'), + (0x1D6F1, 'M', u'π'), + (0x1D6F2, 'M', u'ρ'), + (0x1D6F3, 'M', u'θ'), + (0x1D6F4, 'M', u'σ'), + (0x1D6F5, 'M', u'τ'), + (0x1D6F6, 'M', u'υ'), + (0x1D6F7, 'M', u'φ'), + (0x1D6F8, 'M', u'χ'), + (0x1D6F9, 'M', u'ψ'), + (0x1D6FA, 'M', u'ω'), + (0x1D6FB, 'M', u'∇'), + (0x1D6FC, 'M', u'α'), + (0x1D6FD, 'M', u'β'), + (0x1D6FE, 'M', u'γ'), + (0x1D6FF, 'M', u'δ'), + (0x1D700, 'M', u'ε'), + ] + +def _seg_61(): + return [ + (0x1D701, 'M', u'ζ'), + (0x1D702, 'M', u'η'), + (0x1D703, 'M', u'θ'), + (0x1D704, 'M', u'ι'), + (0x1D705, 'M', u'κ'), + (0x1D706, 'M', u'λ'), + (0x1D707, 'M', u'μ'), + (0x1D708, 'M', u'ν'), + (0x1D709, 'M', u'ξ'), + (0x1D70A, 'M', u'ο'), + (0x1D70B, 'M', u'π'), + (0x1D70C, 'M', u'ρ'), + (0x1D70D, 'M', u'σ'), + (0x1D70F, 'M', u'τ'), + (0x1D710, 'M', u'υ'), + (0x1D711, 'M', u'φ'), + (0x1D712, 'M', u'χ'), + (0x1D713, 'M', u'ψ'), + (0x1D714, 'M', u'ω'), + (0x1D715, 'M', u'∂'), + (0x1D716, 'M', u'ε'), + (0x1D717, 'M', u'θ'), + (0x1D718, 'M', u'κ'), + (0x1D719, 'M', u'φ'), + (0x1D71A, 'M', u'ρ'), + (0x1D71B, 'M', u'π'), + (0x1D71C, 'M', u'α'), + (0x1D71D, 'M', u'β'), + (0x1D71E, 'M', u'γ'), + (0x1D71F, 'M', u'δ'), + (0x1D720, 'M', u'ε'), + (0x1D721, 'M', u'ζ'), + (0x1D722, 'M', u'η'), + (0x1D723, 'M', u'θ'), + (0x1D724, 'M', u'ι'), + (0x1D725, 'M', u'κ'), + (0x1D726, 'M', u'λ'), + (0x1D727, 'M', u'μ'), + (0x1D728, 'M', u'ν'), + (0x1D729, 'M', u'ξ'), + (0x1D72A, 'M', u'ο'), + (0x1D72B, 'M', u'π'), + (0x1D72C, 'M', u'ρ'), + (0x1D72D, 'M', u'θ'), + (0x1D72E, 'M', u'σ'), + (0x1D72F, 'M', u'τ'), + (0x1D730, 'M', u'υ'), + (0x1D731, 'M', u'φ'), + (0x1D732, 'M', u'χ'), + (0x1D733, 'M', u'ψ'), + (0x1D734, 'M', u'ω'), + (0x1D735, 'M', u'∇'), + (0x1D736, 'M', u'α'), + (0x1D737, 'M', u'β'), + (0x1D738, 'M', u'γ'), + (0x1D739, 'M', u'δ'), + (0x1D73A, 'M', u'ε'), + (0x1D73B, 'M', u'ζ'), + (0x1D73C, 'M', u'η'), + (0x1D73D, 'M', u'θ'), + (0x1D73E, 'M', u'ι'), + (0x1D73F, 'M', u'κ'), + (0x1D740, 'M', u'λ'), + (0x1D741, 'M', u'μ'), + (0x1D742, 'M', u'ν'), + (0x1D743, 'M', u'ξ'), + (0x1D744, 'M', u'ο'), + (0x1D745, 'M', u'π'), + (0x1D746, 'M', u'ρ'), + (0x1D747, 'M', u'σ'), + (0x1D749, 'M', u'τ'), + (0x1D74A, 'M', u'υ'), + (0x1D74B, 'M', u'φ'), + (0x1D74C, 'M', u'χ'), + (0x1D74D, 'M', u'ψ'), + (0x1D74E, 'M', u'ω'), + (0x1D74F, 'M', u'∂'), + (0x1D750, 'M', u'ε'), + (0x1D751, 'M', u'θ'), + (0x1D752, 'M', u'κ'), + (0x1D753, 'M', u'φ'), + (0x1D754, 'M', u'ρ'), + (0x1D755, 'M', u'π'), + (0x1D756, 'M', u'α'), + (0x1D757, 'M', u'β'), + (0x1D758, 'M', u'γ'), + (0x1D759, 'M', u'δ'), + (0x1D75A, 'M', u'ε'), + (0x1D75B, 'M', u'ζ'), + (0x1D75C, 'M', u'η'), + (0x1D75D, 'M', u'θ'), + (0x1D75E, 'M', u'ι'), + (0x1D75F, 'M', u'κ'), + (0x1D760, 'M', u'λ'), + (0x1D761, 'M', u'μ'), + (0x1D762, 'M', u'ν'), + (0x1D763, 'M', u'ξ'), + (0x1D764, 'M', u'ο'), + (0x1D765, 'M', u'π'), + (0x1D766, 'M', u'ρ'), + ] + +def _seg_62(): + return [ + (0x1D767, 'M', u'θ'), + (0x1D768, 'M', u'σ'), + (0x1D769, 'M', u'τ'), + (0x1D76A, 'M', u'υ'), + (0x1D76B, 'M', u'φ'), + (0x1D76C, 'M', u'χ'), + (0x1D76D, 'M', u'ψ'), + (0x1D76E, 'M', u'ω'), + (0x1D76F, 'M', u'∇'), + (0x1D770, 'M', u'α'), + (0x1D771, 'M', u'β'), + (0x1D772, 'M', u'γ'), + (0x1D773, 'M', u'δ'), + (0x1D774, 'M', u'ε'), + (0x1D775, 'M', u'ζ'), + (0x1D776, 'M', u'η'), + (0x1D777, 'M', u'θ'), + (0x1D778, 'M', u'ι'), + (0x1D779, 'M', u'κ'), + (0x1D77A, 'M', u'λ'), + (0x1D77B, 'M', u'μ'), + (0x1D77C, 'M', u'ν'), + (0x1D77D, 'M', u'ξ'), + (0x1D77E, 'M', u'ο'), + (0x1D77F, 'M', u'π'), + (0x1D780, 'M', u'ρ'), + (0x1D781, 'M', u'σ'), + (0x1D783, 'M', u'τ'), + (0x1D784, 'M', u'υ'), + (0x1D785, 'M', u'φ'), + (0x1D786, 'M', u'χ'), + (0x1D787, 'M', u'ψ'), + (0x1D788, 'M', u'ω'), + (0x1D789, 'M', u'∂'), + (0x1D78A, 'M', u'ε'), + (0x1D78B, 'M', u'θ'), + (0x1D78C, 'M', u'κ'), + (0x1D78D, 'M', u'φ'), + (0x1D78E, 'M', u'ρ'), + (0x1D78F, 'M', u'π'), + (0x1D790, 'M', u'α'), + (0x1D791, 'M', u'β'), + (0x1D792, 'M', u'γ'), + (0x1D793, 'M', u'δ'), + (0x1D794, 'M', u'ε'), + (0x1D795, 'M', u'ζ'), + (0x1D796, 'M', u'η'), + (0x1D797, 'M', u'θ'), + (0x1D798, 'M', u'ι'), + (0x1D799, 'M', u'κ'), + (0x1D79A, 'M', u'λ'), + (0x1D79B, 'M', u'μ'), + (0x1D79C, 'M', u'ν'), + (0x1D79D, 'M', u'ξ'), + (0x1D79E, 'M', u'ο'), + (0x1D79F, 'M', u'π'), + (0x1D7A0, 'M', u'ρ'), + (0x1D7A1, 'M', u'θ'), + (0x1D7A2, 'M', u'σ'), + (0x1D7A3, 'M', u'τ'), + (0x1D7A4, 'M', u'υ'), + (0x1D7A5, 'M', u'φ'), + (0x1D7A6, 'M', u'χ'), + (0x1D7A7, 'M', u'ψ'), + (0x1D7A8, 'M', u'ω'), + (0x1D7A9, 'M', u'∇'), + (0x1D7AA, 'M', u'α'), + (0x1D7AB, 'M', u'β'), + (0x1D7AC, 'M', u'γ'), + (0x1D7AD, 'M', u'δ'), + (0x1D7AE, 'M', u'ε'), + (0x1D7AF, 'M', u'ζ'), + (0x1D7B0, 'M', u'η'), + (0x1D7B1, 'M', u'θ'), + (0x1D7B2, 'M', u'ι'), + (0x1D7B3, 'M', u'κ'), + (0x1D7B4, 'M', u'λ'), + (0x1D7B5, 'M', u'μ'), + (0x1D7B6, 'M', u'ν'), + (0x1D7B7, 'M', u'ξ'), + (0x1D7B8, 'M', u'ο'), + (0x1D7B9, 'M', u'π'), + (0x1D7BA, 'M', u'ρ'), + (0x1D7BB, 'M', u'σ'), + (0x1D7BD, 'M', u'τ'), + (0x1D7BE, 'M', u'υ'), + (0x1D7BF, 'M', u'φ'), + (0x1D7C0, 'M', u'χ'), + (0x1D7C1, 'M', u'ψ'), + (0x1D7C2, 'M', u'ω'), + (0x1D7C3, 'M', u'∂'), + (0x1D7C4, 'M', u'ε'), + (0x1D7C5, 'M', u'θ'), + (0x1D7C6, 'M', u'κ'), + (0x1D7C7, 'M', u'φ'), + (0x1D7C8, 'M', u'ρ'), + (0x1D7C9, 'M', u'π'), + (0x1D7CA, 'M', u'ϝ'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', u'0'), + ] + +def _seg_63(): + return [ + (0x1D7CF, 'M', u'1'), + (0x1D7D0, 'M', u'2'), + (0x1D7D1, 'M', u'3'), + (0x1D7D2, 'M', u'4'), + (0x1D7D3, 'M', u'5'), + (0x1D7D4, 'M', u'6'), + (0x1D7D5, 'M', u'7'), + (0x1D7D6, 'M', u'8'), + (0x1D7D7, 'M', u'9'), + (0x1D7D8, 'M', u'0'), + (0x1D7D9, 'M', u'1'), + (0x1D7DA, 'M', u'2'), + (0x1D7DB, 'M', u'3'), + (0x1D7DC, 'M', u'4'), + (0x1D7DD, 'M', u'5'), + (0x1D7DE, 'M', u'6'), + (0x1D7DF, 'M', u'7'), + (0x1D7E0, 'M', u'8'), + (0x1D7E1, 'M', u'9'), + (0x1D7E2, 'M', u'0'), + (0x1D7E3, 'M', u'1'), + (0x1D7E4, 'M', u'2'), + (0x1D7E5, 'M', u'3'), + (0x1D7E6, 'M', u'4'), + (0x1D7E7, 'M', u'5'), + (0x1D7E8, 'M', u'6'), + (0x1D7E9, 'M', u'7'), + (0x1D7EA, 'M', u'8'), + (0x1D7EB, 'M', u'9'), + (0x1D7EC, 'M', u'0'), + (0x1D7ED, 'M', u'1'), + (0x1D7EE, 'M', u'2'), + (0x1D7EF, 'M', u'3'), + (0x1D7F0, 'M', u'4'), + (0x1D7F1, 'M', u'5'), + (0x1D7F2, 'M', u'6'), + (0x1D7F3, 'M', u'7'), + (0x1D7F4, 'M', u'8'), + (0x1D7F5, 'M', u'9'), + (0x1D7F6, 'M', u'0'), + (0x1D7F7, 'M', u'1'), + (0x1D7F8, 'M', u'2'), + (0x1D7F9, 'M', u'3'), + (0x1D7FA, 'M', u'4'), + (0x1D7FB, 'M', u'5'), + (0x1D7FC, 'M', u'6'), + (0x1D7FD, 'M', u'7'), + (0x1D7FE, 'M', u'8'), + (0x1D7FF, 'M', u'9'), + (0x1D800, 'X'), + (0x1EE00, 'M', u'ا'), + (0x1EE01, 'M', u'ب'), + (0x1EE02, 'M', u'ج'), + (0x1EE03, 'M', u'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', u'و'), + (0x1EE06, 'M', u'ز'), + (0x1EE07, 'M', u'ح'), + (0x1EE08, 'M', u'ط'), + (0x1EE09, 'M', u'ي'), + (0x1EE0A, 'M', u'ك'), + (0x1EE0B, 'M', u'ل'), + (0x1EE0C, 'M', u'م'), + (0x1EE0D, 'M', u'ن'), + (0x1EE0E, 'M', u'س'), + (0x1EE0F, 'M', u'ع'), + (0x1EE10, 'M', u'ف'), + (0x1EE11, 'M', u'ص'), + (0x1EE12, 'M', u'ق'), + (0x1EE13, 'M', u'ر'), + (0x1EE14, 'M', u'ش'), + (0x1EE15, 'M', u'ت'), + (0x1EE16, 'M', u'ث'), + (0x1EE17, 'M', u'خ'), + (0x1EE18, 'M', u'ذ'), + (0x1EE19, 'M', u'ض'), + (0x1EE1A, 'M', u'ظ'), + (0x1EE1B, 'M', u'غ'), + (0x1EE1C, 'M', u'ٮ'), + (0x1EE1D, 'M', u'ں'), + (0x1EE1E, 'M', u'ڡ'), + (0x1EE1F, 'M', u'ٯ'), + (0x1EE20, 'X'), + (0x1EE21, 'M', u'ب'), + (0x1EE22, 'M', u'ج'), + (0x1EE23, 'X'), + (0x1EE24, 'M', u'ه'), + (0x1EE25, 'X'), + (0x1EE27, 'M', u'ح'), + (0x1EE28, 'X'), + (0x1EE29, 'M', u'ي'), + (0x1EE2A, 'M', u'ك'), + (0x1EE2B, 'M', u'ل'), + (0x1EE2C, 'M', u'م'), + (0x1EE2D, 'M', u'ن'), + (0x1EE2E, 'M', u'س'), + (0x1EE2F, 'M', u'ع'), + (0x1EE30, 'M', u'ف'), + (0x1EE31, 'M', u'ص'), + (0x1EE32, 'M', u'ق'), + ] + +def _seg_64(): + return [ + (0x1EE33, 'X'), + (0x1EE34, 'M', u'ش'), + (0x1EE35, 'M', u'ت'), + (0x1EE36, 'M', u'ث'), + (0x1EE37, 'M', u'خ'), + (0x1EE38, 'X'), + (0x1EE39, 'M', u'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', u'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', u'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', u'ح'), + (0x1EE48, 'X'), + (0x1EE49, 'M', u'ي'), + (0x1EE4A, 'X'), + (0x1EE4B, 'M', u'ل'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', u'ن'), + (0x1EE4E, 'M', u'س'), + (0x1EE4F, 'M', u'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', u'ص'), + (0x1EE52, 'M', u'ق'), + (0x1EE53, 'X'), + (0x1EE54, 'M', u'ش'), + (0x1EE55, 'X'), + (0x1EE57, 'M', u'خ'), + (0x1EE58, 'X'), + (0x1EE59, 'M', u'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', u'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', u'ں'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', u'ٯ'), + (0x1EE60, 'X'), + (0x1EE61, 'M', u'ب'), + (0x1EE62, 'M', u'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', u'ه'), + (0x1EE65, 'X'), + (0x1EE67, 'M', u'ح'), + (0x1EE68, 'M', u'ط'), + (0x1EE69, 'M', u'ي'), + (0x1EE6A, 'M', u'ك'), + (0x1EE6B, 'X'), + (0x1EE6C, 'M', u'م'), + (0x1EE6D, 'M', u'ن'), + (0x1EE6E, 'M', u'س'), + (0x1EE6F, 'M', u'ع'), + (0x1EE70, 'M', u'ف'), + (0x1EE71, 'M', u'ص'), + (0x1EE72, 'M', u'ق'), + (0x1EE73, 'X'), + (0x1EE74, 'M', u'ش'), + (0x1EE75, 'M', u'ت'), + (0x1EE76, 'M', u'ث'), + (0x1EE77, 'M', u'خ'), + (0x1EE78, 'X'), + (0x1EE79, 'M', u'ض'), + (0x1EE7A, 'M', u'ظ'), + (0x1EE7B, 'M', u'غ'), + (0x1EE7C, 'M', u'ٮ'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', u'ڡ'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', u'ا'), + (0x1EE81, 'M', u'ب'), + (0x1EE82, 'M', u'ج'), + (0x1EE83, 'M', u'د'), + (0x1EE84, 'M', u'ه'), + (0x1EE85, 'M', u'و'), + (0x1EE86, 'M', u'ز'), + (0x1EE87, 'M', u'ح'), + (0x1EE88, 'M', u'ط'), + (0x1EE89, 'M', u'ي'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', u'ل'), + (0x1EE8C, 'M', u'م'), + (0x1EE8D, 'M', u'ن'), + (0x1EE8E, 'M', u'س'), + (0x1EE8F, 'M', u'ع'), + (0x1EE90, 'M', u'ف'), + (0x1EE91, 'M', u'ص'), + (0x1EE92, 'M', u'ق'), + (0x1EE93, 'M', u'ر'), + (0x1EE94, 'M', u'ش'), + (0x1EE95, 'M', u'ت'), + (0x1EE96, 'M', u'ث'), + (0x1EE97, 'M', u'خ'), + (0x1EE98, 'M', u'ذ'), + (0x1EE99, 'M', u'ض'), + (0x1EE9A, 'M', u'ظ'), + (0x1EE9B, 'M', u'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', u'ب'), + (0x1EEA2, 'M', u'ج'), + (0x1EEA3, 'M', u'د'), + (0x1EEA4, 'X'), + ] + +def _seg_65(): + return [ + (0x1EEA5, 'M', u'و'), + (0x1EEA6, 'M', u'ز'), + (0x1EEA7, 'M', u'ح'), + (0x1EEA8, 'M', u'ط'), + (0x1EEA9, 'M', u'ي'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', u'ل'), + (0x1EEAC, 'M', u'م'), + (0x1EEAD, 'M', u'ن'), + (0x1EEAE, 'M', u'س'), + (0x1EEAF, 'M', u'ع'), + (0x1EEB0, 'M', u'ف'), + (0x1EEB1, 'M', u'ص'), + (0x1EEB2, 'M', u'ق'), + (0x1EEB3, 'M', u'ر'), + (0x1EEB4, 'M', u'ش'), + (0x1EEB5, 'M', u'ت'), + (0x1EEB6, 'M', u'ث'), + (0x1EEB7, 'M', u'خ'), + (0x1EEB8, 'M', u'ذ'), + (0x1EEB9, 'M', u'ض'), + (0x1EEBA, 'M', u'ظ'), + (0x1EEBB, 'M', u'غ'), + (0x1EEBC, 'X'), + (0x1EEF0, 'V'), + (0x1EEF2, 'X'), + (0x1F000, 'V'), + (0x1F02C, 'X'), + (0x1F030, 'V'), + (0x1F094, 'X'), + (0x1F0A0, 'V'), + (0x1F0AF, 'X'), + (0x1F0B1, 'V'), + (0x1F0BF, 'X'), + (0x1F0C1, 'V'), + (0x1F0D0, 'X'), + (0x1F0D1, 'V'), + (0x1F0E0, 'X'), + (0x1F101, '3', u'0,'), + (0x1F102, '3', u'1,'), + (0x1F103, '3', u'2,'), + (0x1F104, '3', u'3,'), + (0x1F105, '3', u'4,'), + (0x1F106, '3', u'5,'), + (0x1F107, '3', u'6,'), + (0x1F108, '3', u'7,'), + (0x1F109, '3', u'8,'), + (0x1F10A, '3', u'9,'), + (0x1F10B, 'X'), + (0x1F110, '3', u'(a)'), + (0x1F111, '3', u'(b)'), + (0x1F112, '3', u'(c)'), + (0x1F113, '3', u'(d)'), + (0x1F114, '3', u'(e)'), + (0x1F115, '3', u'(f)'), + (0x1F116, '3', u'(g)'), + (0x1F117, '3', u'(h)'), + (0x1F118, '3', u'(i)'), + (0x1F119, '3', u'(j)'), + (0x1F11A, '3', u'(k)'), + (0x1F11B, '3', u'(l)'), + (0x1F11C, '3', u'(m)'), + (0x1F11D, '3', u'(n)'), + (0x1F11E, '3', u'(o)'), + (0x1F11F, '3', u'(p)'), + (0x1F120, '3', u'(q)'), + (0x1F121, '3', u'(r)'), + (0x1F122, '3', u'(s)'), + (0x1F123, '3', u'(t)'), + (0x1F124, '3', u'(u)'), + (0x1F125, '3', u'(v)'), + (0x1F126, '3', u'(w)'), + (0x1F127, '3', u'(x)'), + (0x1F128, '3', u'(y)'), + (0x1F129, '3', u'(z)'), + (0x1F12A, 'M', u'〔s〕'), + (0x1F12B, 'M', u'c'), + (0x1F12C, 'M', u'r'), + (0x1F12D, 'M', u'cd'), + (0x1F12E, 'M', u'wz'), + (0x1F12F, 'X'), + (0x1F130, 'M', u'a'), + (0x1F131, 'M', u'b'), + (0x1F132, 'M', u'c'), + (0x1F133, 'M', u'd'), + (0x1F134, 'M', u'e'), + (0x1F135, 'M', u'f'), + (0x1F136, 'M', u'g'), + (0x1F137, 'M', u'h'), + (0x1F138, 'M', u'i'), + (0x1F139, 'M', u'j'), + (0x1F13A, 'M', u'k'), + (0x1F13B, 'M', u'l'), + (0x1F13C, 'M', u'm'), + (0x1F13D, 'M', u'n'), + (0x1F13E, 'M', u'o'), + (0x1F13F, 'M', u'p'), + (0x1F140, 'M', u'q'), + (0x1F141, 'M', u'r'), + (0x1F142, 'M', u's'), + ] + +def _seg_66(): + return [ + (0x1F143, 'M', u't'), + (0x1F144, 'M', u'u'), + (0x1F145, 'M', u'v'), + (0x1F146, 'M', u'w'), + (0x1F147, 'M', u'x'), + (0x1F148, 'M', u'y'), + (0x1F149, 'M', u'z'), + (0x1F14A, 'M', u'hv'), + (0x1F14B, 'M', u'mv'), + (0x1F14C, 'M', u'sd'), + (0x1F14D, 'M', u'ss'), + (0x1F14E, 'M', u'ppv'), + (0x1F14F, 'M', u'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', u'mc'), + (0x1F16B, 'M', u'md'), + (0x1F16C, 'X'), + (0x1F170, 'V'), + (0x1F190, 'M', u'dj'), + (0x1F191, 'V'), + (0x1F19B, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', u'ほか'), + (0x1F201, 'M', u'ココ'), + (0x1F202, 'M', u'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', u'手'), + (0x1F211, 'M', u'字'), + (0x1F212, 'M', u'双'), + (0x1F213, 'M', u'デ'), + (0x1F214, 'M', u'二'), + (0x1F215, 'M', u'多'), + (0x1F216, 'M', u'解'), + (0x1F217, 'M', u'天'), + (0x1F218, 'M', u'交'), + (0x1F219, 'M', u'映'), + (0x1F21A, 'M', u'無'), + (0x1F21B, 'M', u'料'), + (0x1F21C, 'M', u'前'), + (0x1F21D, 'M', u'後'), + (0x1F21E, 'M', u'再'), + (0x1F21F, 'M', u'新'), + (0x1F220, 'M', u'初'), + (0x1F221, 'M', u'終'), + (0x1F222, 'M', u'生'), + (0x1F223, 'M', u'販'), + (0x1F224, 'M', u'声'), + (0x1F225, 'M', u'吹'), + (0x1F226, 'M', u'演'), + (0x1F227, 'M', u'投'), + (0x1F228, 'M', u'捕'), + (0x1F229, 'M', u'一'), + (0x1F22A, 'M', u'三'), + (0x1F22B, 'M', u'遊'), + (0x1F22C, 'M', u'左'), + (0x1F22D, 'M', u'中'), + (0x1F22E, 'M', u'右'), + (0x1F22F, 'M', u'指'), + (0x1F230, 'M', u'走'), + (0x1F231, 'M', u'打'), + (0x1F232, 'M', u'禁'), + (0x1F233, 'M', u'空'), + (0x1F234, 'M', u'合'), + (0x1F235, 'M', u'満'), + (0x1F236, 'M', u'有'), + (0x1F237, 'M', u'月'), + (0x1F238, 'M', u'申'), + (0x1F239, 'M', u'割'), + (0x1F23A, 'M', u'営'), + (0x1F23B, 'X'), + (0x1F240, 'M', u'〔本〕'), + (0x1F241, 'M', u'〔三〕'), + (0x1F242, 'M', u'〔二〕'), + (0x1F243, 'M', u'〔安〕'), + (0x1F244, 'M', u'〔点〕'), + (0x1F245, 'M', u'〔打〕'), + (0x1F246, 'M', u'〔盗〕'), + (0x1F247, 'M', u'〔勝〕'), + (0x1F248, 'M', u'〔敗〕'), + (0x1F249, 'X'), + (0x1F250, 'M', u'得'), + (0x1F251, 'M', u'可'), + (0x1F252, 'X'), + (0x1F300, 'V'), + (0x1F321, 'X'), + (0x1F330, 'V'), + (0x1F336, 'X'), + (0x1F337, 'V'), + (0x1F37D, 'X'), + (0x1F380, 'V'), + (0x1F394, 'X'), + (0x1F3A0, 'V'), + (0x1F3C5, 'X'), + (0x1F3C6, 'V'), + (0x1F3CB, 'X'), + (0x1F3E0, 'V'), + (0x1F3F1, 'X'), + (0x1F400, 'V'), + (0x1F43F, 'X'), + (0x1F440, 'V'), + ] + +def _seg_67(): + return [ + (0x1F441, 'X'), + (0x1F442, 'V'), + (0x1F4F8, 'X'), + (0x1F4F9, 'V'), + (0x1F4FD, 'X'), + (0x1F500, 'V'), + (0x1F53E, 'X'), + (0x1F540, 'V'), + (0x1F544, 'X'), + (0x1F550, 'V'), + (0x1F568, 'X'), + (0x1F5FB, 'V'), + (0x1F641, 'X'), + (0x1F645, 'V'), + (0x1F650, 'X'), + (0x1F680, 'V'), + (0x1F6C6, 'X'), + (0x1F700, 'V'), + (0x1F774, 'X'), + (0x20000, 'V'), + (0x2A6D7, 'X'), + (0x2A700, 'V'), + (0x2B735, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2F800, 'M', u'丽'), + (0x2F801, 'M', u'丸'), + (0x2F802, 'M', u'乁'), + (0x2F803, 'M', u'𠄢'), + (0x2F804, 'M', u'你'), + (0x2F805, 'M', u'侮'), + (0x2F806, 'M', u'侻'), + (0x2F807, 'M', u'倂'), + (0x2F808, 'M', u'偺'), + (0x2F809, 'M', u'備'), + (0x2F80A, 'M', u'僧'), + (0x2F80B, 'M', u'像'), + (0x2F80C, 'M', u'㒞'), + (0x2F80D, 'M', u'𠘺'), + (0x2F80E, 'M', u'免'), + (0x2F80F, 'M', u'兔'), + (0x2F810, 'M', u'兤'), + (0x2F811, 'M', u'具'), + (0x2F812, 'M', u'𠔜'), + (0x2F813, 'M', u'㒹'), + (0x2F814, 'M', u'內'), + (0x2F815, 'M', u'再'), + (0x2F816, 'M', u'𠕋'), + (0x2F817, 'M', u'冗'), + (0x2F818, 'M', u'冤'), + (0x2F819, 'M', u'仌'), + (0x2F81A, 'M', u'冬'), + (0x2F81B, 'M', u'况'), + (0x2F81C, 'M', u'𩇟'), + (0x2F81D, 'M', u'凵'), + (0x2F81E, 'M', u'刃'), + (0x2F81F, 'M', u'㓟'), + (0x2F820, 'M', u'刻'), + (0x2F821, 'M', u'剆'), + (0x2F822, 'M', u'割'), + (0x2F823, 'M', u'剷'), + (0x2F824, 'M', u'㔕'), + (0x2F825, 'M', u'勇'), + (0x2F826, 'M', u'勉'), + (0x2F827, 'M', u'勤'), + (0x2F828, 'M', u'勺'), + (0x2F829, 'M', u'包'), + (0x2F82A, 'M', u'匆'), + (0x2F82B, 'M', u'北'), + (0x2F82C, 'M', u'卉'), + (0x2F82D, 'M', u'卑'), + (0x2F82E, 'M', u'博'), + (0x2F82F, 'M', u'即'), + (0x2F830, 'M', u'卽'), + (0x2F831, 'M', u'卿'), + (0x2F834, 'M', u'𠨬'), + (0x2F835, 'M', u'灰'), + (0x2F836, 'M', u'及'), + (0x2F837, 'M', u'叟'), + (0x2F838, 'M', u'𠭣'), + (0x2F839, 'M', u'叫'), + (0x2F83A, 'M', u'叱'), + (0x2F83B, 'M', u'吆'), + (0x2F83C, 'M', u'咞'), + (0x2F83D, 'M', u'吸'), + (0x2F83E, 'M', u'呈'), + (0x2F83F, 'M', u'周'), + (0x2F840, 'M', u'咢'), + (0x2F841, 'M', u'哶'), + (0x2F842, 'M', u'唐'), + (0x2F843, 'M', u'啓'), + (0x2F844, 'M', u'啣'), + (0x2F845, 'M', u'善'), + (0x2F847, 'M', u'喙'), + (0x2F848, 'M', u'喫'), + (0x2F849, 'M', u'喳'), + (0x2F84A, 'M', u'嗂'), + (0x2F84B, 'M', u'圖'), + (0x2F84C, 'M', u'嘆'), + (0x2F84D, 'M', u'圗'), + ] + +def _seg_68(): + return [ + (0x2F84E, 'M', u'噑'), + (0x2F84F, 'M', u'噴'), + (0x2F850, 'M', u'切'), + (0x2F851, 'M', u'壮'), + (0x2F852, 'M', u'城'), + (0x2F853, 'M', u'埴'), + (0x2F854, 'M', u'堍'), + (0x2F855, 'M', u'型'), + (0x2F856, 'M', u'堲'), + (0x2F857, 'M', u'報'), + (0x2F858, 'M', u'墬'), + (0x2F859, 'M', u'𡓤'), + (0x2F85A, 'M', u'売'), + (0x2F85B, 'M', u'壷'), + (0x2F85C, 'M', u'夆'), + (0x2F85D, 'M', u'多'), + (0x2F85E, 'M', u'夢'), + (0x2F85F, 'M', u'奢'), + (0x2F860, 'M', u'𡚨'), + (0x2F861, 'M', u'𡛪'), + (0x2F862, 'M', u'姬'), + (0x2F863, 'M', u'娛'), + (0x2F864, 'M', u'娧'), + (0x2F865, 'M', u'姘'), + (0x2F866, 'M', u'婦'), + (0x2F867, 'M', u'㛮'), + (0x2F868, 'X'), + (0x2F869, 'M', u'嬈'), + (0x2F86A, 'M', u'嬾'), + (0x2F86C, 'M', u'𡧈'), + (0x2F86D, 'M', u'寃'), + (0x2F86E, 'M', u'寘'), + (0x2F86F, 'M', u'寧'), + (0x2F870, 'M', u'寳'), + (0x2F871, 'M', u'𡬘'), + (0x2F872, 'M', u'寿'), + (0x2F873, 'M', u'将'), + (0x2F874, 'X'), + (0x2F875, 'M', u'尢'), + (0x2F876, 'M', u'㞁'), + (0x2F877, 'M', u'屠'), + (0x2F878, 'M', u'屮'), + (0x2F879, 'M', u'峀'), + (0x2F87A, 'M', u'岍'), + (0x2F87B, 'M', u'𡷤'), + (0x2F87C, 'M', u'嵃'), + (0x2F87D, 'M', u'𡷦'), + (0x2F87E, 'M', u'嵮'), + (0x2F87F, 'M', u'嵫'), + (0x2F880, 'M', u'嵼'), + (0x2F881, 'M', u'巡'), + (0x2F882, 'M', u'巢'), + (0x2F883, 'M', u'㠯'), + (0x2F884, 'M', u'巽'), + (0x2F885, 'M', u'帨'), + (0x2F886, 'M', u'帽'), + (0x2F887, 'M', u'幩'), + (0x2F888, 'M', u'㡢'), + (0x2F889, 'M', u'𢆃'), + (0x2F88A, 'M', u'㡼'), + (0x2F88B, 'M', u'庰'), + (0x2F88C, 'M', u'庳'), + (0x2F88D, 'M', u'庶'), + (0x2F88E, 'M', u'廊'), + (0x2F88F, 'M', u'𪎒'), + (0x2F890, 'M', u'廾'), + (0x2F891, 'M', u'𢌱'), + (0x2F893, 'M', u'舁'), + (0x2F894, 'M', u'弢'), + (0x2F896, 'M', u'㣇'), + (0x2F897, 'M', u'𣊸'), + (0x2F898, 'M', u'𦇚'), + (0x2F899, 'M', u'形'), + (0x2F89A, 'M', u'彫'), + (0x2F89B, 'M', u'㣣'), + (0x2F89C, 'M', u'徚'), + (0x2F89D, 'M', u'忍'), + (0x2F89E, 'M', u'志'), + (0x2F89F, 'M', u'忹'), + (0x2F8A0, 'M', u'悁'), + (0x2F8A1, 'M', u'㤺'), + (0x2F8A2, 'M', u'㤜'), + (0x2F8A3, 'M', u'悔'), + (0x2F8A4, 'M', u'𢛔'), + (0x2F8A5, 'M', u'惇'), + (0x2F8A6, 'M', u'慈'), + (0x2F8A7, 'M', u'慌'), + (0x2F8A8, 'M', u'慎'), + (0x2F8A9, 'M', u'慌'), + (0x2F8AA, 'M', u'慺'), + (0x2F8AB, 'M', u'憎'), + (0x2F8AC, 'M', u'憲'), + (0x2F8AD, 'M', u'憤'), + (0x2F8AE, 'M', u'憯'), + (0x2F8AF, 'M', u'懞'), + (0x2F8B0, 'M', u'懲'), + (0x2F8B1, 'M', u'懶'), + (0x2F8B2, 'M', u'成'), + (0x2F8B3, 'M', u'戛'), + (0x2F8B4, 'M', u'扝'), + ] + +def _seg_69(): + return [ + (0x2F8B5, 'M', u'抱'), + (0x2F8B6, 'M', u'拔'), + (0x2F8B7, 'M', u'捐'), + (0x2F8B8, 'M', u'𢬌'), + (0x2F8B9, 'M', u'挽'), + (0x2F8BA, 'M', u'拼'), + (0x2F8BB, 'M', u'捨'), + (0x2F8BC, 'M', u'掃'), + (0x2F8BD, 'M', u'揤'), + (0x2F8BE, 'M', u'𢯱'), + (0x2F8BF, 'M', u'搢'), + (0x2F8C0, 'M', u'揅'), + (0x2F8C1, 'M', u'掩'), + (0x2F8C2, 'M', u'㨮'), + (0x2F8C3, 'M', u'摩'), + (0x2F8C4, 'M', u'摾'), + (0x2F8C5, 'M', u'撝'), + (0x2F8C6, 'M', u'摷'), + (0x2F8C7, 'M', u'㩬'), + (0x2F8C8, 'M', u'敏'), + (0x2F8C9, 'M', u'敬'), + (0x2F8CA, 'M', u'𣀊'), + (0x2F8CB, 'M', u'旣'), + (0x2F8CC, 'M', u'書'), + (0x2F8CD, 'M', u'晉'), + (0x2F8CE, 'M', u'㬙'), + (0x2F8CF, 'M', u'暑'), + (0x2F8D0, 'M', u'㬈'), + (0x2F8D1, 'M', u'㫤'), + (0x2F8D2, 'M', u'冒'), + (0x2F8D3, 'M', u'冕'), + (0x2F8D4, 'M', u'最'), + (0x2F8D5, 'M', u'暜'), + (0x2F8D6, 'M', u'肭'), + (0x2F8D7, 'M', u'䏙'), + (0x2F8D8, 'M', u'朗'), + (0x2F8D9, 'M', u'望'), + (0x2F8DA, 'M', u'朡'), + (0x2F8DB, 'M', u'杞'), + (0x2F8DC, 'M', u'杓'), + (0x2F8DD, 'M', u'𣏃'), + (0x2F8DE, 'M', u'㭉'), + (0x2F8DF, 'M', u'柺'), + (0x2F8E0, 'M', u'枅'), + (0x2F8E1, 'M', u'桒'), + (0x2F8E2, 'M', u'梅'), + (0x2F8E3, 'M', u'𣑭'), + (0x2F8E4, 'M', u'梎'), + (0x2F8E5, 'M', u'栟'), + (0x2F8E6, 'M', u'椔'), + (0x2F8E7, 'M', u'㮝'), + (0x2F8E8, 'M', u'楂'), + (0x2F8E9, 'M', u'榣'), + (0x2F8EA, 'M', u'槪'), + (0x2F8EB, 'M', u'檨'), + (0x2F8EC, 'M', u'𣚣'), + (0x2F8ED, 'M', u'櫛'), + (0x2F8EE, 'M', u'㰘'), + (0x2F8EF, 'M', u'次'), + (0x2F8F0, 'M', u'𣢧'), + (0x2F8F1, 'M', u'歔'), + (0x2F8F2, 'M', u'㱎'), + (0x2F8F3, 'M', u'歲'), + (0x2F8F4, 'M', u'殟'), + (0x2F8F5, 'M', u'殺'), + (0x2F8F6, 'M', u'殻'), + (0x2F8F7, 'M', u'𣪍'), + (0x2F8F8, 'M', u'𡴋'), + (0x2F8F9, 'M', u'𣫺'), + (0x2F8FA, 'M', u'汎'), + (0x2F8FB, 'M', u'𣲼'), + (0x2F8FC, 'M', u'沿'), + (0x2F8FD, 'M', u'泍'), + (0x2F8FE, 'M', u'汧'), + (0x2F8FF, 'M', u'洖'), + (0x2F900, 'M', u'派'), + (0x2F901, 'M', u'海'), + (0x2F902, 'M', u'流'), + (0x2F903, 'M', u'浩'), + (0x2F904, 'M', u'浸'), + (0x2F905, 'M', u'涅'), + (0x2F906, 'M', u'𣴞'), + (0x2F907, 'M', u'洴'), + (0x2F908, 'M', u'港'), + (0x2F909, 'M', u'湮'), + (0x2F90A, 'M', u'㴳'), + (0x2F90B, 'M', u'滋'), + (0x2F90C, 'M', u'滇'), + (0x2F90D, 'M', u'𣻑'), + (0x2F90E, 'M', u'淹'), + (0x2F90F, 'M', u'潮'), + (0x2F910, 'M', u'𣽞'), + (0x2F911, 'M', u'𣾎'), + (0x2F912, 'M', u'濆'), + (0x2F913, 'M', u'瀹'), + (0x2F914, 'M', u'瀞'), + (0x2F915, 'M', u'瀛'), + (0x2F916, 'M', u'㶖'), + (0x2F917, 'M', u'灊'), + (0x2F918, 'M', u'災'), + ] + +def _seg_70(): + return [ + (0x2F919, 'M', u'灷'), + (0x2F91A, 'M', u'炭'), + (0x2F91B, 'M', u'𠔥'), + (0x2F91C, 'M', u'煅'), + (0x2F91D, 'M', u'𤉣'), + (0x2F91E, 'M', u'熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', u'爨'), + (0x2F921, 'M', u'爵'), + (0x2F922, 'M', u'牐'), + (0x2F923, 'M', u'𤘈'), + (0x2F924, 'M', u'犀'), + (0x2F925, 'M', u'犕'), + (0x2F926, 'M', u'𤜵'), + (0x2F927, 'M', u'𤠔'), + (0x2F928, 'M', u'獺'), + (0x2F929, 'M', u'王'), + (0x2F92A, 'M', u'㺬'), + (0x2F92B, 'M', u'玥'), + (0x2F92C, 'M', u'㺸'), + (0x2F92E, 'M', u'瑇'), + (0x2F92F, 'M', u'瑜'), + (0x2F930, 'M', u'瑱'), + (0x2F931, 'M', u'璅'), + (0x2F932, 'M', u'瓊'), + (0x2F933, 'M', u'㼛'), + (0x2F934, 'M', u'甤'), + (0x2F935, 'M', u'𤰶'), + (0x2F936, 'M', u'甾'), + (0x2F937, 'M', u'𤲒'), + (0x2F938, 'M', u'異'), + (0x2F939, 'M', u'𢆟'), + (0x2F93A, 'M', u'瘐'), + (0x2F93B, 'M', u'𤾡'), + (0x2F93C, 'M', u'𤾸'), + (0x2F93D, 'M', u'𥁄'), + (0x2F93E, 'M', u'㿼'), + (0x2F93F, 'M', u'䀈'), + (0x2F940, 'M', u'直'), + (0x2F941, 'M', u'𥃳'), + (0x2F942, 'M', u'𥃲'), + (0x2F943, 'M', u'𥄙'), + (0x2F944, 'M', u'𥄳'), + (0x2F945, 'M', u'眞'), + (0x2F946, 'M', u'真'), + (0x2F948, 'M', u'睊'), + (0x2F949, 'M', u'䀹'), + (0x2F94A, 'M', u'瞋'), + (0x2F94B, 'M', u'䁆'), + (0x2F94C, 'M', u'䂖'), + (0x2F94D, 'M', u'𥐝'), + (0x2F94E, 'M', u'硎'), + (0x2F94F, 'M', u'碌'), + (0x2F950, 'M', u'磌'), + (0x2F951, 'M', u'䃣'), + (0x2F952, 'M', u'𥘦'), + (0x2F953, 'M', u'祖'), + (0x2F954, 'M', u'𥚚'), + (0x2F955, 'M', u'𥛅'), + (0x2F956, 'M', u'福'), + (0x2F957, 'M', u'秫'), + (0x2F958, 'M', u'䄯'), + (0x2F959, 'M', u'穀'), + (0x2F95A, 'M', u'穊'), + (0x2F95B, 'M', u'穏'), + (0x2F95C, 'M', u'𥥼'), + (0x2F95D, 'M', u'𥪧'), + (0x2F95F, 'X'), + (0x2F960, 'M', u'䈂'), + (0x2F961, 'M', u'𥮫'), + (0x2F962, 'M', u'篆'), + (0x2F963, 'M', u'築'), + (0x2F964, 'M', u'䈧'), + (0x2F965, 'M', u'𥲀'), + (0x2F966, 'M', u'糒'), + (0x2F967, 'M', u'䊠'), + (0x2F968, 'M', u'糨'), + (0x2F969, 'M', u'糣'), + (0x2F96A, 'M', u'紀'), + (0x2F96B, 'M', u'𥾆'), + (0x2F96C, 'M', u'絣'), + (0x2F96D, 'M', u'䌁'), + (0x2F96E, 'M', u'緇'), + (0x2F96F, 'M', u'縂'), + (0x2F970, 'M', u'繅'), + (0x2F971, 'M', u'䌴'), + (0x2F972, 'M', u'𦈨'), + (0x2F973, 'M', u'𦉇'), + (0x2F974, 'M', u'䍙'), + (0x2F975, 'M', u'𦋙'), + (0x2F976, 'M', u'罺'), + (0x2F977, 'M', u'𦌾'), + (0x2F978, 'M', u'羕'), + (0x2F979, 'M', u'翺'), + (0x2F97A, 'M', u'者'), + (0x2F97B, 'M', u'𦓚'), + (0x2F97C, 'M', u'𦔣'), + (0x2F97D, 'M', u'聠'), + (0x2F97E, 'M', u'𦖨'), + (0x2F97F, 'M', u'聰'), + ] + +def _seg_71(): + return [ + (0x2F980, 'M', u'𣍟'), + (0x2F981, 'M', u'䏕'), + (0x2F982, 'M', u'育'), + (0x2F983, 'M', u'脃'), + (0x2F984, 'M', u'䐋'), + (0x2F985, 'M', u'脾'), + (0x2F986, 'M', u'媵'), + (0x2F987, 'M', u'𦞧'), + (0x2F988, 'M', u'𦞵'), + (0x2F989, 'M', u'𣎓'), + (0x2F98A, 'M', u'𣎜'), + (0x2F98B, 'M', u'舁'), + (0x2F98C, 'M', u'舄'), + (0x2F98D, 'M', u'辞'), + (0x2F98E, 'M', u'䑫'), + (0x2F98F, 'M', u'芑'), + (0x2F990, 'M', u'芋'), + (0x2F991, 'M', u'芝'), + (0x2F992, 'M', u'劳'), + (0x2F993, 'M', u'花'), + (0x2F994, 'M', u'芳'), + (0x2F995, 'M', u'芽'), + (0x2F996, 'M', u'苦'), + (0x2F997, 'M', u'𦬼'), + (0x2F998, 'M', u'若'), + (0x2F999, 'M', u'茝'), + (0x2F99A, 'M', u'荣'), + (0x2F99B, 'M', u'莭'), + (0x2F99C, 'M', u'茣'), + (0x2F99D, 'M', u'莽'), + (0x2F99E, 'M', u'菧'), + (0x2F99F, 'M', u'著'), + (0x2F9A0, 'M', u'荓'), + (0x2F9A1, 'M', u'菊'), + (0x2F9A2, 'M', u'菌'), + (0x2F9A3, 'M', u'菜'), + (0x2F9A4, 'M', u'𦰶'), + (0x2F9A5, 'M', u'𦵫'), + (0x2F9A6, 'M', u'𦳕'), + (0x2F9A7, 'M', u'䔫'), + (0x2F9A8, 'M', u'蓱'), + (0x2F9A9, 'M', u'蓳'), + (0x2F9AA, 'M', u'蔖'), + (0x2F9AB, 'M', u'𧏊'), + (0x2F9AC, 'M', u'蕤'), + (0x2F9AD, 'M', u'𦼬'), + (0x2F9AE, 'M', u'䕝'), + (0x2F9AF, 'M', u'䕡'), + (0x2F9B0, 'M', u'𦾱'), + (0x2F9B1, 'M', u'𧃒'), + (0x2F9B2, 'M', u'䕫'), + (0x2F9B3, 'M', u'虐'), + (0x2F9B4, 'M', u'虜'), + (0x2F9B5, 'M', u'虧'), + (0x2F9B6, 'M', u'虩'), + (0x2F9B7, 'M', u'蚩'), + (0x2F9B8, 'M', u'蚈'), + (0x2F9B9, 'M', u'蜎'), + (0x2F9BA, 'M', u'蛢'), + (0x2F9BB, 'M', u'蝹'), + (0x2F9BC, 'M', u'蜨'), + (0x2F9BD, 'M', u'蝫'), + (0x2F9BE, 'M', u'螆'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', u'蟡'), + (0x2F9C1, 'M', u'蠁'), + (0x2F9C2, 'M', u'䗹'), + (0x2F9C3, 'M', u'衠'), + (0x2F9C4, 'M', u'衣'), + (0x2F9C5, 'M', u'𧙧'), + (0x2F9C6, 'M', u'裗'), + (0x2F9C7, 'M', u'裞'), + (0x2F9C8, 'M', u'䘵'), + (0x2F9C9, 'M', u'裺'), + (0x2F9CA, 'M', u'㒻'), + (0x2F9CB, 'M', u'𧢮'), + (0x2F9CC, 'M', u'𧥦'), + (0x2F9CD, 'M', u'䚾'), + (0x2F9CE, 'M', u'䛇'), + (0x2F9CF, 'M', u'誠'), + (0x2F9D0, 'M', u'諭'), + (0x2F9D1, 'M', u'變'), + (0x2F9D2, 'M', u'豕'), + (0x2F9D3, 'M', u'𧲨'), + (0x2F9D4, 'M', u'貫'), + (0x2F9D5, 'M', u'賁'), + (0x2F9D6, 'M', u'贛'), + (0x2F9D7, 'M', u'起'), + (0x2F9D8, 'M', u'𧼯'), + (0x2F9D9, 'M', u'𠠄'), + (0x2F9DA, 'M', u'跋'), + (0x2F9DB, 'M', u'趼'), + (0x2F9DC, 'M', u'跰'), + (0x2F9DD, 'M', u'𠣞'), + (0x2F9DE, 'M', u'軔'), + (0x2F9DF, 'M', u'輸'), + (0x2F9E0, 'M', u'𨗒'), + (0x2F9E1, 'M', u'𨗭'), + (0x2F9E2, 'M', u'邔'), + (0x2F9E3, 'M', u'郱'), + ] + +def _seg_72(): + return [ + (0x2F9E4, 'M', u'鄑'), + (0x2F9E5, 'M', u'𨜮'), + (0x2F9E6, 'M', u'鄛'), + (0x2F9E7, 'M', u'鈸'), + (0x2F9E8, 'M', u'鋗'), + (0x2F9E9, 'M', u'鋘'), + (0x2F9EA, 'M', u'鉼'), + (0x2F9EB, 'M', u'鏹'), + (0x2F9EC, 'M', u'鐕'), + (0x2F9ED, 'M', u'𨯺'), + (0x2F9EE, 'M', u'開'), + (0x2F9EF, 'M', u'䦕'), + (0x2F9F0, 'M', u'閷'), + (0x2F9F1, 'M', u'𨵷'), + (0x2F9F2, 'M', u'䧦'), + (0x2F9F3, 'M', u'雃'), + (0x2F9F4, 'M', u'嶲'), + (0x2F9F5, 'M', u'霣'), + (0x2F9F6, 'M', u'𩅅'), + (0x2F9F7, 'M', u'𩈚'), + (0x2F9F8, 'M', u'䩮'), + (0x2F9F9, 'M', u'䩶'), + (0x2F9FA, 'M', u'韠'), + (0x2F9FB, 'M', u'𩐊'), + (0x2F9FC, 'M', u'䪲'), + (0x2F9FD, 'M', u'𩒖'), + (0x2F9FE, 'M', u'頋'), + (0x2FA00, 'M', u'頩'), + (0x2FA01, 'M', u'𩖶'), + (0x2FA02, 'M', u'飢'), + (0x2FA03, 'M', u'䬳'), + (0x2FA04, 'M', u'餩'), + (0x2FA05, 'M', u'馧'), + (0x2FA06, 'M', u'駂'), + (0x2FA07, 'M', u'駾'), + (0x2FA08, 'M', u'䯎'), + (0x2FA09, 'M', u'𩬰'), + (0x2FA0A, 'M', u'鬒'), + (0x2FA0B, 'M', u'鱀'), + (0x2FA0C, 'M', u'鳽'), + (0x2FA0D, 'M', u'䳎'), + (0x2FA0E, 'M', u'䳭'), + (0x2FA0F, 'M', u'鵧'), + (0x2FA10, 'M', u'𪃎'), + (0x2FA11, 'M', u'䳸'), + (0x2FA12, 'M', u'𪄅'), + (0x2FA13, 'M', u'𪈎'), + (0x2FA14, 'M', u'𪊑'), + (0x2FA15, 'M', u'麻'), + (0x2FA16, 'M', u'䵖'), + (0x2FA17, 'M', u'黹'), + (0x2FA18, 'M', u'黾'), + (0x2FA19, 'M', u'鼅'), + (0x2FA1A, 'M', u'鼏'), + (0x2FA1B, 'M', u'鼖'), + (0x2FA1C, 'M', u'鼻'), + (0x2FA1D, 'M', u'𪘀'), + (0x2FA1E, 'X'), + (0xE0100, 'I'), + (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() +) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/ipaddress.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/ipaddress.py new file mode 100644 index 0000000..8cfdd58 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/ipaddress.py @@ -0,0 +1,2419 @@ +# Copyright 2007 Google Inc. +# Licensed to PSF under a Contributor Agreement. + +"""A fast, lightweight IPv4/IPv6 manipulation library in Python. + +This library is used to create/poke/manipulate IPv4 and IPv6 addresses +and networks. + +""" + +from __future__ import unicode_literals + + +import itertools +import struct + +__version__ = '1.0.19' + +# Compatibility functions +_compat_int_types = (int,) +try: + _compat_int_types = (int, long) +except NameError: + pass +try: + _compat_str = unicode +except NameError: + _compat_str = str + assert bytes != str +if b'\0'[0] == 0: # Python 3 semantics + def _compat_bytes_to_byte_vals(byt): + return byt +else: + def _compat_bytes_to_byte_vals(byt): + return [struct.unpack(b'!B', b)[0] for b in byt] +try: + _compat_int_from_byte_vals = int.from_bytes +except AttributeError: + def _compat_int_from_byte_vals(bytvals, endianess): + assert endianess == 'big' + res = 0 + for bv in bytvals: + assert isinstance(bv, _compat_int_types) + res = (res << 8) + bv + return res + + +def _compat_to_bytes(intval, length, endianess): + assert isinstance(intval, _compat_int_types) + assert endianess == 'big' + if length == 4: + if intval < 0 or intval >= 2 ** 32: + raise struct.error("integer out of range for 'I' format code") + return struct.pack(b'!I', intval) + elif length == 16: + if intval < 0 or intval >= 2 ** 128: + raise struct.error("integer out of range for 'QQ' format code") + return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) + else: + raise NotImplementedError() + + +if hasattr(int, 'bit_length'): + # Not int.bit_length , since that won't work in 2.7 where long exists + def _compat_bit_length(i): + return i.bit_length() +else: + def _compat_bit_length(i): + for res in itertools.count(): + if i >> res == 0: + return res + + +def _compat_range(start, end, step=1): + assert step > 0 + i = start + while i < end: + yield i + i += step + + +class _TotalOrderingMixin(object): + __slots__ = () + + # Helper that derives the other comparison operations from + # __lt__ and __eq__ + # We avoid functools.total_ordering because it doesn't handle + # NotImplemented correctly yet (http://bugs.python.org/issue10042) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not equal + + def __lt__(self, other): + raise NotImplementedError + + def __le__(self, other): + less = self.__lt__(other) + if less is NotImplemented or not less: + return self.__eq__(other) + return less + + def __gt__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not (less or equal) + + def __ge__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + return not less + + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def ip_address(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the *address* passed isn't either a v4 or a v6 + address + + """ + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def ip_network(address, strict=True): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP network. Either IPv4 or + IPv6 networks may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if the network has host bits set. + + """ + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 network. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def ip_interface(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Interface or IPv6Interface object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + Notes: + The IPv?Interface classes describe an Address on a particular + Network, so they're basically a combination of both the Address + and Network classes. + + """ + try: + return IPv4Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % + address) + + +def v4_int_to_packed(address): + """Represent an address as 4 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The integer address packed as 4 bytes in network (big-endian) order. + + Raises: + ValueError: If the integer is negative or too large to be an + IPv4 IP address. + + """ + try: + return _compat_to_bytes(address, 4, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv4") + + +def v6_int_to_packed(address): + """Represent an address as 16 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv6 IP address. + + Returns: + The integer address packed as 16 bytes in network (big-endian) order. + + """ + try: + return _compat_to_bytes(address, 16, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv6") + + +def _split_optional_netmask(address): + """Helper to split the netmask and raise AddressValueError if needed""" + addr = _compat_str(address).split('/') + if len(addr) > 2: + raise AddressValueError("Only one '/' permitted in %r" % address) + return addr + + +def _find_address_range(addresses): + """Find a sequence of sorted deduplicated IPv#Address. + + Args: + addresses: a list of IPv#Address objects. + + Yields: + A tuple containing the first and last IP addresses in the sequence. + + """ + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last + + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + return min(bits, _compat_bit_length(~number & (number - 1))) + + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> list(summarize_address_range(IPv4Address('192.0.2.0'), + ... IPv4Address('192.0.2.130'))) + ... #doctest: +NORMALIZE_WHITESPACE + [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), + IPv4Network('192.0.2.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + An iterator of the summarized IPv(4|6) network objects. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version of the first address is not 4 or 6. + + """ + if (not (isinstance(first, _BaseAddress) and + isinstance(last, _BaseAddress))): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + first, last)) + if first > last: + raise ValueError('last IP address must be greater than first') + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = min(_count_righthand_zero_bits(first_int, ip_bits), + _compat_bit_length(last_int - first_int + 1) - 1) + net = ip((first_int, ip_bits - nbits)) + yield net + first_int += 1 << nbits + if first_int - 1 == ip._ALL_ONES: + break + + +def _collapse_addresses_internal(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('192.0.2.0/26') + ip2 = IPv4Network('192.0.2.64/26') + ip3 = IPv4Network('192.0.2.128/26') + ip4 = IPv4Network('192.0.2.192/26') + + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> + [IPv4Network('192.0.2.0/24')] + + This shouldn't be called directly; it is called via + collapse_addresses([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, + # last.network_address <= net.network_address is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net + + +def collapse_addresses(addresses): + """Collapse a list of IP objects. + + Example: + collapse_addresses([IPv4Network('192.0.2.0/25'), + IPv4Network('192.0.2.128/25')]) -> + [IPv4Network('192.0.2.0/24')] + + Args: + addresses: An iterator of IPv4Network or IPv6Network objects. + + Returns: + An iterator of the collapsed IPv(4|6)Network objects. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseAddress): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + try: + ips.append(ip.ip) + except AttributeError: + ips.append(ip.network_address) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, nets[-1])) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) + + return _collapse_addresses_internal(addrs + nets) + + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddress sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNetwork): + return obj._get_networks_key() + elif isinstance(obj, _BaseAddress): + return obj._get_address_key() + return NotImplemented + + +class _IPAddressBase(_TotalOrderingMixin): + + """The mother class.""" + + __slots__ = () + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return _compat_str(self) + + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + + @property + def version(self): + msg = '%200s has no version specified' % (type(self),) + raise NotImplementedError(msg) + + def _check_int_address(self, address): + if address < 0: + msg = "%d (< 0) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._version)) + if address > self._ALL_ONES: + msg = "%d (>= 2**%d) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._max_prefixlen, + self._version)) + + def _check_packed_address(self, address, expected_len): + address_len = len(address) + if address_len != expected_len: + msg = ( + '%r (len %d != %d) is not permitted as an IPv%d address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?') + raise AddressValueError(msg % (address, address_len, + expected_len, self._version)) + + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) + + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. + + Args: + ip_int: An integer, the netmask in expanded bitwise format + + Returns: + An integer, the prefix length. + + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = _compat_to_bytes(ip_int, byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask + """ + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen + + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length + + Args: + ip_str: The netmask/hostmask to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (_compat_str(self),) + + +class _BaseAddress(_IPAddressBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + """ + + __slots__ = () + + def __int__(self): + return self._ip + + def __eq__(self, other): + try: + return (self._ip == other._ip and + self._version == other._version) + except AttributeError: + return NotImplemented + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseAddress): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self._ip != other._ip: + return self._ip < other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) + other) + + def __sub__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) - other) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return _compat_str(self._string_from_ip_int(self._ip)) + + def __hash__(self): + return hash(hex(int(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + def __reduce__(self): + return self.__class__, (self._ip,) + + +class _BaseNetwork(_IPAddressBase): + + """A generic IP network object. + + This IP class contains the version independent methods which are + used by networks. + + """ + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return '%s/%d' % (self.network_address, self.prefixlen) + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast): + yield self._address_class(x) + + def __iter__(self): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network, broadcast + 1): + yield self._address_class(x) + + def __getitem__(self, n): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + if n >= 0: + if network + n > broadcast: + raise IndexError('address out of range') + return self._address_class(network + n) + else: + n += 1 + if broadcast + n < network: + raise IndexError('address out of range') + return self._address_class(broadcast + n) + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseNetwork): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self.network_address != other.network_address: + return self.network_address < other.network_address + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __eq__(self, other): + try: + return (self._version == other._version and + self.network_address == other.network_address and + int(self.netmask) == int(other.netmask)) + except AttributeError: + return NotImplemented + + def __hash__(self): + return hash(int(self.network_address) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNetwork): + return False + # dealing with another address + else: + # address + return (int(self.network_address) <= int(other._ip) <= + int(self.broadcast_address)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network_address in other or ( + self.broadcast_address in other or ( + other.network_address in self or ( + other.broadcast_address in self))) + + @property + def broadcast_address(self): + x = self._cache.get('broadcast_address') + if x is None: + x = self._address_class(int(self.network_address) | + int(self.hostmask)) + self._cache['broadcast_address'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = self._address_class(int(self.netmask) ^ self._ALL_ONES) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (self.network_address, self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self.network_address, self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self.network_address, self.hostmask) + + @property + def num_addresses(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast_address) - int(self.network_address) + 1 + + @property + def _address_class(self): + # Returning bare address objects (rather than interfaces) allows for + # more consistent behaviour across the network address, broadcast + # address and individual host addresses. + msg = '%200s has no associated address class' % (type(self),) + raise NotImplementedError(msg) + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = ip_network('192.0.2.0/28') + addr2 = ip_network('192.0.2.1/32') + list(addr1.address_exclude(addr2)) = + [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), + IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] + + or IPv6: + + addr1 = ip_network('2001:db8::1/32') + addr2 = ip_network('2001:db8::1/128') + list(addr1.address_exclude(addr2)) = + [ip_network('2001:db8::1/128'), + ip_network('2001:db8::2/127'), + ip_network('2001:db8::4/126'), + ip_network('2001:db8::8/125'), + ... + ip_network('2001:db8:8000::/33')] + + Args: + other: An IPv4Network or IPv6Network object of the same type. + + Returns: + An iterator of the IPv(4|6)Network objects which is self + minus other. + + Raises: + TypeError: If self and other are of differing address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + self, other)) + + if not isinstance(other, _BaseNetwork): + raise TypeError("%s is not a network object" % other) + + if not other.subnet_of(self): + raise ValueError('%s not contained in %s' % (other, self)) + if other == self: + return + + # Make sure we're comparing the network of other. + other = other.__class__('%s/%s' % (other.network_address, + other.prefixlen)) + + s1, s2 = self.subnets() + while s1 != other and s2 != other: + if other.subnet_of(s1): + yield s2 + s1, s2 = s1.subnets() + elif other.subnet_of(s2): + yield s1 + s1, s2 = s2.subnets() + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + if s1 == other: + yield s2 + elif s2 == other: + yield s1 + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') + IPv6Network('2001:db8::1000/124') < + IPv6Network('2001:db8::2000/124') + 0 if self == other + eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') + IPv6Network('2001:db8::1000/124') == + IPv6Network('2001:db8::1000/124') + 1 if self > other + eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') + IPv6Network('2001:db8::2000/124') > + IPv6Network('2001:db8::1000/124') + + Raises: + TypeError if the IP versions are different. + + """ + # does this need to raise a ValueError? + if self._version != other._version: + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + # self._version == other._version below here: + if self.network_address < other.network_address: + return -1 + if self.network_address > other.network_address: + return 1 + # self.network_address == other.network_address below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network_address, self.netmask) + + def subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), yield an iterator with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if new_prefixlen > self._max_prefixlen: + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, self)) + + start = int(self.network_address) + end = int(self.broadcast_address) + 1 + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in _compat_range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) + yield current + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have + a negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen)) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return (self.network_address.is_multicast and + self.broadcast_address.is_multicast) + + @staticmethod + def _is_subnet_of(a, b): + try: + # Always false if one is v4 and the other is v6. + if a._version != b._version: + raise TypeError("%s and %s are not of the same version" (a, b)) + return (b.network_address <= a.network_address and + b.broadcast_address >= a.broadcast_address) + except AttributeError: + raise TypeError("Unable to test subnet containment " + "between %s and %s" % (a, b)) + + def subnet_of(self, other): + """Return True if this network is a subnet of other.""" + return self._is_subnet_of(self, other) + + def supernet_of(self, other): + """Return True if this network is a supernet of other.""" + return self._is_subnet_of(other, self) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self.network_address.is_reserved and + self.broadcast_address.is_reserved) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return (self.network_address.is_link_local and + self.broadcast_address.is_link_local) + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return (self.network_address.is_private and + self.broadcast_address.is_private) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return (self.network_address.is_unspecified and + self.broadcast_address.is_unspecified) + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return (self.network_address.is_loopback and + self.broadcast_address.is_loopback) + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 4 + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2 ** IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + def _explode_shorthand_ip_string(self): + return _compat_str(self) + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError("Expected 4 octets in %r" % ip_str) + + try: + return _compat_int_from_byte_vals( + map(cls._parse_octet, octets), 'big') + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_octet(cls, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + if not octet_str: + raise ValueError("Empty octet not permitted") + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._DECIMAL_DIGITS.issuperset(octet_str): + msg = "Only decimal digits permitted in %r" + raise ValueError(msg % octet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(octet_str) > 3: + msg = "At most 3 characters permitted in %r" + raise ValueError(msg % octet_str) + # Convert to integer (we know digits are legal) + octet_int = int(octet_str, 10) + # Any octets that look like they *might* be written in octal, + # and which don't look exactly the same in both octal and + # decimal are rejected as ambiguous + if octet_int > 7 and octet_str[0] == '0': + msg = "Ambiguous (octal/decimal) value in %r not permitted" + raise ValueError(msg % octet_str) + if octet_int > 255: + raise ValueError("Octet %d (> 255) not permitted" % octet_int) + return octet_int + + @classmethod + def _string_from_ip_int(cls, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] + if isinstance(b, bytes) + else b) + for b in _compat_to_bytes(ip_int, 4, 'big')) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [x for x in map(int, bits) if x in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = _compat_str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv4Address(_BaseV4, _BaseAddress): + + """Represent and manipulate single IPv4 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv4Address('192.0.2.1') == IPv4Address(3221225985). + or, more generally + IPv4Address(int(IPv4Address('192.0.2.1'))) == + IPv4Address('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 4) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in self._constants._reserved_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + return ( + self not in self._constants._public_network and + not self.is_private) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self == self._constants._unspecified_address + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in self._constants._loopback_network + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in self._constants._linklocal_network + + +class IPv4Interface(IPv4Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv4Address.__init__(self, address) + self.network = IPv4Network(self._ip) + self._prefixlen = self._max_prefixlen + return + + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv4Address.__init__(self, addr[0]) + + self.network = IPv4Network(address, strict=False) + self._prefixlen = self.network._prefixlen + + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv4Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv4Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv4Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + +class IPv4Network(_BaseV4, _BaseNetwork): + + """This class represents and manipulates 32-bit IPv4 network + addresses.. + + Attributes: [examples for IPv4Network('192.0.2.0/27')] + .network_address: IPv4Address('192.0.2.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast_address: IPv4Address('192.0.2.32') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + # Class to use when creating address objects + _address_class = IPv4Address + + def __init__(self, address, strict=True): + + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.0.2.0/24' + '192.0.2.0/255.255.255.0' + '192.0.0.2/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.0.2.1' + '192.0.2.1/255.255.255.255' + '192.0.2.1/32' + are also functionally equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.0.2.1') == IPv4Network(3221225985) + or, more generally + IPv4Interface(int(IPv4Interface('192.0.2.1'))) == + IPv4Interface('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict is True and a network address is not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Constructing from a packed address or integer + if isinstance(address, (_compat_int_types, bytes)): + self.network_address = IPv4Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + # fixme: address/network test here. + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv4Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv4Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry. + + """ + return (not (self.network_address in IPv4Network('100.64.0.0/10') and + self.broadcast_address in IPv4Network('100.64.0.0/10')) and + not self.is_private) + + +class _IPv4Constants(object): + + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _public_network = IPv4Network('100.64.0.0/10') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 6 + _ALL_ONES = (2 ** IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + An int, the IPv6 address + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + _min_parts = 3 + if len(parts) < _min_parts: + msg = "At least %d parts expected in %r" % (_min_parts, ip_str) + raise AddressValueError(msg) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + try: + ipv4_int = IPv4Address(parts.pop())._ip + except AddressValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + # The extra colon comes from using the "::" notation for a single + # leading or trailing zero part. + _max_parts = cls._HEXTET_COUNT + 1 + if len(parts) > _max_parts: + msg = "At most %d colons permitted in %r" % ( + _max_parts - 1, ip_str) + raise AddressValueError(msg) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + skip_index = None + for i in _compat_range(1, len(parts) - 1): + if not parts[i]: + if skip_index is not None: + # Can't have more than one '::' + msg = "At most one '::' permitted in %r" % ip_str + raise AddressValueError(msg) + skip_index = i + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + msg = "Expected at most %d other parts with '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) + else: + # Otherwise, allocate the entire address to parts_hi. The + # endpoints could still be empty, but _parse_hextet() will check + # for that. + if len(parts) != cls._HEXTET_COUNT: + msg = "Exactly %d parts expected without '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) + if not parts[0]: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0 + for i in range(parts_hi): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in range(-parts_lo, 0): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + return ip_int + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_hextet(cls, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from + [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._HEX_DIGITS.issuperset(hextet_str): + raise ValueError("Only hex digits permitted in %r" % hextet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(hextet_str) > 4: + msg = "At most 4 characters permitted in %r" + raise ValueError(msg % hextet_str) + # Length check means we can skip checking the integer value + return int(hextet_str, 16) + + @classmethod + def _compress_hextets(cls, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index, hextet in enumerate(hextets): + if hextet == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + @classmethod + def _string_from_ip_int(cls, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if ip_int is None: + ip_int = int(cls._ip) + + if ip_int > cls._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] + + hextets = cls._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if isinstance(self, IPv6Network): + ip_str = _compat_str(self.network_address) + elif isinstance(self, IPv6Interface): + ip_str = _compat_str(self.ip) + else: + ip_str = _compat_str(self) + + ip_int = self._ip_int_from_string(ip_str) + hex_str = '%032x' % ip_int + parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] + if isinstance(self, (_BaseNetwork, IPv6Interface)): + return '%s/%d' % (':'.join(parts), self._prefixlen) + return ':'.join(parts) + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv6Address(_BaseV6, _BaseAddress): + + """Represent and manipulate single IPv6 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:db8::') == + IPv6Address(42540766411282592856903984951653826560) + or, more generally + IPv6Address(int(IPv6Address('2001:db8::'))) == + IPv6Address('2001:db8::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 16) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return any(self in x for x in self._constants._reserved_networks) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in self._constants._linklocal_network + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in self._constants._sitelocal_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv6-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, true if the address is not reserved per + iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Interface(IPv6Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv6Address.__init__(self, address) + self.network = IPv6Network(self._ip) + self._prefixlen = self._max_prefixlen + return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv6Address.__init__(self, addr[0]) + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self._prefixlen = self.network._prefixlen + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv6Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv6Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv6Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + @property + def is_unspecified(self): + return self._ip == 0 and self.network.is_unspecified + + @property + def is_loopback(self): + return self._ip == 1 and self.network.is_loopback + + +class IPv6Network(_BaseV6, _BaseNetwork): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:db8::1000/124')] + .network_address: IPv6Address('2001:db8::1000') + .hostmask: IPv6Address('::f') + .broadcast_address: IPv6Address('2001:db8::100f') + .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') + .prefixlen: 124 + + """ + + # Class to use when creating address objects + _address_class = IPv6Address + + def __init__(self, address, strict=True): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the + IP and prefix/netmask. + '2001:db8::/128' + '2001:db8:0000:0000:0000:0000:0000:0000/128' + '2001:db8::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:db8::') == + IPv6Network(42540766411282592856903984951653826560) + or, more generally + IPv6Network(int(IPv6Network('2001:db8::'))) == + IPv6Network('2001:db8::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 2001:db8::1000/124 and not an + IP address on a network, eg, 2001:db8::1/124. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, _compat_int_types)): + self.network_address = IPv6Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + + self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv6Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv6Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast + 1): + yield self._address_class(x) + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return (self.network_address.is_site_local and + self.broadcast_address.is_site_local) + + +class _IPv6Constants(object): + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py new file mode 100644 index 0000000..a6f44a5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- + +""" +lockfile.py - Platform-independent advisory file locks. + +Requires Python 2.5 unless you apply 2.4.diff +Locking is done on a per-thread basis instead of a per-process basis. + +Usage: + +>>> lock = LockFile('somefile') +>>> try: +... lock.acquire() +... except AlreadyLocked: +... print 'somefile', 'is locked already.' +... except LockFailed: +... print 'somefile', 'can\\'t be locked.' +... else: +... print 'got lock' +got lock +>>> print lock.is_locked() +True +>>> lock.release() + +>>> lock = LockFile('somefile') +>>> print lock.is_locked() +False +>>> with lock: +... print lock.is_locked() +True +>>> print lock.is_locked() +False + +>>> lock = LockFile('somefile') +>>> # It is okay to lock twice from the same thread... +>>> with lock: +... lock.acquire() +... +>>> # Though no counter is kept, so you can't unlock multiple times... +>>> print lock.is_locked() +False + +Exceptions: + + Error - base class for other exceptions + LockError - base class for all locking exceptions + AlreadyLocked - Another thread or process already holds the lock + LockFailed - Lock failed for some other reason + UnlockError - base class for all unlocking exceptions + AlreadyUnlocked - File was not locked. + NotMyLock - File was locked but not by the current thread/process +""" + +from __future__ import absolute_import + +import functools +import os +import socket +import threading +import warnings + +# Work with PEP8 and non-PEP8 versions of threading module. +if not hasattr(threading, "current_thread"): + threading.current_thread = threading.currentThread +if not hasattr(threading.Thread, "get_name"): + threading.Thread.get_name = threading.Thread.getName + +__all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked', + 'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock', + 'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock', + 'LockBase', 'locked'] + + +class Error(Exception): + """ + Base class for other exceptions. + + >>> try: + ... raise Error + ... except Exception: + ... pass + """ + pass + + +class LockError(Error): + """ + Base class for error arising from attempts to acquire the lock. + + >>> try: + ... raise LockError + ... except Error: + ... pass + """ + pass + + +class LockTimeout(LockError): + """Raised when lock creation fails within a user-defined period of time. + + >>> try: + ... raise LockTimeout + ... except LockError: + ... pass + """ + pass + + +class AlreadyLocked(LockError): + """Some other thread/process is locking the file. + + >>> try: + ... raise AlreadyLocked + ... except LockError: + ... pass + """ + pass + + +class LockFailed(LockError): + """Lock file creation failed for some other reason. + + >>> try: + ... raise LockFailed + ... except LockError: + ... pass + """ + pass + + +class UnlockError(Error): + """ + Base class for errors arising from attempts to release the lock. + + >>> try: + ... raise UnlockError + ... except Error: + ... pass + """ + pass + + +class NotLocked(UnlockError): + """Raised when an attempt is made to unlock an unlocked file. + + >>> try: + ... raise NotLocked + ... except UnlockError: + ... pass + """ + pass + + +class NotMyLock(UnlockError): + """Raised when an attempt is made to unlock a file someone else locked. + + >>> try: + ... raise NotMyLock + ... except UnlockError: + ... pass + """ + pass + + +class _SharedBase(object): + def __init__(self, path): + self.path = path + + def acquire(self, timeout=None): + """ + Acquire the lock. + + * If timeout is omitted (or None), wait forever trying to lock the + file. + + * If timeout > 0, try to acquire the lock for that many seconds. If + the lock period expires and the file is still locked, raise + LockTimeout. + + * If timeout <= 0, raise AlreadyLocked immediately if the file is + already locked. + """ + raise NotImplemented("implement in subclass") + + def release(self): + """ + Release the lock. + + If the file is not locked, raise NotLocked. + """ + raise NotImplemented("implement in subclass") + + def __enter__(self): + """ + Context manager support. + """ + self.acquire() + return self + + def __exit__(self, *_exc): + """ + Context manager support. + """ + self.release() + + def __repr__(self): + return "<%s: %r>" % (self.__class__.__name__, self.path) + + +class LockBase(_SharedBase): + """Base class for platform-specific lock classes.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = LockBase('somefile') + >>> lock = LockBase('somefile', threaded=False) + """ + super(LockBase, self).__init__(path) + self.lock_file = os.path.abspath(path) + ".lock" + self.hostname = socket.gethostname() + self.pid = os.getpid() + if threaded: + t = threading.current_thread() + # Thread objects in Python 2.4 and earlier do not have ident + # attrs. Worm around that. + ident = getattr(t, "ident", hash(t)) + self.tname = "-%x" % (ident & 0xffffffff) + else: + self.tname = "" + dirname = os.path.dirname(self.lock_file) + + # unique name is mostly about the current process, but must + # also contain the path -- otherwise, two adjacent locked + # files conflict (one file gets locked, creating lock-file and + # unique file, the other one gets locked, creating lock-file + # and overwriting the already existing lock-file, then one + # gets unlocked, deleting both lock-file and unique file, + # finally the last lock errors out upon releasing. + self.unique_name = os.path.join(dirname, + "%s%s.%s%s" % (self.hostname, + self.tname, + self.pid, + hash(self.path))) + self.timeout = timeout + + def is_locked(self): + """ + Tell whether or not the file is locked. + """ + raise NotImplemented("implement in subclass") + + def i_am_locking(self): + """ + Return True if this object is locking the file. + """ + raise NotImplemented("implement in subclass") + + def break_lock(self): + """ + Remove a lock. Useful if a locking thread failed to unlock. + """ + raise NotImplemented("implement in subclass") + + def __repr__(self): + return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, + self.path) + + +def _fl_helper(cls, mod, *args, **kwds): + warnings.warn("Import from %s module instead of lockfile package" % mod, + DeprecationWarning, stacklevel=2) + # This is a bit funky, but it's only for awhile. The way the unit tests + # are constructed this function winds up as an unbound method, so it + # actually takes three args, not two. We want to toss out self. + if not isinstance(args[0], str): + # We are testing, avoid the first arg + args = args[1:] + if len(args) == 1 and not kwds: + kwds["threaded"] = True + return cls(*args, **kwds) + + +def LinkFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import LinkLockFile from the + lockfile.linklockfile module. + """ + from . import linklockfile + return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", + *args, **kwds) + + +def MkdirFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import MkdirLockFile from the + lockfile.mkdirlockfile module. + """ + from . import mkdirlockfile + return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", + *args, **kwds) + + +def SQLiteFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import SQLiteLockFile from the + lockfile.mkdirlockfile module. + """ + from . import sqlitelockfile + return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", + *args, **kwds) + + +def locked(path, timeout=None): + """Decorator which enables locks for decorated function. + + Arguments: + - path: path for lockfile. + - timeout (optional): Timeout for acquiring lock. + + Usage: + @locked('/var/run/myname', timeout=0) + def myname(...): + ... + """ + def decor(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + lock = FileLock(path, timeout=timeout) + lock.acquire() + try: + return func(*args, **kwargs) + finally: + lock.release() + return wrapper + return decor + + +if hasattr(os, "link"): + from . import linklockfile as _llf + LockFile = _llf.LinkLockFile +else: + from . import mkdirlockfile as _mlf + LockFile = _mlf.MkdirLockFile + +FileLock = LockFile diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..43d4d02 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc new file mode 100644 index 0000000..ab22bde Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc new file mode 100644 index 0000000..cd7bbb4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py new file mode 100644 index 0000000..2ca9be0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import + +import time +import os + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class LinkLockFile(LockBase): + """Lock access to a file using atomic property of link(2). + + >>> lock = LinkLockFile('somefile') + >>> lock = LinkLockFile('somefile', threaded=False) + """ + + def acquire(self, timeout=None): + try: + open(self.unique_name, "wb").close() + except IOError: + raise LockFailed("failed to create %s" % self.unique_name) + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a hard link to it. + try: + os.link(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + nlinks = os.stat(self.unique_name).st_nlink + if nlinks == 2: + # The original link plus the one I created == 2. We're + # good to go. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + os.unlink(self.unique_name) + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name) and + os.stat(self.unique_name).st_nlink == 2) + + def break_lock(self): + if os.path.exists(self.lock_file): + os.unlink(self.lock_file) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py new file mode 100644 index 0000000..05a8c96 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import, division + +import time +import os +import sys +import errno + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class MkdirLockFile(LockBase): + """Lock file by creating a directory.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = MkdirLockFile('somefile') + >>> lock = MkdirLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + # Lock file itself is a directory. Place the unique file name into + # it. + self.unique_name = os.path.join(self.lock_file, + "%s.%s%s" % (self.hostname, + self.tname, + self.pid)) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + else: + wait = max(0, timeout / 10) + + while True: + try: + os.mkdir(self.lock_file) + except OSError: + err = sys.exc_info()[1] + if err.errno == errno.EEXIST: + # Already locked. + if os.path.exists(self.unique_name): + # Already locked by me. + return + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock. + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(wait) + else: + # Couldn't create the lock for some other reason + raise LockFailed("failed to create %s" % self.lock_file) + else: + open(self.unique_name, "wb").close() + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.rmdir(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name)) + + def break_lock(self): + if os.path.exists(self.lock_file): + for name in os.listdir(self.lock_file): + os.unlink(os.path.join(self.lock_file, name)) + os.rmdir(self.lock_file) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py new file mode 100644 index 0000000..069e85b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- + +# pidlockfile.py +# +# Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> +# +# This is free software: you may copy, modify, and/or distribute this work +# under the terms of the Python Software Foundation License, version 2 or +# later as published by the Python Software Foundation. +# No warranty expressed or implied. See the file LICENSE.PSF-2 for details. + +""" Lockfile behaviour implemented via Unix PID files. + """ + +from __future__ import absolute_import + +import errno +import os +import time + +from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, + LockTimeout) + + +class PIDLockFile(LockBase): + """ Lockfile implemented as a Unix PID file. + + The lock file is a normal file named by the attribute `path`. + A lock's PID file contains a single line of text, containing + the process ID (PID) of the process that acquired the lock. + + >>> lock = PIDLockFile('somefile') + >>> lock = PIDLockFile('somefile') + """ + + def __init__(self, path, threaded=False, timeout=None): + # pid lockfiles don't support threaded operation, so always force + # False as the threaded arg. + LockBase.__init__(self, path, False, timeout) + self.unique_name = self.path + + def read_pid(self): + """ Get the PID from the lock file. + """ + return read_pid_from_pidfile(self.path) + + def is_locked(self): + """ Test if the lock is currently held. + + The lock is held if the PID file for this lock exists. + + """ + return os.path.exists(self.path) + + def i_am_locking(self): + """ Test if the lock is held by the current process. + + Returns ``True`` if the current process ID matches the + number stored in the PID file. + """ + return self.is_locked() and os.getpid() == self.read_pid() + + def acquire(self, timeout=None): + """ Acquire the lock. + + Creates the PID file for this lock, or raises an error if + the lock could not be acquired. + """ + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + try: + write_pid_to_pidfile(self.path) + except OSError as exc: + if exc.errno == errno.EEXIST: + # The lock creation failed. Maybe sleep a bit. + if time.time() > end_time: + if timeout is not None and timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + raise LockFailed("failed to create %s" % self.path) + else: + return + + def release(self): + """ Release the lock. + + Removes the PID file to release the lock, or raises an + error if the current process does not hold the lock. + + """ + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + remove_existing_pidfile(self.path) + + def break_lock(self): + """ Break an existing lock. + + Removes the PID file if it already exists, otherwise does + nothing. + + """ + remove_existing_pidfile(self.path) + + +def read_pid_from_pidfile(pidfile_path): + """ Read the PID recorded in the named PID file. + + Read and return the numeric PID recorded as text in the named + PID file. If the PID file cannot be read, or if the content is + not a valid PID, return ``None``. + + """ + pid = None + try: + pidfile = open(pidfile_path, 'r') + except IOError: + pass + else: + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. + # + # Programs that read PID files should be somewhat flexible + # in what they accept; i.e., they should ignore extra + # whitespace, leading zeroes, absence of the trailing + # newline, or additional lines in the PID file. + + line = pidfile.readline().strip() + try: + pid = int(line) + except ValueError: + pass + pidfile.close() + + return pid + + +def write_pid_to_pidfile(pidfile_path): + """ Write the PID in the named PID file. + + Get the numeric process ID (“PID”) of the current process + and write it to the named file as a line of text. + + """ + open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) + open_mode = 0o644 + pidfile_fd = os.open(pidfile_path, open_flags, open_mode) + pidfile = os.fdopen(pidfile_fd, 'w') + + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. For + # example, if crond was process number 25, /var/run/crond.pid + # would contain three characters: two, five, and newline. + + pid = os.getpid() + pidfile.write("%s\n" % pid) + pidfile.close() + + +def remove_existing_pidfile(pidfile_path): + """ Remove the named PID file if it exists. + + Removing a PID file that doesn't already exist puts us in the + desired state, so we ignore the condition if the file does not + exist. + + """ + try: + os.remove(pidfile_path) + except OSError as exc: + if exc.errno == errno.ENOENT: + pass + else: + raise diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py new file mode 100644 index 0000000..f997e24 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py @@ -0,0 +1,156 @@ +from __future__ import absolute_import, division + +import time +import os + +try: + unicode +except NameError: + unicode = str + +from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked + + +class SQLiteLockFile(LockBase): + "Demonstrate SQL-based locking." + + testdb = None + + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = SQLiteLockFile('somefile') + >>> lock = SQLiteLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + self.lock_file = unicode(self.lock_file) + self.unique_name = unicode(self.unique_name) + + if SQLiteLockFile.testdb is None: + import tempfile + _fd, testdb = tempfile.mkstemp() + os.close(_fd) + os.unlink(testdb) + del _fd, tempfile + SQLiteLockFile.testdb = testdb + + import sqlite3 + self.connection = sqlite3.connect(SQLiteLockFile.testdb) + + c = self.connection.cursor() + try: + c.execute("create table locks" + "(" + " lock_file varchar(32)," + " unique_name varchar(32)" + ")") + except sqlite3.OperationalError: + pass + else: + self.connection.commit() + import atexit + atexit.register(os.unlink, SQLiteLockFile.testdb) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + elif timeout <= 0: + wait = 0 + else: + wait = timeout / 10 + + cursor = self.connection.cursor() + + while True: + if not self.is_locked(): + # Not locked. Try to lock it. + cursor.execute("insert into locks" + " (lock_file, unique_name)" + " values" + " (?, ?)", + (self.lock_file, self.unique_name)) + self.connection.commit() + + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) > 1: + # Nope. Someone else got there. Remove our lock. + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + else: + # Yup. We're done, so go home. + return + else: + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) == 1: + # We're the locker, so go home. + return + + # Maybe we should wait a bit longer. + if timeout is not None and time.time() > end_time: + if timeout > 0: + # No more waiting. + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock and we are impatient.. + raise AlreadyLocked("%s is already locked" % self.path) + + # Well, okay. We'll give it a bit longer. + time.sleep(wait) + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me (by %s)" % + (self.unique_name, self._who_is_locking())) + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + + def _who_is_locking(self): + cursor = self.connection.cursor() + cursor.execute("select unique_name from locks" + " where lock_file = ?", + (self.lock_file,)) + return cursor.fetchone()[0] + + def is_locked(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?", + (self.lock_file,)) + rows = cursor.fetchall() + return not not rows + + def i_am_locking(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?" + " and unique_name = ?", + (self.lock_file, self.unique_name)) + return not not cursor.fetchall() + + def break_lock(self): + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where lock_file = ?", + (self.lock_file,)) + self.connection.commit() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py new file mode 100644 index 0000000..23b41f5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py @@ -0,0 +1,70 @@ +from __future__ import absolute_import + +import os +import time + +from . import (LockBase, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class SymlinkLockFile(LockBase): + """Lock access to a file using symlink(2).""" + + def __init__(self, path, threaded=True, timeout=None): + # super(SymlinkLockFile).__init(...) + LockBase.__init__(self, path, threaded, timeout) + # split it back! + self.unique_name = os.path.split(self.unique_name)[1] + + def acquire(self, timeout=None): + # Hopefully unnecessary for symlink. + # try: + # open(self.unique_name, "wb").close() + # except IOError: + # raise LockFailed("failed to create %s" % self.unique_name) + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a symbolic link to it. + try: + os.symlink(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + if self.i_am_locking(): + # Linked to out unique name. Proceed. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout / 10 if timeout is not None else 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.islink(self.lock_file) + + def i_am_locking(self): + return (os.path.islink(self.lock_file) + and os.readlink(self.lock_file) == self.unique_name) + + def break_lock(self): + if os.path.islink(self.lock_file): # exists && link + os.unlink(self.lock_file) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__init__.py new file mode 100644 index 0000000..2afca5a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__init__.py @@ -0,0 +1,66 @@ +# coding: utf-8 +from pip._vendor.msgpack._version import version +from pip._vendor.msgpack.exceptions import * + +from collections import namedtuple + + +class ExtType(namedtuple('ExtType', 'code data')): + """ExtType represents ext type in msgpack.""" + def __new__(cls, code, data): + if not isinstance(code, int): + raise TypeError("code must be int") + if not isinstance(data, bytes): + raise TypeError("data must be bytes") + if not 0 <= code <= 127: + raise ValueError("code must be 0~127") + return super(ExtType, cls).__new__(cls, code, data) + + +import os +if os.environ.get('MSGPACK_PUREPYTHON'): + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker +else: + try: + from pip._vendor.msgpack._packer import Packer + from pip._vendor.msgpack._unpacker import unpackb, Unpacker + except ImportError: + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker + + +def pack(o, stream, **kwargs): + """ + Pack object `o` and write it to `stream` + + See :class:`Packer` for options. + """ + packer = Packer(**kwargs) + stream.write(packer.pack(o)) + + +def packb(o, **kwargs): + """ + Pack object `o` and return packed bytes + + See :class:`Packer` for options. + """ + return Packer(**kwargs).pack(o) + + +def unpack(stream, **kwargs): + """ + Unpack an object from `stream`. + + Raises `ExtraData` when `stream` contains extra bytes. + See :class:`Unpacker` for options. + """ + data = stream.read() + return unpackb(data, **kwargs) + + +# alias for compatibility to simplejson/marshal/pickle. +load = unpack +loads = unpackb + +dump = pack +dumps = packb diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..a6b9f92 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc new file mode 100644 index 0000000..dd7dfa1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000..dcdda1b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc new file mode 100644 index 0000000..b78abd1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/_version.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/_version.py new file mode 100644 index 0000000..d28f0de --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/_version.py @@ -0,0 +1 @@ +version = (0, 5, 6) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/exceptions.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/exceptions.py new file mode 100644 index 0000000..9766881 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/exceptions.py @@ -0,0 +1,41 @@ +class UnpackException(Exception): + """Deprecated. Use Exception instead to catch all exception during unpacking.""" + + +class BufferFull(UnpackException): + pass + + +class OutOfData(UnpackException): + pass + + +class UnpackValueError(UnpackException, ValueError): + """Deprecated. Use ValueError instead.""" + + +class ExtraData(UnpackValueError): + def __init__(self, unpacked, extra): + self.unpacked = unpacked + self.extra = extra + + def __str__(self): + return "unpack(b) received extra data." + + +class PackException(Exception): + """Deprecated. Use Exception instead to catch all exception during packing.""" + + +class PackValueError(PackException, ValueError): + """PackValueError is raised when type of input data is supported but it's value is unsupported. + + Deprecated. Use ValueError instead. + """ + + +class PackOverflowError(PackValueError, OverflowError): + """PackOverflowError is raised when integer value is out of range of msgpack support [-2**31, 2**32). + + Deprecated. Use ValueError instead. + """ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/fallback.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/fallback.py new file mode 100644 index 0000000..9418421 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/msgpack/fallback.py @@ -0,0 +1,977 @@ +"""Fallback pure Python implementation of msgpack""" + +import sys +import struct +import warnings + +if sys.version_info[0] == 3: + PY3 = True + int_types = int + Unicode = str + xrange = range + def dict_iteritems(d): + return d.items() +else: + PY3 = False + int_types = (int, long) + Unicode = unicode + def dict_iteritems(d): + return d.iteritems() + + +if hasattr(sys, 'pypy_version_info'): + # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own + # StringBuilder is fastest. + from __pypy__ import newlist_hint + try: + from __pypy__.builders import BytesBuilder as StringBuilder + except ImportError: + from __pypy__.builders import StringBuilder + USING_STRINGBUILDER = True + class StringIO(object): + def __init__(self, s=b''): + if s: + self.builder = StringBuilder(len(s)) + self.builder.append(s) + else: + self.builder = StringBuilder() + def write(self, s): + if isinstance(s, memoryview): + s = s.tobytes() + elif isinstance(s, bytearray): + s = bytes(s) + self.builder.append(s) + def getvalue(self): + return self.builder.build() +else: + USING_STRINGBUILDER = False + from io import BytesIO as StringIO + newlist_hint = lambda size: [] + + +from pip._vendor.msgpack.exceptions import ( + BufferFull, + OutOfData, + UnpackValueError, + PackValueError, + PackOverflowError, + ExtraData) + +from pip._vendor.msgpack import ExtType + + +EX_SKIP = 0 +EX_CONSTRUCT = 1 +EX_READ_ARRAY_HEADER = 2 +EX_READ_MAP_HEADER = 3 + +TYPE_IMMEDIATE = 0 +TYPE_ARRAY = 1 +TYPE_MAP = 2 +TYPE_RAW = 3 +TYPE_BIN = 4 +TYPE_EXT = 5 + +DEFAULT_RECURSE_LIMIT = 511 + + +def _check_type_strict(obj, t, type=type, tuple=tuple): + if type(t) is tuple: + return type(obj) in t + else: + return type(obj) is t + + +def _get_data_from_buffer(obj): + try: + view = memoryview(obj) + except TypeError: + # try to use legacy buffer protocol if 2.7, otherwise re-raise + if not PY3: + view = memoryview(buffer(obj)) + warnings.warn("using old buffer interface to unpack %s; " + "this leads to unpacking errors if slicing is used and " + "will be removed in a future version" % type(obj), + RuntimeWarning) + else: + raise + if view.itemsize != 1: + raise ValueError("cannot unpack from multi-byte object") + return view + + +def unpack(stream, **kwargs): + warnings.warn( + "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.", + PendingDeprecationWarning) + data = stream.read() + return unpackb(data, **kwargs) + + +def unpackb(packed, **kwargs): + """ + Unpack an object from `packed`. + + Raises `ExtraData` when `packed` contains extra bytes. + See :class:`Unpacker` for options. + """ + unpacker = Unpacker(None, **kwargs) + unpacker.feed(packed) + try: + ret = unpacker._unpack() + except OutOfData: + raise UnpackValueError("Data is not enough.") + if unpacker._got_extradata(): + raise ExtraData(ret, unpacker._get_extradata()) + return ret + + +class Unpacker(object): + """Streaming unpacker. + + arguments: + + :param file_like: + File-like object having `.read(n)` method. + If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable. + + :param int read_size: + Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`) + + :param bool use_list: + If true, unpack msgpack array to Python list. + Otherwise, unpack to Python tuple. (default: True) + + :param bool raw: + If true, unpack msgpack raw to Python bytes (default). + Otherwise, unpack to Python str (or unicode on Python 2) by decoding + with UTF-8 encoding (recommended). + Currently, the default is true, but it will be changed to false in + near future. So you must specify it explicitly for keeping backward + compatibility. + + *encoding* option which is deprecated overrides this option. + + :param callable object_hook: + When specified, it should be callable. + Unpacker calls it with a dict argument after unpacking msgpack map. + (See also simplejson) + + :param callable object_pairs_hook: + When specified, it should be callable. + Unpacker calls it with a list of key-value pairs after unpacking msgpack map. + (See also simplejson) + + :param str encoding: + Encoding used for decoding msgpack raw. + If it is None (default), msgpack raw is deserialized to Python bytes. + + :param str unicode_errors: + (deprecated) Used for decoding msgpack raw with *encoding*. + (default: `'strict'`) + + :param int max_buffer_size: + Limits size of data waiting unpacked. 0 means system's INT_MAX (default). + Raises `BufferFull` exception when it is insufficient. + You should set this parameter when unpacking data from untrusted source. + + :param int max_str_len: + Limits max length of str. (default: 2**31-1) + + :param int max_bin_len: + Limits max length of bin. (default: 2**31-1) + + :param int max_array_len: + Limits max length of array. (default: 2**31-1) + + :param int max_map_len: + Limits max length of map. (default: 2**31-1) + + + example of streaming deserialize from file-like object:: + + unpacker = Unpacker(file_like, raw=False) + for o in unpacker: + process(o) + + example of streaming deserialize from socket:: + + unpacker = Unpacker(raw=False) + while True: + buf = sock.recv(1024**2) + if not buf: + break + unpacker.feed(buf) + for o in unpacker: + process(o) + """ + + def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, + object_hook=None, object_pairs_hook=None, list_hook=None, + encoding=None, unicode_errors=None, max_buffer_size=0, + ext_hook=ExtType, + max_str_len=2147483647, # 2**32-1 + max_bin_len=2147483647, + max_array_len=2147483647, + max_map_len=2147483647, + max_ext_len=2147483647): + + if encoding is not None: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + if file_like is None: + self._feeding = True + else: + if not callable(file_like.read): + raise TypeError("`file_like.read` must be callable") + self.file_like = file_like + self._feeding = False + + #: array of bytes fed. + self._buffer = bytearray() + # Some very old pythons don't support `struct.unpack_from()` with a + # `bytearray`. So we wrap it in a `buffer()` there. + if sys.version_info < (2, 7, 6): + self._buffer_view = buffer(self._buffer) + else: + self._buffer_view = self._buffer + #: Which position we currently reads + self._buff_i = 0 + + # When Unpacker is used as an iterable, between the calls to next(), + # the buffer is not "consumed" completely, for efficiency sake. + # Instead, it is done sloppily. To make sure we raise BufferFull at + # the correct moments, we have to keep track of how sloppy we were. + # Furthermore, when the buffer is incomplete (that is: in the case + # we raise an OutOfData) we need to rollback the buffer to the correct + # state, which _buf_checkpoint records. + self._buf_checkpoint = 0 + + self._max_buffer_size = max_buffer_size or 2**31-1 + if read_size > self._max_buffer_size: + raise ValueError("read_size must be smaller than max_buffer_size") + self._read_size = read_size or min(self._max_buffer_size, 16*1024) + self._raw = bool(raw) + self._encoding = encoding + self._unicode_errors = unicode_errors + self._use_list = use_list + self._list_hook = list_hook + self._object_hook = object_hook + self._object_pairs_hook = object_pairs_hook + self._ext_hook = ext_hook + self._max_str_len = max_str_len + self._max_bin_len = max_bin_len + self._max_array_len = max_array_len + self._max_map_len = max_map_len + self._max_ext_len = max_ext_len + self._stream_offset = 0 + + if list_hook is not None and not callable(list_hook): + raise TypeError('`list_hook` is not callable') + if object_hook is not None and not callable(object_hook): + raise TypeError('`object_hook` is not callable') + if object_pairs_hook is not None and not callable(object_pairs_hook): + raise TypeError('`object_pairs_hook` is not callable') + if object_hook is not None and object_pairs_hook is not None: + raise TypeError("object_pairs_hook and object_hook are mutually " + "exclusive") + if not callable(ext_hook): + raise TypeError("`ext_hook` is not callable") + + def feed(self, next_bytes): + assert self._feeding + view = _get_data_from_buffer(next_bytes) + if (len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size): + raise BufferFull + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + self._buffer += view + + def _consume(self): + """ Gets rid of the used parts of the buffer. """ + self._stream_offset += self._buff_i - self._buf_checkpoint + self._buf_checkpoint = self._buff_i + + def _got_extradata(self): + return self._buff_i < len(self._buffer) + + def _get_extradata(self): + return self._buffer[self._buff_i:] + + def read_bytes(self, n): + return self._read(n) + + def _read(self, n): + # (int) -> bytearray + self._reserve(n) + i = self._buff_i + self._buff_i = i+n + return self._buffer[i:i+n] + + def _reserve(self, n): + remain_bytes = len(self._buffer) - self._buff_i - n + + # Fast path: buffer has n bytes already + if remain_bytes >= 0: + return + + if self._feeding: + self._buff_i = self._buf_checkpoint + raise OutOfData + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + # Read from file + remain_bytes = -remain_bytes + while remain_bytes > 0: + to_read_bytes = max(self._read_size, remain_bytes) + read_data = self.file_like.read(to_read_bytes) + if not read_data: + break + assert isinstance(read_data, bytes) + self._buffer += read_data + remain_bytes -= len(read_data) + + if len(self._buffer) < n + self._buff_i: + self._buff_i = 0 # rollback + raise OutOfData + + def _read_header(self, execute=EX_CONSTRUCT): + typ = TYPE_IMMEDIATE + n = 0 + obj = None + self._reserve(1) + b = self._buffer[self._buff_i] + self._buff_i += 1 + if b & 0b10000000 == 0: + obj = b + elif b & 0b11100000 == 0b11100000: + obj = -1 - (b ^ 0xff) + elif b & 0b11100000 == 0b10100000: + n = b & 0b00011111 + typ = TYPE_RAW + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b & 0b11110000 == 0b10010000: + n = b & 0b00001111 + typ = TYPE_ARRAY + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b & 0b11110000 == 0b10000000: + n = b & 0b00001111 + typ = TYPE_MAP + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + elif b == 0xc0: + obj = None + elif b == 0xc2: + obj = False + elif b == 0xc3: + obj = True + elif b == 0xc4: + typ = TYPE_BIN + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc5: + typ = TYPE_BIN + self._reserve(2) + n = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc6: + typ = TYPE_BIN + self._reserve(4) + n = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc7: # ext 8 + typ = TYPE_EXT + self._reserve(2) + L, n = struct.unpack_from('Bb', self._buffer_view, self._buff_i) + self._buff_i += 2 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc8: # ext 16 + typ = TYPE_EXT + self._reserve(3) + L, n = struct.unpack_from('>Hb', self._buffer_view, self._buff_i) + self._buff_i += 3 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc9: # ext 32 + typ = TYPE_EXT + self._reserve(5) + L, n = struct.unpack_from('>Ib', self._buffer_view, self._buff_i) + self._buff_i += 5 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xca: + self._reserve(4) + obj = struct.unpack_from(">f", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcb: + self._reserve(8) + obj = struct.unpack_from(">d", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xcc: + self._reserve(1) + obj = self._buffer[self._buff_i] + self._buff_i += 1 + elif b == 0xcd: + self._reserve(2) + obj = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xce: + self._reserve(4) + obj = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcf: + self._reserve(8) + obj = struct.unpack_from(">Q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd0: + self._reserve(1) + obj = struct.unpack_from("b", self._buffer_view, self._buff_i)[0] + self._buff_i += 1 + elif b == 0xd1: + self._reserve(2) + obj = struct.unpack_from(">h", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xd2: + self._reserve(4) + obj = struct.unpack_from(">i", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xd3: + self._reserve(8) + obj = struct.unpack_from(">q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd4: # fixext 1 + typ = TYPE_EXT + if self._max_ext_len < 1: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) + self._reserve(2) + n, obj = struct.unpack_from("b1s", self._buffer_view, self._buff_i) + self._buff_i += 2 + elif b == 0xd5: # fixext 2 + typ = TYPE_EXT + if self._max_ext_len < 2: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) + self._reserve(3) + n, obj = struct.unpack_from("b2s", self._buffer_view, self._buff_i) + self._buff_i += 3 + elif b == 0xd6: # fixext 4 + typ = TYPE_EXT + if self._max_ext_len < 4: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) + self._reserve(5) + n, obj = struct.unpack_from("b4s", self._buffer_view, self._buff_i) + self._buff_i += 5 + elif b == 0xd7: # fixext 8 + typ = TYPE_EXT + if self._max_ext_len < 8: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) + self._reserve(9) + n, obj = struct.unpack_from("b8s", self._buffer_view, self._buff_i) + self._buff_i += 9 + elif b == 0xd8: # fixext 16 + typ = TYPE_EXT + if self._max_ext_len < 16: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) + self._reserve(17) + n, obj = struct.unpack_from("b16s", self._buffer_view, self._buff_i) + self._buff_i += 17 + elif b == 0xd9: + typ = TYPE_RAW + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xda: + typ = TYPE_RAW + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdb: + typ = TYPE_RAW + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdc: + typ = TYPE_ARRAY + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xdd: + typ = TYPE_ARRAY + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xde: + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + elif b == 0xdf: + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + else: + raise UnpackValueError("Unknown header: 0x%x" % b) + return typ, n, obj + + def _unpack(self, execute=EX_CONSTRUCT): + typ, n, obj = self._read_header(execute) + + if execute == EX_READ_ARRAY_HEADER: + if typ != TYPE_ARRAY: + raise UnpackValueError("Expected array") + return n + if execute == EX_READ_MAP_HEADER: + if typ != TYPE_MAP: + raise UnpackValueError("Expected map") + return n + # TODO should we eliminate the recursion? + if typ == TYPE_ARRAY: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call `list_hook` + self._unpack(EX_SKIP) + return + ret = newlist_hint(n) + for i in xrange(n): + ret.append(self._unpack(EX_CONSTRUCT)) + if self._list_hook is not None: + ret = self._list_hook(ret) + # TODO is the interaction between `list_hook` and `use_list` ok? + return ret if self._use_list else tuple(ret) + if typ == TYPE_MAP: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call hooks + self._unpack(EX_SKIP) + self._unpack(EX_SKIP) + return + if self._object_pairs_hook is not None: + ret = self._object_pairs_hook( + (self._unpack(EX_CONSTRUCT), + self._unpack(EX_CONSTRUCT)) + for _ in xrange(n)) + else: + ret = {} + for _ in xrange(n): + key = self._unpack(EX_CONSTRUCT) + ret[key] = self._unpack(EX_CONSTRUCT) + if self._object_hook is not None: + ret = self._object_hook(ret) + return ret + if execute == EX_SKIP: + return + if typ == TYPE_RAW: + if self._encoding is not None: + obj = obj.decode(self._encoding, self._unicode_errors) + elif self._raw: + obj = bytes(obj) + else: + obj = obj.decode('utf_8') + return obj + if typ == TYPE_EXT: + return self._ext_hook(n, bytes(obj)) + if typ == TYPE_BIN: + return bytes(obj) + assert typ == TYPE_IMMEDIATE + return obj + + def __iter__(self): + return self + + def __next__(self): + try: + ret = self._unpack(EX_CONSTRUCT) + self._consume() + return ret + except OutOfData: + self._consume() + raise StopIteration + + next = __next__ + + def skip(self, write_bytes=None): + self._unpack(EX_SKIP) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + + def unpack(self, write_bytes=None): + ret = self._unpack(EX_CONSTRUCT) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_array_header(self, write_bytes=None): + ret = self._unpack(EX_READ_ARRAY_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_map_header(self, write_bytes=None): + ret = self._unpack(EX_READ_MAP_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def tell(self): + return self._stream_offset + + +class Packer(object): + """ + MessagePack Packer + + usage: + + packer = Packer() + astream.write(packer.pack(a)) + astream.write(packer.pack(b)) + + Packer's constructor has some keyword arguments: + + :param callable default: + Convert user type to builtin type that Packer supports. + See also simplejson's document. + + :param bool use_single_float: + Use single precision float type for float. (default: False) + + :param bool autoreset: + Reset buffer after each pack and return its content as `bytes`. (default: True). + If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. + + :param bool use_bin_type: + Use bin type introduced in msgpack spec 2.0 for bytes. + It also enables str8 type for unicode. + + :param bool strict_types: + If set to true, types will be checked to be exact. Derived classes + from serializeable types will not be serialized and will be + treated as unsupported type and forwarded to default. + Additionally tuples will not be serialized as lists. + This is useful when trying to implement accurate serialization + for python types. + + :param str encoding: + (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8') + + :param str unicode_errors: + Error handler for encoding unicode. (default: 'strict') + """ + def __init__(self, default=None, encoding=None, unicode_errors=None, + use_single_float=False, autoreset=True, use_bin_type=False, + strict_types=False): + if encoding is None: + encoding = 'utf_8' + else: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + self._strict_types = strict_types + self._use_float = use_single_float + self._autoreset = autoreset + self._use_bin_type = use_bin_type + self._encoding = encoding + self._unicode_errors = unicode_errors + self._buffer = StringIO() + if default is not None: + if not callable(default): + raise TypeError("default must be callable") + self._default = default + + def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, + check=isinstance, check_type_strict=_check_type_strict): + default_used = False + if self._strict_types: + check = check_type_strict + list_types = list + else: + list_types = (list, tuple) + while True: + if nest_limit < 0: + raise PackValueError("recursion limit exceeded") + if obj is None: + return self._buffer.write(b"\xc0") + if check(obj, bool): + if obj: + return self._buffer.write(b"\xc3") + return self._buffer.write(b"\xc2") + if check(obj, int_types): + if 0 <= obj < 0x80: + return self._buffer.write(struct.pack("B", obj)) + if -0x20 <= obj < 0: + return self._buffer.write(struct.pack("b", obj)) + if 0x80 <= obj <= 0xff: + return self._buffer.write(struct.pack("BB", 0xcc, obj)) + if -0x80 <= obj < 0: + return self._buffer.write(struct.pack(">Bb", 0xd0, obj)) + if 0xff < obj <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xcd, obj)) + if -0x8000 <= obj < -0x80: + return self._buffer.write(struct.pack(">Bh", 0xd1, obj)) + if 0xffff < obj <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xce, obj)) + if -0x80000000 <= obj < -0x8000: + return self._buffer.write(struct.pack(">Bi", 0xd2, obj)) + if 0xffffffff < obj <= 0xffffffffffffffff: + return self._buffer.write(struct.pack(">BQ", 0xcf, obj)) + if -0x8000000000000000 <= obj < -0x80000000: + return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = True + continue + raise PackOverflowError("Integer value out of range") + if check(obj, (bytes, bytearray)): + n = len(obj) + if n >= 2**32: + raise PackValueError("%s is too large" % type(obj).__name__) + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, Unicode): + if self._encoding is None: + raise TypeError( + "Can't encode unicode string: " + "no encoding is specified") + obj = obj.encode(self._encoding, self._unicode_errors) + n = len(obj) + if n >= 2**32: + raise PackValueError("String is too large") + self._pack_raw_header(n) + return self._buffer.write(obj) + if check(obj, memoryview): + n = len(obj) * obj.itemsize + if n >= 2**32: + raise PackValueError("Memoryview is too large") + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, float): + if self._use_float: + return self._buffer.write(struct.pack(">Bf", 0xca, obj)) + return self._buffer.write(struct.pack(">Bd", 0xcb, obj)) + if check(obj, ExtType): + code = obj.code + data = obj.data + assert isinstance(code, int) + assert isinstance(data, bytes) + L = len(data) + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(struct.pack(">BB", 0xc7, L)) + elif L <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xc8, L)) + else: + self._buffer.write(struct.pack(">BI", 0xc9, L)) + self._buffer.write(struct.pack("b", code)) + self._buffer.write(data) + return + if check(obj, list_types): + n = len(obj) + self._pack_array_header(n) + for i in xrange(n): + self._pack(obj[i], nest_limit - 1) + return + if check(obj, dict): + return self._pack_map_pairs(len(obj), dict_iteritems(obj), + nest_limit - 1) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = 1 + continue + raise TypeError("Cannot serialize %r" % (obj, )) + + def pack(self, obj): + try: + self._pack(obj) + except: + self._buffer = StringIO() # force reset + raise + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_pairs(self, pairs): + self._pack_map_pairs(len(pairs), pairs) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_array_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_array_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_map_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_ext_type(self, typecode, data): + if not isinstance(typecode, int): + raise TypeError("typecode must have int type.") + if not 0 <= typecode <= 127: + raise ValueError("typecode should be 0-127") + if not isinstance(data, bytes): + raise TypeError("data must have bytes type") + L = len(data) + if L > 0xffffffff: + raise PackValueError("Too large data") + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(b'\xc7' + struct.pack('B', L)) + elif L <= 0xffff: + self._buffer.write(b'\xc8' + struct.pack('>H', L)) + else: + self._buffer.write(b'\xc9' + struct.pack('>I', L)) + self._buffer.write(struct.pack('B', typecode)) + self._buffer.write(data) + + def _pack_array_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x90 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xdc, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdd, n)) + raise PackValueError("Array is too large") + + def _pack_map_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x80 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xde, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdf, n)) + raise PackValueError("Dict is too large") + + def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT): + self._pack_map_header(n) + for (k, v) in pairs: + self._pack(k, nest_limit - 1) + self._pack(v, nest_limit - 1) + + def _pack_raw_header(self, n): + if n <= 0x1f: + self._buffer.write(struct.pack('B', 0xa0 + n)) + elif self._use_bin_type and n <= 0xff: + self._buffer.write(struct.pack('>BB', 0xd9, n)) + elif n <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xda, n)) + elif n <= 0xffffffff: + self._buffer.write(struct.pack(">BI", 0xdb, n)) + else: + raise PackValueError('Raw is too large') + + def _pack_bin_header(self, n): + if not self._use_bin_type: + return self._pack_raw_header(n) + elif n <= 0xff: + return self._buffer.write(struct.pack('>BB', 0xc4, n)) + elif n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xc5, n)) + elif n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xc6, n)) + else: + raise PackValueError('Bin is too large') + + def bytes(self): + return self._buffer.getvalue() + + def reset(self): + self._buffer = StringIO() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py new file mode 100644 index 0000000..4255c5b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "17.1" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc new file mode 100644 index 0000000..992bf29 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..75865aa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000..21aa68b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc new file mode 100644 index 0000000..822f941 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000..cac3279 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc new file mode 100644 index 0000000..62183c8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc new file mode 100644 index 0000000..b8f5a51 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000..1b709c8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000..a6d9e40 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + Create a base class with a metaclass. + """ + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py new file mode 100644 index 0000000..e9fc4a0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/_structures.py @@ -0,0 +1,70 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + + +NegativeInfinity = NegativeInfinity() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py new file mode 100644 index 0000000..e5834ce --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pip._vendor.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pip._vendor.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +class Variable(Node): + + def serialize(self): + return str(self) + + +class Value(Node): + + def serialize(self): + return '"{0}"'.format(self) + + +class Op(Node): + + def serialize(self): + return str(self) + + +VARIABLE = ( + L("implementation_version") | + L("platform_python_implementation") | + L("implementation_name") | + L("python_full_version") | + L("platform_release") | + L("platform_version") | + L("platform_machine") | + L("platform_system") | + L("python_version") | + L("sys_platform") | + L("os_name") | + L("os.name") | # PEP-345 + L("sys.platform") | # PEP-345 + L("platform.version") | # PEP-345 + L("platform.machine") | # PEP-345 + L("platform.python_implementation") | # PEP-345 + L("python_implementation") | # undocumented setuptools legacy + L("extra") +) +ALIASES = { + 'os.name': 'os_name', + 'sys.platform': 'sys_platform', + 'platform.version': 'platform_version', + 'platform.machine': 'platform_machine', + 'platform.python_implementation': 'platform_python_implementation', + 'python_implementation': 'platform_python_implementation' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if (isinstance(marker, list) and len(marker) == 1 and + isinstance(marker[0], (list, tuple))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "sys_platform": sys.platform, + } + + +class Marker(object): + + def __init__(self, marker): + try: + self._markers = _coerce_parse_result(MARKER.parseString(marker)) + except ParseException as e: + err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( + marker, marker[e.loc:e.loc + 8]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py new file mode 100644 index 0000000..2760483 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/requirements.py @@ -0,0 +1,130 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pip._vendor.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from pip._vendor.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from pip._vendor.pyparsing import Literal as L # noqa +from pip._vendor.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) +VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) + +VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY +VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), + joinString=",", adjacent=False)("_raw_spec") +_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') + +VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") +VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) + +MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") +MARKER_EXPR.setParseAction( + lambda s, l, t: Marker(s[t._original_start:t._original_end]) +) +MARKER_SEPARATOR = SEMICOLON +MARKER = MARKER_SEPARATOR + MARKER_EXPR + +VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) +URL_AND_MARKER = URL + Optional(MARKER) + +NAMED_REQUIREMENT = \ + NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement( + "Invalid requirement, parse error at \"{0!r}\"".format( + requirement_string[e.loc:e.loc + 8])) + + self.name = req.name + if req.url: + parsed_url = urlparse.urlparse(req.url) + if not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc): + raise InvalidRequirement("Invalid URL given") + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..9b6353f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=None): + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) + + self._spec = ( + match.group("operator").strip(), + match.group("version").strip(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version or LegacyVersion, this allows us to have + # a shortcut for ``"2.0" in Specifier(">=2") + item = self._coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + return self._get_operator(self.operator)(item, self.version) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later incase nothing + # else matches this specifier. + if (parsed_version.is_prerelease and not + (prereleases or self.prereleases)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the beginning. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # Compatible releases have an equivalent combination of >= and ==. That + # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to + # implement this in terms of the other specifiers instead of + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # We need special logic to handle prefix matching + if spec.endswith(".*"): + # In the case of prefix matching we want to ignore local segment. + prospective = Version(prospective.public) + # Split the spec out by dots, and pretend that there is an implicit + # dot in between a release segment and a pre-release segment. + spec = _version_split(spec[:-2]) # Remove the trailing .* + + # Split the prospective version out by dots, and pretend that there + # is an implicit dot in between a release segment and a pre-release + # segment. + prospective = _version_split(str(prospective)) + + # Shorten the prospective version to be the same length as the spec + # so that we can determine if the specifier is a prefix of the + # prospective version or not. + prospective = prospective[:len(spec)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = Version(spec) + + # If the specifier does not have a local segment, then we want to + # act as if the prospective version also does not have a local + # segment. + if not spec.local: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is less than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is greater than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # in the specifier, which is techincally greater than, to match. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) + + # Get the rest of our versions + left_split.append(left[len(left_split[0]):]) + right_split.append(right[len(right_split[0]):]) + + # Insert our padding + left_split.insert( + 1, + ["0"] * max(0, len(right_split[0]) - len(left_split[0])), + ) + right_split.insert( + 1, + ["0"] * max(0, len(left_split[0]) - len(right_split[0])), + ) + + return ( + list(itertools.chain(*left_split)), + list(itertools.chain(*right_split)), + ) + + +class SpecifierSet(BaseSpecifier): + + def __init__(self, specifiers="", prereleases=None): + # Split on , to break each indidivual specifier into it's own item, and + # strip each item to remove leading/trailing whitespace. + specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + # Parsed each individual specifier, attempting first to make it a + # Specifier and falling back to a LegacySpecifier. + parsed = set() + for specifier in specifiers: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # given version is contained within all of them. + # Note: This use of all() here means that an empty set of specifiers + # will always return True, this is an explicit design decision. + return all( + s.contains(item, prereleases=prereleases) + for s in self._specs + ) + + def filter(self, iterable, prereleases=None): + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # which will filter out any pre-releases, unless there are no final + # releases, and which will filter out LegacyVersion in general. + else: + filtered = [] + found_prereleases = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py new file mode 100644 index 0000000..4b94a82 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/utils.py @@ -0,0 +1,63 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + +from .version import InvalidVersion, Version + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() + + +def canonicalize_version(version): + """ + This is very similar to Version.__str__, but has one subtle differences + with the way it handles the release segment. + """ + + try: + version = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + + parts = [] + + # Epoch + if version.epoch != 0: + parts.append("{0}!".format(version.epoch)) + + # Release segment + # NB: This strips trailing '.0's to normalize + parts.append( + re.sub( + r'(\.0)+$', + '', + ".".join(str(x) for x in version.release) + ) + ) + + # Pre-release + if version.pre is not None: + parts.append("".join(str(x) for x in version.pre)) + + # Post-release + if version.post is not None: + parts.append(".post{0}".format(version.post)) + + # Development release + if version.dev is not None: + parts.append(".dev{0}".format(version.dev)) + + # Local version segment + if version.local is not None: + parts.append("+{0}".format(version.local)) + + return "".join(parts) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py new file mode 100644 index 0000000..6ed5cbb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/packaging/version.py @@ -0,0 +1,441 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(version): + """ + Parse the given version string and return either a :class:`Version` object + or a :class:`LegacyVersion` object depending on if the given version is + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def epoch(self): + return -1 + + @property + def release(self): + return None + + @property + def pre(self): + return None + + @property + def post(self): + return None + + @property + def dev(self): + return None + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + @property + def is_devrelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + return epoch, parts + + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse +VERSION_PATTERN = r""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _regex = re.compile( + r"^\s*" + VERSION_PATTERN + r"\s*$", + re.VERBOSE | re.IGNORECASE, + ) + + def __init__(self, version): + # Validate the version and parse it into pieces + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + self._version = _Version( + epoch=int(match.group("epoch")) if match.group("epoch") else 0, + release=tuple(int(i) for i in match.group("release").split(".")), + pre=_parse_letter_version( + match.group("pre_l"), + match.group("pre_n"), + ), + post=_parse_letter_version( + match.group("post_l"), + match.group("post_n1") or match.group("post_n2"), + ), + dev=_parse_letter_version( + match.group("dev_l"), + match.group("dev_n"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + # Pre-release + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) + + # Post-release + if self.post is not None: + parts.append(".post{0}".format(self.post)) + + # Development release + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) + + # Local version segment + if self.local is not None: + parts.append("+{0}".format(self.local)) + + return "".join(parts) + + @property + def epoch(self): + return self._version.epoch + + @property + def release(self): + return self._version.release + + @property + def pre(self): + return self._version.pre + + @property + def post(self): + return self._version.post[1] if self._version.post else None + + @property + def dev(self): + return self._version.dev[1] if self._version.dev else None + + @property + def local(self): + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + return "".join(parts) + + @property + def is_prerelease(self): + return self.dev is not None or self.pre is not None + + @property + def is_postrelease(self): + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None + + +def _parse_letter_version(letter, number): + if letter: + # We consider there to be an implicit 0 in a pre-release if there is + # not a numeral associated with it. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_separators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_separators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # When we compare a release version, we want to compare it with all of the + # trailing zeros removed. So we'll use a reverse the list, drop all the now + # leading zeros until we come to something non zero, then take the rest + # re-reverse it back into the correct order and make it a tuple and use + # that for our sorting key. + release = tuple( + reversed(list( + itertools.dropwhile( + lambda x: x == 0, + reversed(release), + ) + )) + ) + + # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # if there is not a pre or a post segment. If we have one of those then + # the normal sorting rules will handle this case correctly. + if pre is None and post is None and dev is not None: + pre = -Infinity + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - Numeric segments sort numerically + # - Shorter versions sort before longer versions when the prefixes + # match exactly + local = tuple( + (i, "") if isinstance(i, int) else (-Infinity, i) + for i in local + ) + + return epoch, release, pre, post, dev, local diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__init__.py new file mode 100644 index 0000000..19d3d05 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__init__.py @@ -0,0 +1,3125 @@ +# coding: utf-8 +""" +Package resource API +-------------------- + +A resource is a logical file contained within a package, or a logical +subdirectory thereof. The package resource API expects resource names +to have their path parts separated with ``/``, *not* whatever the local +path separator is. Do not use os.path operations to manipulate resource +names being passed into the API. + +The package resource API is designed to work with normal filesystem packages, +.egg files, and unpacked .egg files. It can also work in a limited way with +.zip files and with custom PEP 302 loaders that support the ``get_data()`` +method. +""" + +from __future__ import absolute_import + +import sys +import os +import io +import time +import re +import types +import zipfile +import zipimport +import warnings +import stat +import functools +import pkgutil +import operator +import platform +import collections +import plistlib +import email.parser +import errno +import tempfile +import textwrap +import itertools +import inspect +from pkgutil import get_importer + +try: + import _imp +except ImportError: + # Python 3.2 compatibility + import imp as _imp + +from pip._vendor import six +from pip._vendor.six.moves import urllib, map, filter + +# capture these to bypass sandboxing +from os import utime +try: + from os import mkdir, rename, unlink + WRITE_SUPPORT = True +except ImportError: + # no write support, probably under GAE + WRITE_SUPPORT = False + +from os import open as os_open +from os.path import isdir, split + +try: + import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: + importlib_machinery = None + +from . import py31compat +from pip._vendor import appdirs +from pip._vendor import packaging +__import__('pip._vendor.packaging.version') +__import__('pip._vendor.packaging.specifiers') +__import__('pip._vendor.packaging.requirements') +__import__('pip._vendor.packaging.markers') + + +if (3, 0) < sys.version_info < (3, 3): + raise RuntimeError("Python 3.3 or later is required") + +if six.PY2: + # Those builtin exceptions are only defined in Python 3 + PermissionError = None + NotADirectoryError = None + +# declare some globals that will be defined later to +# satisfy the linters. +require = None +working_set = None +add_activation_listener = None +resources_stream = None +cleanup_resources = None +resource_dir = None +resource_stream = None +set_extraction_path = None +resource_isdir = None +resource_string = None +iter_entry_points = None +resource_listdir = None +resource_filename = None +resource_exists = None +_distribution_finders = None +_namespace_handlers = None +_namespace_packages = None + + +class PEP440Warning(RuntimeWarning): + """ + Used when there is an issue with a version or specifier not complying with + PEP 440. + """ + + +def parse_version(v): + try: + return packaging.version.Version(v) + except packaging.version.InvalidVersion: + return packaging.version.LegacyVersion(v) + + +_state_vars = {} + + +def _declare_state(vartype, **kw): + globals().update(kw) + _state_vars.update(dict.fromkeys(kw, vartype)) + + +def __getstate__(): + state = {} + g = globals() + for k, v in _state_vars.items(): + state[k] = g['_sget_' + v](g[k]) + return state + + +def __setstate__(state): + g = globals() + for k, v in state.items(): + g['_sset_' + _state_vars[k]](k, g[k], v) + return state + + +def _sget_dict(val): + return val.copy() + + +def _sset_dict(key, ob, state): + ob.clear() + ob.update(state) + + +def _sget_object(val): + return val.__getstate__() + + +def _sset_object(key, ob, state): + ob.__setstate__(state) + + +_sget_none = _sset_none = lambda *args: None + + +def get_supported_platform(): + """Return this platform's maximum compatible version. + + distutils.util.get_platform() normally reports the minimum version + of Mac OS X that would be required to *use* extensions produced by + distutils. But what we want when checking compatibility is to know the + version of Mac OS X that we are *running*. To allow usage of packages that + explicitly require a newer version of Mac OS X, we must also know the + current version of the OS. + + If this condition occurs for any other platform with a version in its + platform strings, this function should be extended accordingly. + """ + plat = get_build_platform() + m = macosVersionString.match(plat) + if m is not None and sys.platform == "darwin": + try: + plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) + except ValueError: + # not Mac OS X + pass + return plat + + +__all__ = [ + # Basic resource access and distribution/entry point discovery + 'require', 'run_script', 'get_provider', 'get_distribution', + 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'iter_entry_points', + 'resource_string', 'resource_stream', 'resource_filename', + 'resource_listdir', 'resource_exists', 'resource_isdir', + + # Environmental control + 'declare_namespace', 'working_set', 'add_activation_listener', + 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'get_default_cache', + + # Primary implementation classes + 'Environment', 'WorkingSet', 'ResourceManager', + 'Distribution', 'Requirement', 'EntryPoint', + + # Exceptions + 'ResolutionError', 'VersionConflict', 'DistributionNotFound', + 'UnknownExtra', 'ExtractionError', + + # Warnings + 'PEP440Warning', + + # Parsing functions and string utilities + 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', + 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', + 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', + + # filesystem utilities + 'ensure_directory', 'normalize_path', + + # Distribution "precedence" constants + 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', + + # "Provider" interfaces, implementations, and registration/lookup APIs + 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', + 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', + 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', + 'register_finder', 'register_namespace_handler', 'register_loader_type', + 'fixup_namespace_packages', 'get_importer', + + # Deprecated/backward compatibility only + 'run_main', 'AvailableDistributions', +] + + +class ResolutionError(Exception): + """Abstract base for dependency resolution errors""" + + def __repr__(self): + return self.__class__.__name__ + repr(self.args) + + +class VersionConflict(ResolutionError): + """ + An already-installed version conflicts with the requested version. + + Should be initialized with the installed Distribution and the requested + Requirement. + """ + + _template = "{self.dist} is installed but {self.req} is required" + + @property + def dist(self): + return self.args[0] + + @property + def req(self): + return self.args[1] + + def report(self): + return self._template.format(**locals()) + + def with_context(self, required_by): + """ + If required_by is non-empty, return a version of self that is a + ContextualVersionConflict. + """ + if not required_by: + return self + args = self.args + (required_by,) + return ContextualVersionConflict(*args) + + +class ContextualVersionConflict(VersionConflict): + """ + A VersionConflict that accepts a third parameter, the set of the + requirements that required the installed Distribution. + """ + + _template = VersionConflict._template + ' by {self.required_by}' + + @property + def required_by(self): + return self.args[2] + + +class DistributionNotFound(ResolutionError): + """A requested distribution was not found""" + + _template = ("The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}") + + @property + def req(self): + return self.args[0] + + @property + def requirers(self): + return self.args[1] + + @property + def requirers_str(self): + if not self.requirers: + return 'the application' + return ', '.join(self.requirers) + + def report(self): + return self._template.format(**locals()) + + def __str__(self): + return self.report() + + +class UnknownExtra(ResolutionError): + """Distribution doesn't have an "extra feature" of the given name""" + + +_provider_factories = {} + +PY_MAJOR = sys.version[:3] +EGG_DIST = 3 +BINARY_DIST = 2 +SOURCE_DIST = 1 +CHECKOUT_DIST = 0 +DEVELOP_DIST = -1 + + +def register_loader_type(loader_type, provider_factory): + """Register `provider_factory` to make providers for `loader_type` + + `loader_type` is the type or class of a PEP 302 ``module.__loader__``, + and `provider_factory` is a function that, passed a *module* object, + returns an ``IResourceProvider`` for that module. + """ + _provider_factories[loader_type] = provider_factory + + +def get_provider(moduleOrReq): + """Return an IResourceProvider for the named module or requirement""" + if isinstance(moduleOrReq, Requirement): + return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] + try: + module = sys.modules[moduleOrReq] + except KeyError: + __import__(moduleOrReq) + module = sys.modules[moduleOrReq] + loader = getattr(module, '__loader__', None) + return _find_adapter(_provider_factories, loader)(module) + + +def _macosx_vers(_cache=[]): + if not _cache: + version = platform.mac_ver()[0] + # fallback for MacPorts + if version == '': + plist = '/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists(plist): + if hasattr(plistlib, 'readPlist'): + plist_content = plistlib.readPlist(plist) + if 'ProductVersion' in plist_content: + version = plist_content['ProductVersion'] + + _cache.append(version.split('.')) + return _cache[0] + + +def _macosx_arch(machine): + return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) + + +def get_build_platform(): + """Return this platform's string for platform-specific distributions + + XXX Currently this is the same as ``distutils.util.get_platform()``, but it + needs some hacks for Linux and Mac OS X. + """ + try: + # Python 2.7 or >=3.2 + from sysconfig import get_platform + except ImportError: + from distutils.util import get_platform + + plat = get_platform() + if sys.platform == "darwin" and not plat.startswith('macosx-'): + try: + version = _macosx_vers() + machine = os.uname()[4].replace(" ", "_") + return "macosx-%d.%d-%s" % ( + int(version[0]), int(version[1]), + _macosx_arch(machine), + ) + except ValueError: + # if someone is running a non-Mac darwin system, this will fall + # through to the default implementation + pass + return plat + + +macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") +darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") +# XXX backward compat +get_platform = get_build_platform + + +def compatible_platforms(provided, required): + """Can code for the `provided` platform run on the `required` platform? + + Returns true if either platform is ``None``, or the platforms are equal. + + XXX Needs compatibility checks for Linux and other unixy OSes. + """ + if provided is None or required is None or provided == required: + # easy case + return True + + # Mac OS X special cases + reqMac = macosVersionString.match(required) + if reqMac: + provMac = macosVersionString.match(provided) + + # is this a Mac package? + if not provMac: + # this is backwards compatibility for packages built before + # setuptools 0.6. All packages built after this point will + # use the new macosx designation. + provDarwin = darwinVersionString.match(provided) + if provDarwin: + dversion = int(provDarwin.group(1)) + macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + if dversion == 7 and macosversion >= "10.3" or \ + dversion == 8 and macosversion >= "10.4": + return True + # egg isn't macosx or legacy darwin + return False + + # are they the same major version and machine type? + if provMac.group(1) != reqMac.group(1) or \ + provMac.group(3) != reqMac.group(3): + return False + + # is the required OS major update >= the provided one? + if int(provMac.group(2)) > int(reqMac.group(2)): + return False + + return True + + # XXX Linux and other platforms' special cases should go here + return False + + +def run_script(dist_spec, script_name): + """Locate distribution `dist_spec` and run its `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + require(dist_spec)[0].run_script(script_name, ns) + + +# backward compatibility +run_main = run_script + + +def get_distribution(dist): + """Return a current distribution object for a Requirement or string""" + if isinstance(dist, six.string_types): + dist = Requirement.parse(dist) + if isinstance(dist, Requirement): + dist = get_provider(dist) + if not isinstance(dist, Distribution): + raise TypeError("Expected string, Requirement, or Distribution", dist) + return dist + + +def load_entry_point(dist, group, name): + """Return `name` entry point of `group` for `dist` or raise ImportError""" + return get_distribution(dist).load_entry_point(group, name) + + +def get_entry_map(dist, group=None): + """Return the entry point map for `group`, or the full entry map""" + return get_distribution(dist).get_entry_map(group) + + +def get_entry_info(dist, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return get_distribution(dist).get_entry_info(group, name) + + +class IMetadataProvider: + def has_metadata(name): + """Does the package's distribution contain the named metadata?""" + + def get_metadata(name): + """The named metadata resource as a string""" + + def get_metadata_lines(name): + """Yield named metadata resource as list of non-blank non-comment lines + + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" + + def metadata_isdir(name): + """Is the named metadata a directory? (like ``os.path.isdir()``)""" + + def metadata_listdir(name): + """List of metadata names in the directory (like ``os.listdir()``)""" + + def run_script(script_name, namespace): + """Execute the named script in the supplied namespace dictionary""" + + +class IResourceProvider(IMetadataProvider): + """An object that provides access to package resources""" + + def get_resource_filename(manager, resource_name): + """Return a true filesystem path for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_stream(manager, resource_name): + """Return a readable file-like object for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_string(manager, resource_name): + """Return a string containing the contents of `resource_name` + + `manager` must be an ``IResourceManager``""" + + def has_resource(resource_name): + """Does the package contain the named resource?""" + + def resource_isdir(resource_name): + """Is the named resource a directory? (like ``os.path.isdir()``)""" + + def resource_listdir(resource_name): + """List of resource names in the directory (like ``os.listdir()``)""" + + +class WorkingSet(object): + """A collection of active distributions on sys.path (or a similar list)""" + + def __init__(self, entries=None): + """Create working set from list of path entries (default=sys.path)""" + self.entries = [] + self.entry_keys = {} + self.by_key = {} + self.callbacks = [] + + if entries is None: + entries = sys.path + + for entry in entries: + self.add_entry(entry) + + @classmethod + def _build_master(cls): + """ + Prepare the master working set. + """ + ws = cls() + try: + from __main__ import __requires__ + except ImportError: + # The main program does not list any requirements + return ws + + # ensure the requirements are met + try: + ws.require(__requires__) + except VersionConflict: + return cls._build_from_requirements(__requires__) + + return ws + + @classmethod + def _build_from_requirements(cls, req_spec): + """ + Build a working set from a requirement spec. Rewrites sys.path. + """ + # try it without defaults already on sys.path + # by starting with an empty path + ws = cls([]) + reqs = parse_requirements(req_spec) + dists = ws.resolve(reqs, Environment()) + for dist in dists: + ws.add(dist) + + # add any missing entries from sys.path + for entry in sys.path: + if entry not in ws.entries: + ws.add_entry(entry) + + # then copy back to sys.path + sys.path[:] = ws.entries + return ws + + def add_entry(self, entry): + """Add a path item to ``.entries``, finding any distributions on it + + ``find_distributions(entry, True)`` is used to find distributions + corresponding to the path entry, and they are added. `entry` is + always appended to ``.entries``, even if it is already present. + (This is because ``sys.path`` can contain the same value more than + once, and the ``.entries`` of the ``sys.path`` WorkingSet should always + equal ``sys.path``.) + """ + self.entry_keys.setdefault(entry, []) + self.entries.append(entry) + for dist in find_distributions(entry, True): + self.add(dist, entry, False) + + def __contains__(self, dist): + """True if `dist` is the active distribution for its project""" + return self.by_key.get(dist.key) == dist + + def find(self, req): + """Find a distribution matching requirement `req` + + If there is an active distribution for the requested project, this + returns it as long as it meets the version requirement specified by + `req`. But, if there is an active distribution for the project and it + does *not* meet the `req` requirement, ``VersionConflict`` is raised. + If there is no active distribution for the requested project, ``None`` + is returned. + """ + dist = self.by_key.get(req.key) + if dist is not None and dist not in req: + # XXX add more info + raise VersionConflict(dist, req) + return dist + + def iter_entry_points(self, group, name=None): + """Yield entry point objects from `group` matching `name` + + If `name` is None, yields all entry points in `group` from all + distributions in the working set, otherwise only ones matching + both `group` and `name` are yielded (in distribution order). + """ + for dist in self: + entries = dist.get_entry_map(group) + if name is None: + for ep in entries.values(): + yield ep + elif name in entries: + yield entries[name] + + def run_script(self, requires, script_name): + """Locate distribution for `requires` and run `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + self.require(requires)[0].run_script(script_name, ns) + + def __iter__(self): + """Yield distributions for non-duplicate projects in the working set + + The yield order is the order in which the items' path entries were + added to the working set. + """ + seen = {} + for item in self.entries: + if item not in self.entry_keys: + # workaround a cache issue + continue + + for key in self.entry_keys[item]: + if key not in seen: + seen[key] = 1 + yield self.by_key[key] + + def add(self, dist, entry=None, insert=True, replace=False): + """Add `dist` to working set, associated with `entry` + + If `entry` is unspecified, it defaults to the ``.location`` of `dist`. + On exit from this routine, `entry` is added to the end of the working + set's ``.entries`` (if it wasn't already present). + + `dist` is only added to the working set if it's for a project that + doesn't already have a distribution in the set, unless `replace=True`. + If it's added, any callbacks registered with the ``subscribe()`` method + will be called. + """ + if insert: + dist.insert_on(self.entries, entry, replace=replace) + + if entry is None: + entry = dist.location + keys = self.entry_keys.setdefault(entry, []) + keys2 = self.entry_keys.setdefault(dist.location, []) + if not replace and dist.key in self.by_key: + # ignore hidden distros + return + + self.by_key[dist.key] = dist + if dist.key not in keys: + keys.append(dist.key) + if dist.key not in keys2: + keys2.append(dist.key) + self._added_new(dist) + + def resolve(self, requirements, env=None, installer=None, + replace_conflicting=False, extras=None): + """List all distributions needed to (recursively) meet `requirements` + + `requirements` must be a sequence of ``Requirement`` objects. `env`, + if supplied, should be an ``Environment`` instance. If + not supplied, it defaults to all distributions available within any + entry or distribution in the working set. `installer`, if supplied, + will be invoked with each requirement that cannot be met by an + already-installed distribution; it should return a ``Distribution`` or + ``None``. + + Unless `replace_conflicting=True`, raises a VersionConflict exception + if + any requirements are found on the path that have the correct name but + the wrong version. Otherwise, if an `installer` is supplied it will be + invoked to obtain the correct version of the requirement and activate + it. + + `extras` is a list of the extras to be used with these requirements. + This is important because extra requirements may look like `my_req; + extra = "my_extra"`, which would otherwise be interpreted as a purely + optional requirement. Instead, we want to be able to assert that these + requirements are truly required. + """ + + # set up the stack + requirements = list(requirements)[::-1] + # set of processed requirements + processed = {} + # key -> dist + best = {} + to_activate = [] + + req_extras = _ReqExtras() + + # Mapping of requirement to set of distributions that required it; + # useful for reporting info about conflicts. + required_by = collections.defaultdict(set) + + while requirements: + # process dependencies breadth-first + req = requirements.pop(0) + if req in processed: + # Ignore cyclic or redundant dependencies + continue + + if not req_extras.markers_pass(req, extras): + continue + + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, + replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + + # push the new requirements onto the stack + new_requirements = dist.requires(req.extras)[::-1] + requirements.extend(new_requirements) + + # Register the new requirements needed by req + for new_requirement in new_requirements: + required_by[new_requirement].add(req.project_name) + req_extras[new_requirement] = req.extras + + processed[req] = True + + # return list of distros to activate + return to_activate + + def find_plugins( + self, plugin_env, full_env=None, installer=None, fallback=True): + """Find all activatable distributions in `plugin_env` + + Example usage:: + + distributions, errors = working_set.find_plugins( + Environment(plugin_dirlist) + ) + # add plugins+libs to sys.path + map(working_set.add, distributions) + # display errors + print('Could not load', errors) + + The `plugin_env` should be an ``Environment`` instance that contains + only distributions that are in the project's "plugin directory" or + directories. The `full_env`, if supplied, should be an ``Environment`` + contains all currently-available distributions. If `full_env` is not + supplied, one is created automatically from the ``WorkingSet`` this + method is called on, which will typically mean that every directory on + ``sys.path`` will be scanned for distributions. + + `installer` is a standard installer callback as used by the + ``resolve()`` method. The `fallback` flag indicates whether we should + attempt to resolve older versions of a plugin if the newest version + cannot be resolved. + + This method returns a 2-tuple: (`distributions`, `error_info`), where + `distributions` is a list of the distributions found in `plugin_env` + that were loadable, along with any other distributions that are needed + to resolve their dependencies. `error_info` is a dictionary mapping + unloadable plugin distributions to an exception instance describing the + error that occurred. Usually this will be a ``DistributionNotFound`` or + ``VersionConflict`` instance. + """ + + plugin_projects = list(plugin_env) + # scan project names in alphabetic order + plugin_projects.sort() + + error_info = {} + distributions = {} + + if full_env is None: + env = Environment(self.entries) + env += plugin_env + else: + env = full_env + plugin_env + + shadow_set = self.__class__([]) + # put all our entries in shadow_set + list(map(shadow_set.add, self)) + + for project_name in plugin_projects: + + for dist in plugin_env[project_name]: + + req = [dist.as_requirement()] + + try: + resolvees = shadow_set.resolve(req, env, installer) + + except ResolutionError as v: + # save error info + error_info[dist] = v + if fallback: + # try the next older version of project + continue + else: + # give up on this project, keep going + break + + else: + list(map(shadow_set.add, resolvees)) + distributions.update(dict.fromkeys(resolvees)) + + # success, no need to try any more versions of this project + break + + distributions = list(distributions) + distributions.sort() + + return distributions, error_info + + def require(self, *requirements): + """Ensure that distributions matching `requirements` are activated + + `requirements` must be a string or a (possibly-nested) sequence + thereof, specifying the distributions and versions required. The + return value is a sequence of the distributions that needed to be + activated to fulfill the requirements; all relevant distributions are + included, even if they were already activated in this working set. + """ + needed = self.resolve(parse_requirements(requirements)) + + for dist in needed: + self.add(dist) + + return needed + + def subscribe(self, callback, existing=True): + """Invoke `callback` for all distributions + + If `existing=True` (default), + call on all existing ones, as well. + """ + if callback in self.callbacks: + return + self.callbacks.append(callback) + if not existing: + return + for dist in self: + callback(dist) + + def _added_new(self, dist): + for callback in self.callbacks: + callback(dist) + + def __getstate__(self): + return ( + self.entries[:], self.entry_keys.copy(), self.by_key.copy(), + self.callbacks[:] + ) + + def __setstate__(self, e_k_b_c): + entries, keys, by_key, callbacks = e_k_b_c + self.entries = entries[:] + self.entry_keys = keys.copy() + self.by_key = by_key.copy() + self.callbacks = callbacks[:] + + +class _ReqExtras(dict): + """ + Map each requirement to the extras that demanded it. + """ + + def markers_pass(self, req, extras=None): + """ + Evaluate markers for req against each extra that + demanded it. + + Return False if the req has a marker and fails + evaluation. Otherwise, return True. + """ + extra_evals = ( + req.marker.evaluate({'extra': extra}) + for extra in self.get(req, ()) + (extras or (None,)) + ) + return not req.marker or any(extra_evals) + + +class Environment(object): + """Searchable snapshot of distributions on a search path""" + + def __init__( + self, search_path=None, platform=get_supported_platform(), + python=PY_MAJOR): + """Snapshot distributions available on a search path + + Any distributions found on `search_path` are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. + + `platform` is an optional string specifying the name of the platform + that platform-specific distributions must be compatible with. If + unspecified, it defaults to the current platform. `python` is an + optional string naming the desired version of Python (e.g. ``'3.3'``); + it defaults to the current version. + + You may explicitly set `platform` (and/or `python`) to ``None`` if you + wish to map *all* distributions, not just those compatible with the + running platform or Python version. + """ + self._distmap = {} + self.platform = platform + self.python = python + self.scan(search_path) + + def can_add(self, dist): + """Is distribution `dist` acceptable for this environment? + + The distribution must match the platform and python version + requirements specified when this environment was created, or False + is returned. + """ + py_compat = ( + self.python is None + or dist.py_version is None + or dist.py_version == self.python + ) + return py_compat and compatible_platforms(dist.platform, self.platform) + + def remove(self, dist): + """Remove `dist` from the environment""" + self._distmap[dist.key].remove(dist) + + def scan(self, search_path=None): + """Scan `search_path` for distributions usable in this environment + + Any distributions found are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. Only distributions conforming to + the platform/python version defined at initialization are added. + """ + if search_path is None: + search_path = sys.path + + for item in search_path: + for dist in find_distributions(item): + self.add(dist) + + def __getitem__(self, project_name): + """Return a newest-to-oldest list of distributions for `project_name` + + Uses case-insensitive `project_name` comparison, assuming all the + project's distributions use their project's name converted to all + lowercase as their key. + + """ + distribution_key = project_name.lower() + return self._distmap.get(distribution_key, []) + + def add(self, dist): + """Add `dist` if we ``can_add()`` it and it has not already been added + """ + if self.can_add(dist) and dist.has_version(): + dists = self._distmap.setdefault(dist.key, []) + if dist not in dists: + dists.append(dist) + dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + + def best_match( + self, req, working_set, installer=None, replace_conflicting=False): + """Find distribution best matching `req` and usable on `working_set` + + This calls the ``find(req)`` method of the `working_set` to see if a + suitable distribution is already active. (This may raise + ``VersionConflict`` if an unsuitable version of the project is already + active in the specified `working_set`.) If a suitable distribution + isn't active, this method returns the newest distribution in the + environment that meets the ``Requirement`` in `req`. If no suitable + distribution is found, and `installer` is supplied, then the result of + calling the environment's ``obtain(req, installer)`` method will be + returned. + """ + try: + dist = working_set.find(req) + except VersionConflict: + if not replace_conflicting: + raise + dist = None + if dist is not None: + return dist + for dist in self[req.key]: + if dist in req: + return dist + # try to download/install + return self.obtain(req, installer) + + def obtain(self, requirement, installer=None): + """Obtain a distribution matching `requirement` (e.g. via download) + + Obtain a distro that matches requirement (e.g. via download). In the + base ``Environment`` class, this routine just returns + ``installer(requirement)``, unless `installer` is None, in which case + None is returned instead. This method is a hook that allows subclasses + to attempt other ways of obtaining a distribution before falling back + to the `installer` argument.""" + if installer is not None: + return installer(requirement) + + def __iter__(self): + """Yield the unique project names of the available distributions""" + for key in self._distmap.keys(): + if self[key]: + yield key + + def __iadd__(self, other): + """In-place addition of a distribution or environment""" + if isinstance(other, Distribution): + self.add(other) + elif isinstance(other, Environment): + for project in other: + for dist in other[project]: + self.add(dist) + else: + raise TypeError("Can't add %r to environment" % (other,)) + return self + + def __add__(self, other): + """Add an environment or distribution to an environment""" + new = self.__class__([], platform=None, python=None) + for env in self, other: + new += env + return new + + +# XXX backward compatibility +AvailableDistributions = Environment + + +class ExtractionError(RuntimeError): + """An error occurred extracting a resource + + The following attributes are available from instances of this exception: + + manager + The resource manager that raised this exception + + cache_path + The base directory for resource extraction + + original_error + The exception instance that caused extraction to fail + """ + + +class ResourceManager: + """Manage resource extraction and packages""" + extraction_path = None + + def __init__(self): + self.cached_files = {} + + def resource_exists(self, package_or_requirement, resource_name): + """Does the named resource exist?""" + return get_provider(package_or_requirement).has_resource(resource_name) + + def resource_isdir(self, package_or_requirement, resource_name): + """Is the named resource an existing directory?""" + return get_provider(package_or_requirement).resource_isdir( + resource_name + ) + + def resource_filename(self, package_or_requirement, resource_name): + """Return a true filesystem path for specified resource""" + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name + ) + + def resource_stream(self, package_or_requirement, resource_name): + """Return a readable file-like object for specified resource""" + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name + ) + + def resource_string(self, package_or_requirement, resource_name): + """Return specified resource as a string""" + return get_provider(package_or_requirement).get_resource_string( + self, resource_name + ) + + def resource_listdir(self, package_or_requirement, resource_name): + """List the contents of the named resource directory""" + return get_provider(package_or_requirement).resource_listdir( + resource_name + ) + + def extraction_error(self): + """Give an error message for problems extracting file(s)""" + + old_exc = sys.exc_info()[1] + cache_path = self.extraction_path or get_default_cache() + + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache + + The following error occurred while trying to extract file(s) + to the Python egg cache: + + {old_exc} + + The Python egg cache directory is currently set to: + + {cache_path} + + Perhaps your account does not have write access to this directory? + You can change the cache directory by setting the PYTHON_EGG_CACHE + environment variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl.format(**locals())) + err.manager = self + err.cache_path = cache_path + err.original_error = old_exc + raise err + + def get_cache_path(self, archive_name, names=()): + """Return absolute location in cache for `archive_name` and `names` + + The parent directory of the resulting path will be created if it does + not already exist. `archive_name` should be the base filename of the + enclosing egg (which may not be the name of the enclosing zipfile!), + including its ".egg" extension. `names`, if provided, should be a + sequence of path name parts "under" the egg's extraction location. + + This method should only be called by resource providers that need to + obtain an extraction location, and only for names they intend to + extract, as it tracks the generated names for possible cleanup later. + """ + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name + '-tmp', *names) + try: + _bypass_ensure_directory(target_path) + except Exception: + self.extraction_error() + + self._warn_unsafe_extraction_path(extract_path) + + self.cached_files[target_path] = 1 + return target_path + + @staticmethod + def _warn_unsafe_extraction_path(path): + """ + If the default extraction path is overridden and set to an insecure + location, such as /tmp, it opens up an opportunity for an attacker to + replace an extracted file with an unauthorized payload. Warn the user + if a known insecure location is used. + + See Distribute #375 for more details. + """ + if os.name == 'nt' and not path.startswith(os.environ['windir']): + # On Windows, permissions are generally restrictive by default + # and temp directories are not writable by other users, so + # bypass the warning. + return + mode = os.stat(path).st_mode + if mode & stat.S_IWOTH or mode & stat.S_IWGRP: + msg = ( + "%s is writable by group/others and vulnerable to attack " + "when " + "used with get_resource_filename. Consider a more secure " + "location (set with .set_extraction_path or the " + "PYTHON_EGG_CACHE environment variable)." % path + ) + warnings.warn(msg, UserWarning) + + def postprocess(self, tempname, filename): + """Perform any platform-specific postprocessing of `tempname` + + This is where Mac header rewrites should be done; other platforms don't + have anything special they should do. + + Resource providers should call this method ONLY after successfully + extracting a compressed resource. They must NOT call it on resources + that are already in the filesystem. + + `tempname` is the current (temporary) name of the file, and `filename` + is the name it will be renamed to by the caller after this routine + returns. + """ + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 + os.chmod(tempname, mode) + + def set_extraction_path(self, path): + """Set the base path where resources will be extracted to, if needed. + + If you do not call this routine before any extractions take place, the + path defaults to the return value of ``get_default_cache()``. (Which + is based on the ``PYTHON_EGG_CACHE`` environment variable, with various + platform-specific fallbacks. See that routine's documentation for more + details.) + + Resources are extracted to subdirectories of this path based upon + information given by the ``IResourceProvider``. You may set this to a + temporary directory, but then you must call ``cleanup_resources()`` to + delete the extracted files when done. There is no guarantee that + ``cleanup_resources()`` will be able to remove all extracted files. + + (Note: you may not change the extraction path for a given resource + manager once resources have been extracted, unless you first call + ``cleanup_resources()``.) + """ + if self.cached_files: + raise ValueError( + "Can't change extraction path, files already extracted" + ) + + self.extraction_path = path + + def cleanup_resources(self, force=False): + """ + Delete all extracted resource files and directories, returning a list + of the file and directory names that could not be successfully removed. + This function does not have any concurrency protection, so it should + generally only be called when the extraction path is a temporary + directory exclusive to a single process. This method is not + automatically called; you must call it explicitly or register it as an + ``atexit`` function if you wish to ensure cleanup of a temporary + directory used for extractions. + """ + # XXX + + +def get_default_cache(): + """ + Return the ``PYTHON_EGG_CACHE`` environment variable + or a platform-relevant user cache dir for an app + named "Python-Eggs". + """ + return ( + os.environ.get('PYTHON_EGG_CACHE') + or appdirs.user_cache_dir(appname='Python-Eggs') + ) + + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """ + Convert an arbitrary string to a standard version string + """ + try: + # normalize the version + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: + version = version.replace(' ', '.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def safe_extra(extra): + """Convert an arbitrary string to a standard 'extra' name + + Any runs of non-alphanumeric characters are replaced with a single '_', + and the result is always lowercased. + """ + return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-', '_') + + +def invalid_marker(text): + """ + Validate text as a PEP 508 environment marker; return an exception + if invalid or False otherwise. + """ + try: + evaluate_marker(text) + except SyntaxError as e: + e.filename = None + e.lineno = None + return e + return False + + +def evaluate_marker(text, extra=None): + """ + Evaluate a PEP 508 environment marker. + Return a boolean indicating the marker result in this environment. + Raise SyntaxError if marker is invalid. + + This implementation uses the 'pyparsing' module. + """ + try: + marker = packaging.markers.Marker(text) + return marker.evaluate() + except packaging.markers.InvalidMarker as e: + raise SyntaxError(e) + + +class NullProvider: + """Try to implement resources and metadata for arbitrary PEP 302 loaders""" + + egg_name = None + egg_info = None + loader = None + + def __init__(self, module): + self.loader = getattr(module, '__loader__', None) + self.module_path = os.path.dirname(getattr(module, '__file__', '')) + + def get_resource_filename(self, manager, resource_name): + return self._fn(self.module_path, resource_name) + + def get_resource_stream(self, manager, resource_name): + return io.BytesIO(self.get_resource_string(manager, resource_name)) + + def get_resource_string(self, manager, resource_name): + return self._get(self._fn(self.module_path, resource_name)) + + def has_resource(self, resource_name): + return self._has(self._fn(self.module_path, resource_name)) + + def has_metadata(self, name): + return self.egg_info and self._has(self._fn(self.egg_info, name)) + + def get_metadata(self, name): + if not self.egg_info: + return "" + value = self._get(self._fn(self.egg_info, name)) + return value.decode('utf-8') if six.PY3 else value + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + def resource_isdir(self, resource_name): + return self._isdir(self._fn(self.module_path, resource_name)) + + def metadata_isdir(self, name): + return self.egg_info and self._isdir(self._fn(self.egg_info, name)) + + def resource_listdir(self, resource_name): + return self._listdir(self._fn(self.module_path, resource_name)) + + def metadata_listdir(self, name): + if self.egg_info: + return self._listdir(self._fn(self.egg_info, name)) + return [] + + def run_script(self, script_name, namespace): + script = 'scripts/' + script_name + if not self.has_metadata(script): + raise ResolutionError( + "Script {script!r} not found in metadata at {self.egg_info!r}" + .format(**locals()), + ) + script_text = self.get_metadata(script).replace('\r\n', '\n') + script_text = script_text.replace('\r', '\n') + script_filename = self._fn(self.egg_info, script) + namespace['__file__'] = script_filename + if os.path.exists(script_filename): + source = open(script_filename).read() + code = compile(source, script_filename, 'exec') + exec(code, namespace, namespace) + else: + from linecache import cache + cache[script_filename] = ( + len(script_text), 0, script_text.split('\n'), script_filename + ) + script_code = compile(script_text, script_filename, 'exec') + exec(script_code, namespace, namespace) + + def _has(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _isdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _listdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _fn(self, base, resource_name): + if resource_name: + return os.path.join(base, *resource_name.split('/')) + return base + + def _get(self, path): + if hasattr(self.loader, 'get_data'): + return self.loader.get_data(path) + raise NotImplementedError( + "Can't perform this operation for loaders without 'get_data()'" + ) + + +register_loader_type(object, NullProvider) + + +class EggProvider(NullProvider): + """Provider based on a virtual filesystem""" + + def __init__(self, module): + NullProvider.__init__(self, module) + self._setup_prefix() + + def _setup_prefix(self): + # we assume here that our metadata may be nested inside a "basket" + # of multiple eggs; that's why we use module_path instead of .archive + path = self.module_path + old = None + while path != old: + if _is_egg_path(path): + self.egg_name = os.path.basename(path) + self.egg_info = os.path.join(path, 'EGG-INFO') + self.egg_root = path + break + old = path + path, base = os.path.split(path) + + +class DefaultProvider(EggProvider): + """Provides access to package resources in the filesystem""" + + def _has(self, path): + return os.path.exists(path) + + def _isdir(self, path): + return os.path.isdir(path) + + def _listdir(self, path): + return os.listdir(path) + + def get_resource_stream(self, manager, resource_name): + return open(self._fn(self.module_path, resource_name), 'rb') + + def _get(self, path): + with open(path, 'rb') as stream: + return stream.read() + + @classmethod + def _register(cls): + loader_cls = getattr( + importlib_machinery, + 'SourceFileLoader', + type(None), + ) + register_loader_type(loader_cls, cls) + + +DefaultProvider._register() + + +class EmptyProvider(NullProvider): + """Provider that returns nothing for all requests""" + + module_path = None + + _isdir = _has = lambda self, path: False + + def _get(self, path): + return '' + + def _listdir(self, path): + return [] + + def __init__(self): + pass + + +empty_provider = EmptyProvider() + + +class ZipManifests(dict): + """ + zip manifest builder + """ + + @classmethod + def build(cls, path): + """ + Build a dictionary similar to the zipimport directory + caches, except instead of tuples, store ZipInfo objects. + + Use a platform-specific path separator (os.sep) for the path keys + for compatibility with pypy on Windows. + """ + with zipfile.ZipFile(path) as zfile: + items = ( + ( + name.replace('/', os.sep), + zfile.getinfo(name), + ) + for name in zfile.namelist() + ) + return dict(items) + + load = build + + +class MemoizedZipManifests(ZipManifests): + """ + Memoized zipfile manifests. + """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') + + def load(self, path): + """ + Load a manifest at path or return a suitable manifest already loaded. + """ + path = os.path.normpath(path) + mtime = os.stat(path).st_mtime + + if path not in self or self[path].mtime != mtime: + manifest = self.build(path) + self[path] = self.manifest_mod(manifest, mtime) + + return self[path].manifest + + +class ZipProvider(EggProvider): + """Resource support for zips and eggs""" + + eagers = None + _zip_manifests = MemoizedZipManifests() + + def __init__(self, module): + EggProvider.__init__(self, module) + self.zip_pre = self.loader.archive + os.sep + + def _zipinfo_name(self, fspath): + # Convert a virtual filename (full path to file) into a zipfile subpath + # usable with the zipimport directory cache for our target archive + fspath = fspath.rstrip(os.sep) + if fspath == self.loader.archive: + return '' + if fspath.startswith(self.zip_pre): + return fspath[len(self.zip_pre):] + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.zip_pre) + ) + + def _parts(self, zip_path): + # Convert a zipfile subpath into an egg-relative path part list. + # pseudo-fs path + fspath = self.zip_pre + zip_path + if fspath.startswith(self.egg_root + os.sep): + return fspath[len(self.egg_root) + 1:].split(os.sep) + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.egg_root) + ) + + @property + def zipinfo(self): + return self._zip_manifests.load(self.loader.archive) + + def get_resource_filename(self, manager, resource_name): + if not self.egg_name: + raise NotImplementedError( + "resource_filename() only supported for .egg, not .zip" + ) + # no need to lock for extraction, since we use temp names + zip_path = self._resource_to_zip(resource_name) + eagers = self._get_eager_resources() + if '/'.join(self._parts(zip_path)) in eagers: + for name in eagers: + self._extract_resource(manager, self._eager_to_zip(name)) + return self._extract_resource(manager, zip_path) + + @staticmethod + def _get_date_and_size(zip_stat): + size = zip_stat.file_size + # ymdhms+wday, yday, dst + date_time = zip_stat.date_time + (0, 0, -1) + # 1980 offset already done + timestamp = time.mktime(date_time) + return timestamp, size + + def _extract_resource(self, manager, zip_path): + + if zip_path in self._index(): + for name in self._index()[zip_path]: + last = self._extract_resource( + manager, os.path.join(zip_path, name) + ) + # return the extracted directory name + return os.path.dirname(last) + + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + + if not WRITE_SUPPORT: + raise IOError('"os.rename" and "os.unlink" are not supported ' + 'on this platform') + try: + + real_path = manager.get_cache_path( + self.egg_name, self._parts(zip_path) + ) + + if self._is_current(real_path, zip_path): + return real_path + + outf, tmpnam = _mkstemp( + ".$extract", + dir=os.path.dirname(real_path), + ) + os.write(outf, self.loader.get_data(zip_path)) + os.close(outf) + utime(tmpnam, (timestamp, timestamp)) + manager.postprocess(tmpnam, real_path) + + try: + rename(tmpnam, real_path) + + except os.error: + if os.path.isfile(real_path): + if self._is_current(real_path, zip_path): + # the file became current since it was checked above, + # so proceed. + return real_path + # Windows, del old file and retry + elif os.name == 'nt': + unlink(real_path) + rename(tmpnam, real_path) + return real_path + raise + + except os.error: + # report a user-friendly error + manager.extraction_error() + + return real_path + + def _is_current(self, file_path, zip_path): + """ + Return True if the file_path is current for this zip_path + """ + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + if not os.path.isfile(file_path): + return False + stat = os.stat(file_path) + if stat.st_size != size or stat.st_mtime != timestamp: + return False + # check that the contents match + zip_contents = self.loader.get_data(zip_path) + with open(file_path, 'rb') as f: + file_contents = f.read() + return zip_contents == file_contents + + def _get_eager_resources(self): + if self.eagers is None: + eagers = [] + for name in ('native_libs.txt', 'eager_resources.txt'): + if self.has_metadata(name): + eagers.extend(self.get_metadata_lines(name)) + self.eagers = eagers + return self.eagers + + def _index(self): + try: + return self._dirindex + except AttributeError: + ind = {} + for path in self.zipinfo: + parts = path.split(os.sep) + while parts: + parent = os.sep.join(parts[:-1]) + if parent in ind: + ind[parent].append(parts[-1]) + break + else: + ind[parent] = [parts.pop()] + self._dirindex = ind + return ind + + def _has(self, fspath): + zip_path = self._zipinfo_name(fspath) + return zip_path in self.zipinfo or zip_path in self._index() + + def _isdir(self, fspath): + return self._zipinfo_name(fspath) in self._index() + + def _listdir(self, fspath): + return list(self._index().get(self._zipinfo_name(fspath), ())) + + def _eager_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.egg_root, resource_name)) + + def _resource_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.module_path, resource_name)) + + +register_loader_type(zipimport.zipimporter, ZipProvider) + + +class FileMetadata(EmptyProvider): + """Metadata handler for standalone PKG-INFO files + + Usage:: + + metadata = FileMetadata("/path/to/PKG-INFO") + + This provider rejects all data and metadata requests except for PKG-INFO, + which is treated as existing, and will be the contents of the file at + the provided location. + """ + + def __init__(self, path): + self.path = path + + def has_metadata(self, name): + return name == 'PKG-INFO' and os.path.isfile(self.path) + + def get_metadata(self, name): + if name != 'PKG-INFO': + raise KeyError("No metadata except PKG-INFO is available") + + with io.open(self.path, encoding='utf-8', errors="replace") as f: + metadata = f.read() + self._warn_on_replacement(metadata) + return metadata + + def _warn_on_replacement(self, metadata): + # Python 2.7 compat for: replacement_char = '�' + replacement_char = b'\xef\xbf\xbd'.decode('utf-8') + if replacement_char in metadata: + tmpl = "{self.path} could not be properly decoded in UTF-8" + msg = tmpl.format(**locals()) + warnings.warn(msg) + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + +class PathMetadata(DefaultProvider): + """Metadata provider for egg directories + + Usage:: + + # Development eggs: + + egg_info = "/path/to/PackageName.egg-info" + base_dir = os.path.dirname(egg_info) + metadata = PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + dist = Distribution(basedir, project_name=dist_name, metadata=metadata) + + # Unpacked egg directories: + + egg_path = "/path/to/PackageName-ver-pyver-etc.egg" + metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) + dist = Distribution.from_filename(egg_path, metadata=metadata) + """ + + def __init__(self, path, egg_info): + self.module_path = path + self.egg_info = egg_info + + +class EggMetadata(ZipProvider): + """Metadata provider for .egg files""" + + def __init__(self, importer): + """Create a metadata provider from a zipimporter""" + + self.zip_pre = importer.archive + os.sep + self.loader = importer + if importer.prefix: + self.module_path = os.path.join(importer.archive, importer.prefix) + else: + self.module_path = importer.archive + self._setup_prefix() + + +_declare_state('dict', _distribution_finders={}) + + +def register_finder(importer_type, distribution_finder): + """Register `distribution_finder` to find distributions in sys.path items + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `distribution_finder` is a callable that, passed a path + item and the importer instance, yields ``Distribution`` instances found on + that path item. See ``pkg_resources.find_on_path`` for an example.""" + _distribution_finders[importer_type] = distribution_finder + + +def find_distributions(path_item, only=False): + """Yield distributions accessible via `path_item`""" + importer = get_importer(path_item) + finder = _find_adapter(_distribution_finders, importer) + return finder(importer, path_item, only) + + +def find_eggs_in_zip(importer, path_item, only=False): + """ + Find eggs in zip files; possibly multiple nested eggs. + """ + if importer.archive.endswith('.whl'): + # wheels are not supported with this finder + # they don't have PKG-INFO metadata, and won't ever contain eggs + return + metadata = EggMetadata(importer) + if metadata.has_metadata('PKG-INFO'): + yield Distribution.from_filename(path_item, metadata=metadata) + if only: + # don't yield nested distros + return + for subitem in metadata.resource_listdir('/'): + if _is_egg_path(subitem): + subpath = os.path.join(path_item, subitem) + dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) + for dist in dists: + yield dist + elif subitem.lower().endswith('.dist-info'): + subpath = os.path.join(path_item, subitem) + submeta = EggMetadata(zipimport.zipimporter(subpath)) + submeta.egg_info = subpath + yield Distribution.from_location(path_item, subitem, submeta) + + +register_finder(zipimport.zipimporter, find_eggs_in_zip) + + +def find_nothing(importer, path_item, only=False): + return () + + +register_finder(object, find_nothing) + + +def _by_version_descending(names): + """ + Given a list of filenames, return them in descending order + by version number. + + >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' + >>> _by_version_descending(names) + ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] + """ + def _by_version(name): + """ + Parse each component of the filename + """ + name, ext = os.path.splitext(name) + parts = itertools.chain(name.split('-'), [ext]) + return [packaging.version.parse(part) for part in parts] + + return sorted(names, key=_by_version, reverse=True) + + +def find_on_path(importer, path_item, only=False): + """Yield distributions accessible on a sys.path directory""" + path_item = _normalize_cached(path_item) + + if _is_unpacked_egg(path_item): + yield Distribution.from_filename( + path_item, metadata=PathMetadata( + path_item, os.path.join(path_item, 'EGG-INFO') + ) + ) + return + + entries = safe_listdir(path_item) + + # for performance, before sorting by version, + # screen entries for only those that will yield + # distributions + filtered = ( + entry + for entry in entries + if dist_factory(path_item, entry, only) + ) + + # scan for .egg and .egg-info in directory + path_item_entries = _by_version_descending(filtered) + for entry in path_item_entries: + fullpath = os.path.join(path_item, entry) + factory = dist_factory(path_item, entry, only) + for dist in factory(fullpath): + yield dist + + +def dist_factory(path_item, entry, only): + """ + Return a dist_factory for a path_item and entry + """ + lower = entry.lower() + is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + return ( + distributions_from_metadata + if is_meta else + find_distributions + if not only and _is_egg_path(entry) else + resolve_egg_link + if not only and lower.endswith('.egg-link') else + NoDists() + ) + + +class NoDists: + """ + >>> bool(NoDists()) + False + + >>> list(NoDists()('anything')) + [] + """ + def __bool__(self): + return False + if six.PY2: + __nonzero__ = __bool__ + + def __call__(self, fullpath): + return iter(()) + + +def safe_listdir(path): + """ + Attempt to list contents of path, but suppress some exceptions. + """ + try: + return os.listdir(path) + except (PermissionError, NotADirectoryError): + pass + except OSError as e: + # Ignore the directory if does not exist, not a directory or + # permission denied + ignorable = ( + e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) + # Python 2 on Windows needs to be handled this way :( + or getattr(e, "winerror", None) == 267 + ) + if not ignorable: + raise + return () + + +def distributions_from_metadata(path): + root = os.path.dirname(path) + if os.path.isdir(path): + if len(os.listdir(path)) == 0: + # empty metadata dir; skip + return + metadata = PathMetadata(root, path) + else: + metadata = FileMetadata(path) + entry = os.path.basename(path) + yield Distribution.from_location( + root, entry, metadata, precedence=DEVELOP_DIST, + ) + + +def non_empty_lines(path): + """ + Yield non-empty lines from file at path + """ + with open(path) as f: + for line in f: + line = line.strip() + if line: + yield line + + +def resolve_egg_link(path): + """ + Given a path to an .egg-link, resolve distributions + present in the referenced path. + """ + referenced_paths = non_empty_lines(path) + resolved_paths = ( + os.path.join(os.path.dirname(path), ref) + for ref in referenced_paths + ) + dist_groups = map(find_distributions, resolved_paths) + return next(dist_groups, ()) + + +register_finder(pkgutil.ImpImporter, find_on_path) + +if hasattr(importlib_machinery, 'FileFinder'): + register_finder(importlib_machinery.FileFinder, find_on_path) + +_declare_state('dict', _namespace_handlers={}) +_declare_state('dict', _namespace_packages={}) + + +def register_namespace_handler(importer_type, namespace_handler): + """Register `namespace_handler` to declare namespace packages + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `namespace_handler` is a callable like this:: + + def namespace_handler(importer, path_entry, moduleName, module): + # return a path_entry to use for child packages + + Namespace handlers are only called if the importer object has already + agreed that it can handle the relevant path item, and they should only + return a subpath if the module __path__ does not already contain an + equivalent subpath. For an example namespace handler, see + ``pkg_resources.file_ns_handler``. + """ + _namespace_handlers[importer_type] = namespace_handler + + +def _handle_ns(packageName, path_item): + """Ensure that named package includes a subpath of path_item (if needed)""" + + importer = get_importer(path_item) + if importer is None: + return None + loader = importer.find_module(packageName) + if loader is None: + return None + module = sys.modules.get(packageName) + if module is None: + module = sys.modules[packageName] = types.ModuleType(packageName) + module.__path__ = [] + _set_parent_ns(packageName) + elif not hasattr(module, '__path__'): + raise TypeError("Not a package:", packageName) + handler = _find_adapter(_namespace_handlers, importer) + subpath = handler(importer, path_item, packageName, module) + if subpath is not None: + path = module.__path__ + path.append(subpath) + loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath + + +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path = [_normalize_cached(p) for p in sys.path] + + def safe_sys_path_index(entry): + """ + Workaround for #520 and #513. + """ + try: + return sys_path.index(entry) + except ValueError: + return float('inf') + + def position_in_sys_path(path): + """ + Return the ordinal of the path based on its position in sys.path + """ + path_parts = path.split(os.sep) + module_parts = package_name.count('.') + 1 + parts = path_parts[:-module_parts] + return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) + + if not isinstance(orig_path, list): + # Is this behavior useful when module.__path__ is not a list? + return + + orig_path.sort(key=position_in_sys_path) + module.__path__[:] = [_normalize_cached(p) for p in orig_path] + + +def declare_namespace(packageName): + """Declare that package 'packageName' is a namespace package""" + + _imp.acquire_lock() + try: + if packageName in _namespace_packages: + return + + path, parent = sys.path, None + if '.' in packageName: + parent = '.'.join(packageName.split('.')[:-1]) + declare_namespace(parent) + if parent not in _namespace_packages: + __import__(parent) + try: + path = sys.modules[parent].__path__ + except AttributeError: + raise TypeError("Not a package:", parent) + + # Track what packages are namespaces, so when new path items are added, + # they can be updated + _namespace_packages.setdefault(parent, []).append(packageName) + _namespace_packages.setdefault(packageName, []) + + for path_item in path: + # Ensure all the parent's path items are reflected in the child, + # if they apply + _handle_ns(packageName, path_item) + + finally: + _imp.release_lock() + + +def fixup_namespace_packages(path_item, parent=None): + """Ensure that previously-declared namespace packages include path_item""" + _imp.acquire_lock() + try: + for package in _namespace_packages.get(parent, ()): + subpath = _handle_ns(package, path_item) + if subpath: + fixup_namespace_packages(subpath, package) + finally: + _imp.release_lock() + + +def file_ns_handler(importer, path_item, packageName, module): + """Compute an ns-package subpath for a filesystem or zipfile importer""" + + subpath = os.path.join(path_item, packageName.split('.')[-1]) + normalized = _normalize_cached(subpath) + for item in module.__path__: + if _normalize_cached(item) == normalized: + break + else: + # Only return the path if it's not already there + return subpath + + +register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) + +if hasattr(importlib_machinery, 'FileFinder'): + register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) + + +def null_ns_handler(importer, path_item, packageName, module): + return None + + +register_namespace_handler(object, null_ns_handler) + + +def normalize_path(filename): + """Normalize a file/dir name for comparison purposes""" + return os.path.normcase(os.path.realpath(filename)) + + +def _normalize_cached(filename, _cache={}): + try: + return _cache[filename] + except KeyError: + _cache[filename] = result = normalize_path(filename) + return result + + +def _is_egg_path(path): + """ + Determine if given path appears to be an egg. + """ + return path.lower().endswith('.egg') + + +def _is_unpacked_egg(path): + """ + Determine if given path appears to be an unpacked egg. + """ + return ( + _is_egg_path(path) and + os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + ) + + +def _set_parent_ns(packageName): + parts = packageName.split('.') + name = parts.pop() + if parts: + parent = '.'.join(parts) + setattr(sys.modules[parent], name, sys.modules[packageName]) + + +def yield_lines(strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + +MODULE = re.compile(r"\w+(\.\w+)*$").match +EGG_NAME = re.compile( + r""" + (?P<name>[^-]+) ( + -(?P<ver>[^-]+) ( + -py(?P<pyver>[^-]+) ( + -(?P<plat>.+) + )? + )? + )? + """, + re.VERBOSE | re.IGNORECASE, +).match + + +class EntryPoint(object): + """Object representing an advertised importable object""" + + def __init__(self, name, module_name, attrs=(), extras=(), dist=None): + if not MODULE(module_name): + raise ValueError("Invalid module name", module_name) + self.name = name + self.module_name = module_name + self.attrs = tuple(attrs) + self.extras = tuple(extras) + self.dist = dist + + def __str__(self): + s = "%s = %s" % (self.name, self.module_name) + if self.attrs: + s += ':' + '.'.join(self.attrs) + if self.extras: + s += ' [%s]' % ','.join(self.extras) + return s + + def __repr__(self): + return "EntryPoint.parse(%r)" % str(self) + + def load(self, require=True, *args, **kwargs): + """ + Require packages for this EntryPoint, then resolve it. + """ + if not require or args or kwargs: + warnings.warn( + "Parameters to load are deprecated. Call .resolve and " + ".require separately.", + DeprecationWarning, + stacklevel=2, + ) + if require: + self.require(*args, **kwargs) + return self.resolve() + + def resolve(self): + """ + Resolve the entry point from its module and attrs. + """ + module = __import__(self.module_name, fromlist=['__name__'], level=0) + try: + return functools.reduce(getattr, self.attrs, module) + except AttributeError as exc: + raise ImportError(str(exc)) + + def require(self, env=None, installer=None): + if self.extras and not self.dist: + raise UnknownExtra("Can't require() without a distribution", self) + + # Get the requirements for this entry point with all its extras and + # then resolve them. We have to pass `extras` along when resolving so + # that the working set knows what extras we want. Otherwise, for + # dist-info distributions, the working set will assume that the + # requirements for that extra are purely optional and skip over them. + reqs = self.dist.requires(self.extras) + items = working_set.resolve(reqs, env, installer, extras=self.extras) + list(map(working_set.add, items)) + + pattern = re.compile( + r'\s*' + r'(?P<name>.+?)\s*' + r'=\s*' + r'(?P<module>[\w.]+)\s*' + r'(:\s*(?P<attr>[\w.]+))?\s*' + r'(?P<extras>\[.*\])?\s*$' + ) + + @classmethod + def parse(cls, src, dist=None): + """Parse a single entry point from string `src` + + Entry point syntax follows the form:: + + name = some.module:some.attr [extra1, extra2] + + The entry name and module name are required, but the ``:attrs`` and + ``[extras]`` parts are optional + """ + m = cls.pattern.match(src) + if not m: + msg = "EntryPoint must be in 'name=module:attrs [extras]' format" + raise ValueError(msg, src) + res = m.groupdict() + extras = cls._parse_extras(res['extras']) + attrs = res['attr'].split('.') if res['attr'] else () + return cls(res['name'], res['module'], attrs, extras, dist) + + @classmethod + def _parse_extras(cls, extras_spec): + if not extras_spec: + return () + req = Requirement.parse('x' + extras_spec) + if req.specs: + raise ValueError() + return req.extras + + @classmethod + def parse_group(cls, group, lines, dist=None): + """Parse an entry point group""" + if not MODULE(group): + raise ValueError("Invalid group name", group) + this = {} + for line in yield_lines(lines): + ep = cls.parse(line, dist) + if ep.name in this: + raise ValueError("Duplicate entry point", group, ep.name) + this[ep.name] = ep + return this + + @classmethod + def parse_map(cls, data, dist=None): + """Parse a map of entry point groups""" + if isinstance(data, dict): + data = data.items() + else: + data = split_sections(data) + maps = {} + for group, lines in data: + if group is None: + if not lines: + continue + raise ValueError("Entry points must be listed in groups") + group = group.strip() + if group in maps: + raise ValueError("Duplicate group name", group) + maps[group] = cls.parse_group(group, lines, dist) + return maps + + +def _remove_md5_fragment(location): + if not location: + return '' + parsed = urllib.parse.urlparse(location) + if parsed[-1].startswith('md5='): + return urllib.parse.urlunparse(parsed[:-1] + ('',)) + return location + + +def _version_from_file(lines): + """ + Given an iterable of lines from a Metadata file, return + the value of the Version field, if present, or None otherwise. + """ + def is_version_line(line): + return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) + line = next(iter(version_lines), '') + _, _, value = line.partition(':') + return safe_version(value.strip()) or None + + +class Distribution(object): + """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' + + def __init__( + self, location=None, metadata=None, project_name=None, + version=None, py_version=PY_MAJOR, platform=None, + precedence=EGG_DIST): + self.project_name = safe_name(project_name or 'Unknown') + if version is not None: + self._version = safe_version(version) + self.py_version = py_version + self.platform = platform + self.location = location + self.precedence = precedence + self._provider = metadata or empty_provider + + @classmethod + def from_location(cls, location, basename, metadata=None, **kw): + project_name, version, py_version, platform = [None] * 4 + basename, ext = os.path.splitext(basename) + if ext.lower() in _distributionImpl: + cls = _distributionImpl[ext.lower()] + + match = EGG_NAME(basename) + if match: + project_name, version, py_version, platform = match.group( + 'name', 'ver', 'pyver', 'plat' + ) + return cls( + location, metadata, project_name=project_name, version=version, + py_version=py_version, platform=platform, **kw + )._reload_version() + + def _reload_version(self): + return self + + @property + def hashcmp(self): + return ( + self.parsed_version, + self.precedence, + self.key, + _remove_md5_fragment(self.location), + self.py_version or '', + self.platform or '', + ) + + def __hash__(self): + return hash(self.hashcmp) + + def __lt__(self, other): + return self.hashcmp < other.hashcmp + + def __le__(self, other): + return self.hashcmp <= other.hashcmp + + def __gt__(self, other): + return self.hashcmp > other.hashcmp + + def __ge__(self, other): + return self.hashcmp >= other.hashcmp + + def __eq__(self, other): + if not isinstance(other, self.__class__): + # It's not a Distribution, so they are not equal + return False + return self.hashcmp == other.hashcmp + + def __ne__(self, other): + return not self == other + + # These properties have to be lazy so that we don't have to load any + # metadata until/unless it's actually needed. (i.e., some distributions + # may not know their name or version without loading PKG-INFO) + + @property + def key(self): + try: + return self._key + except AttributeError: + self._key = key = self.project_name.lower() + return key + + @property + def parsed_version(self): + if not hasattr(self, "_parsed_version"): + self._parsed_version = parse_version(self.version) + + return self._parsed_version + + def _warn_legacy_version(self): + LV = packaging.version.LegacyVersion + is_legacy = isinstance(self._parsed_version, LV) + if not is_legacy: + return + + # While an empty version is technically a legacy version and + # is not a valid PEP 440 version, it's also unlikely to + # actually come from someone and instead it is more likely that + # it comes from setuptools attempting to parse a filename and + # including it in the list. So for that we'll gate this warning + # on if the version is anything at all or not. + if not self.version: + return + + tmpl = textwrap.dedent(""" + '{project_name} ({version})' is being parsed as a legacy, + non PEP 440, + version. You may find odd behavior and sort order. + In particular it will be sorted as less than 0.0. It + is recommended to migrate to PEP 440 compatible + versions. + """).strip().replace('\n', ' ') + + warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + + @property + def version(self): + try: + return self._version + except AttributeError: + version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if version is None: + tmpl = "Missing 'Version:' header and/or %s file" + raise ValueError(tmpl % self.PKG_INFO, self) + return version + + @property + def _dep_map(self): + """ + A map of extra to its list of (direct) requirements + for this distribution, including the null extra. + """ + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._filter_extras(self._build_dep_map()) + return self.__dep_map + + @staticmethod + def _filter_extras(dm): + """ + Given a mapping of extras to dependencies, strip off + environment markers and filter out any dependencies + not matching the markers. + """ + for extra in list(filter(None, dm)): + new_extra = extra + reqs = dm.pop(extra) + new_extra, _, marker = extra.partition(':') + fails_marker = marker and ( + invalid_marker(marker) + or not evaluate_marker(marker) + ) + if fails_marker: + reqs = [] + new_extra = safe_extra(new_extra) or None + + dm.setdefault(new_extra, []).extend(reqs) + return dm + + def _build_dep_map(self): + dm = {} + for name in 'requires.txt', 'depends.txt': + for extra, reqs in split_sections(self._get_metadata(name)): + dm.setdefault(extra, []).extend(parse_requirements(reqs)) + return dm + + def requires(self, extras=()): + """List of Requirements needed for this distro if `extras` are used""" + dm = self._dep_map + deps = [] + deps.extend(dm.get(None, ())) + for ext in extras: + try: + deps.extend(dm[safe_extra(ext)]) + except KeyError: + raise UnknownExtra( + "%s has no such extra feature %r" % (self, ext) + ) + return deps + + def _get_metadata(self, name): + if self.has_metadata(name): + for line in self.get_metadata_lines(name): + yield line + + def activate(self, path=None, replace=False): + """Ensure distribution is importable on `path` (default=sys.path)""" + if path is None: + path = sys.path + self.insert_on(path, replace=replace) + if path is sys.path: + fixup_namespace_packages(self.location) + for pkg in self._get_metadata('namespace_packages.txt'): + if pkg in sys.modules: + declare_namespace(pkg) + + def egg_name(self): + """Return what this distribution's standard .egg filename should be""" + filename = "%s-%s-py%s" % ( + to_filename(self.project_name), to_filename(self.version), + self.py_version or PY_MAJOR + ) + + if self.platform: + filename += '-' + self.platform + return filename + + def __repr__(self): + if self.location: + return "%s (%s)" % (self, self.location) + else: + return str(self) + + def __str__(self): + try: + version = getattr(self, 'version', None) + except ValueError: + version = None + version = version or "[unknown version]" + return "%s %s" % (self.project_name, version) + + def __getattr__(self, attr): + """Delegate all unrecognized public attributes to .metadata provider""" + if attr.startswith('_'): + raise AttributeError(attr) + return getattr(self._provider, attr) + + @classmethod + def from_filename(cls, filename, metadata=None, **kw): + return cls.from_location( + _normalize_cached(filename), os.path.basename(filename), metadata, + **kw + ) + + def as_requirement(self): + """Return a ``Requirement`` that matches this distribution exactly""" + if isinstance(self.parsed_version, packaging.version.Version): + spec = "%s==%s" % (self.project_name, self.parsed_version) + else: + spec = "%s===%s" % (self.project_name, self.parsed_version) + + return Requirement.parse(spec) + + def load_entry_point(self, group, name): + """Return the `name` entry point of `group` or raise ImportError""" + ep = self.get_entry_info(group, name) + if ep is None: + raise ImportError("Entry point %r not found" % ((group, name),)) + return ep.load() + + def get_entry_map(self, group=None): + """Return the entry point map for `group`, or the full entry map""" + try: + ep_map = self._ep_map + except AttributeError: + ep_map = self._ep_map = EntryPoint.parse_map( + self._get_metadata('entry_points.txt'), self + ) + if group is not None: + return ep_map.get(group, {}) + return ep_map + + def get_entry_info(self, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return self.get_entry_map(group).get(name) + + def insert_on(self, path, loc=None, replace=False): + """Ensure self.location is on path + + If replace=False (default): + - If location is already in path anywhere, do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent. + - Else: add to the end of path. + If replace=True: + - If location is already on path anywhere (not eggs) + or higher priority than its parent (eggs) + do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent, + removing any lower-priority entries. + - Else: add it to the front of path. + """ + + loc = loc or self.location + if not loc: + return + + nloc = _normalize_cached(loc) + bdir = os.path.dirname(nloc) + npath = [(p and _normalize_cached(p) or p) for p in path] + + for p, item in enumerate(npath): + if item == nloc: + if replace: + break + else: + # don't modify path (even removing duplicates) if + # found and not replace + return + elif item == bdir and self.precedence == EGG_DIST: + # if it's an .egg, give it precedence over its directory + # UNLESS it's already been added to sys.path and replace=False + if (not replace) and nloc in npath[p:]: + return + if path is sys.path: + self.check_version_conflict() + path.insert(p, loc) + npath.insert(p, nloc) + break + else: + if path is sys.path: + self.check_version_conflict() + if replace: + path.insert(0, loc) + else: + path.append(loc) + return + + # p is the spot where we found or inserted loc; now remove duplicates + while True: + try: + np = npath.index(nloc, p + 1) + except ValueError: + break + else: + del npath[np], path[np] + # ha! + p = np + + return + + def check_version_conflict(self): + if self.key == 'setuptools': + # ignore the inevitable setuptools self-conflicts :( + return + + nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) + loc = normalize_path(self.location) + for modname in self._get_metadata('top_level.txt'): + if (modname not in sys.modules or modname in nsp + or modname in _namespace_packages): + continue + if modname in ('pkg_resources', 'setuptools', 'site'): + continue + fn = getattr(sys.modules[modname], '__file__', None) + if fn and (normalize_path(fn).startswith(loc) or + fn.startswith(self.location)): + continue + issue_warning( + "Module %s was already imported from %s, but %s is being added" + " to sys.path" % (modname, fn, self.location), + ) + + def has_version(self): + try: + self.version + except ValueError: + issue_warning("Unbuilt egg for " + repr(self)) + return False + return True + + def clone(self, **kw): + """Copy this distribution, substituting in any changed keyword args""" + names = 'project_name version py_version platform location precedence' + for attr in names.split(): + kw.setdefault(attr, getattr(self, attr, None)) + kw.setdefault('metadata', self._provider) + return self.__class__(**kw) + + @property + def extras(self): + return [dep for dep in self._dep_map if dep] + + +class EggInfoDistribution(Distribution): + def _reload_version(self): + """ + Packages installed by distutils (e.g. numpy or scipy), + which uses an old safe_version, and so + their version numbers can get mangled when + converted to filenames (e.g., 1.11.0.dev0+2329eae to + 1.11.0.dev0_2329eae). These distributions will not be + parsed properly + downstream by Distribution and safe_version, so + take an extra step and try to get the version number from + the metadata file itself instead of the filename. + """ + md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if md_version: + self._version = md_version + return self + + +class DistInfoDistribution(Distribution): + """ + Wrap an actual or potential sys.path entry + w/metadata, .dist-info style. + """ + PKG_INFO = 'METADATA' + EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") + + @property + def _parsed_pkg_info(self): + """Parse and cache metadata""" + try: + return self._pkg_info + except AttributeError: + metadata = self.get_metadata(self.PKG_INFO) + self._pkg_info = email.parser.Parser().parsestr(metadata) + return self._pkg_info + + @property + def _dep_map(self): + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._compute_dependencies() + return self.__dep_map + + def _compute_dependencies(self): + """Recompute this distribution's dependencies.""" + dm = self.__dep_map = {None: []} + + reqs = [] + # Including any condition expressions + for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: + reqs.extend(parse_requirements(req)) + + def reqs_for_extra(extra): + for req in reqs: + if not req.marker or req.marker.evaluate({'extra': extra}): + yield req + + common = frozenset(reqs_for_extra(None)) + dm[None].extend(common) + + for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: + s_extra = safe_extra(extra.strip()) + dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + + return dm + + +_distributionImpl = { + '.egg': Distribution, + '.egg-info': EggInfoDistribution, + '.dist-info': DistInfoDistribution, +} + + +def issue_warning(*args, **kw): + level = 1 + g = globals() + try: + # find the first stack frame that is *not* code in + # the pkg_resources module, to use for the warning + while sys._getframe(level).f_globals is g: + level += 1 + except ValueError: + pass + warnings.warn(stacklevel=level + 1, *args, **kw) + + +class RequirementParseError(ValueError): + def __str__(self): + return ' '.join(self.args) + + +def parse_requirements(strs): + """Yield ``Requirement`` objects for each specification in `strs` + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(yield_lines(strs)) + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + yield Requirement(line) + + +class Requirement(packaging.requirements.Requirement): + def __init__(self, requirement_string): + """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" + try: + super(Requirement, self).__init__(requirement_string) + except packaging.requirements.InvalidRequirement as e: + raise RequirementParseError(str(e)) + self.unsafe_name = self.name + project_name = safe_name(self.name) + self.project_name, self.key = project_name, project_name.lower() + self.specs = [ + (spec.operator, spec.version) for spec in self.specifier] + self.extras = tuple(map(safe_extra, self.extras)) + self.hashCmp = ( + self.key, + self.specifier, + frozenset(self.extras), + str(self.marker) if self.marker else None, + ) + self.__hash = hash(self.hashCmp) + + def __eq__(self, other): + return ( + isinstance(other, Requirement) and + self.hashCmp == other.hashCmp + ) + + def __ne__(self, other): + return not self == other + + def __contains__(self, item): + if isinstance(item, Distribution): + if item.key != self.key: + return False + + item = item.version + + # Allow prereleases always in order to match the previous behavior of + # this method. In the future this should be smarter and follow PEP 440 + # more accurately. + return self.specifier.contains(item, prereleases=True) + + def __hash__(self): + return self.__hash + + def __repr__(self): + return "Requirement.parse(%r)" % str(self) + + @staticmethod + def parse(s): + req, = parse_requirements(s) + return req + + +def _always_object(classes): + """ + Ensure object appears in the mro even + for old-style classes. + """ + if object not in classes: + return classes + (object,) + return classes + + +def _find_adapter(registry, ob): + """Return an adapter factory for `ob` from `registry`""" + types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) + for t in types: + if t in registry: + return registry[t] + + +def ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + py31compat.makedirs(dirname, exist_ok=True) + + +def _bypass_ensure_directory(path): + """Sandbox-bypassing version of ensure_directory()""" + if not WRITE_SUPPORT: + raise IOError('"os.mkdir" not supported on this platform.') + dirname, filename = split(path) + if dirname and filename and not isdir(dirname): + _bypass_ensure_directory(dirname) + mkdir(dirname, 0o755) + + +def split_sections(s): + """Split a string or iterable thereof into (section, content) pairs + + Each ``section`` is a stripped version of the section header ("[section]") + and each ``content`` is a list of stripped lines excluding blank lines and + comment-only lines. If there are any such lines before the first section + header, they're returned in a first ``section`` of ``None``. + """ + section = None + content = [] + for line in yield_lines(s): + if line.startswith("["): + if line.endswith("]"): + if section or content: + yield section, content + section = line[1:-1].strip() + content = [] + else: + raise ValueError("Invalid section heading", line) + else: + content.append(line) + + # wrap up last segment + yield section, content + + +def _mkstemp(*args, **kw): + old_open = os.open + try: + # temporarily bypass sandboxing + os.open = os_open + return tempfile.mkstemp(*args, **kw) + finally: + # and then put it back + os.open = old_open + + +# Silence the PEP440Warning by default, so that end users don't get hit by it +# randomly just because they use pkg_resources. We want to append the rule +# because we want earlier uses of filterwarnings to take precedence over this +# one. +warnings.filterwarnings("ignore", category=PEP440Warning, append=True) + + +# from jaraco.functools 1.3 +def _call_aside(f, *args, **kwargs): + f(*args, **kwargs) + return f + + +@_call_aside +def _initialize(g=globals()): + "Set up global resource manager (deliberately not state-saved)" + manager = ResourceManager() + g['_manager'] = manager + g.update( + (name, getattr(manager, name)) + for name in dir(manager) + if not name.startswith('_') + ) + + +@_call_aside +def _initialize_master_working_set(): + """ + Prepare the master working set and make the ``require()`` + API available. + + This function has explicit effects on the global state + of pkg_resources. It is intended to be invoked once at + the initialization of this module. + + Invocation by other packages is unsupported and done + at their own risk. + """ + working_set = WorkingSet._build_master() + _declare_state('object', working_set=working_set) + + require = working_set.require + iter_entry_points = working_set.iter_entry_points + add_activation_listener = working_set.subscribe + run_script = working_set.run_script + # backward compatibility + run_main = run_script + # Activate all distributions already on sys.path with replace=False and + # ensure that all distributions added to the working set in the future + # (e.g. by calling ``require()``) will get activated as well, + # with higher priority (replace=True). + tuple( + dist.activate(replace=False) + for dist in working_set + ) + add_activation_listener( + lambda dist: dist.activate(replace=True), + existing=False, + ) + working_set.entries = [] + # match order + list(map(working_set.add_entry, sys.path)) + globals().update(locals()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..0b555d5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc new file mode 100644 index 0000000..808e050 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py new file mode 100644 index 0000000..331a51b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pkg_resources/py31compat.py @@ -0,0 +1,22 @@ +import os +import errno +import sys + + +def _makedirs_31(path, exist_ok=False): + try: + os.makedirs(path) + except OSError as exc: + if not exist_ok or exc.errno != errno.EEXIST: + raise + + +# rely on compatibility behavior until mode considerations +# and exists_ok considerations are disentangled. +# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 +needs_makedirs = ( + sys.version_info < (3, 2, 5) or + (3, 3) <= sys.version_info < (3, 3, 6) or + (3, 4) <= sys.version_info < (3, 4, 1) +) +makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__init__.py new file mode 100644 index 0000000..09dfc1e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__init__.py @@ -0,0 +1,127 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import division + +from collections import deque +from datetime import timedelta +from math import ceil +from sys import stderr +from time import time + + +__version__ = '1.3' + + +class Infinite(object): + file = stderr + sma_window = 10 # Simple Moving Average window + + def __init__(self, *args, **kwargs): + self.index = 0 + self.start_ts = time() + self.avg = 0 + self._ts = self.start_ts + self._xput = deque(maxlen=self.sma_window) + for key, val in kwargs.items(): + setattr(self, key, val) + + def __getitem__(self, key): + if key.startswith('_'): + return None + return getattr(self, key, None) + + @property + def elapsed(self): + return int(time() - self.start_ts) + + @property + def elapsed_td(self): + return timedelta(seconds=self.elapsed) + + def update_avg(self, n, dt): + if n > 0: + self._xput.append(dt / n) + self.avg = sum(self._xput) / len(self._xput) + + def update(self): + pass + + def start(self): + pass + + def finish(self): + pass + + def next(self, n=1): + now = time() + dt = now - self._ts + self.update_avg(n, dt) + self._ts = now + self.index = self.index + n + self.update() + + def iter(self, it): + try: + for x in it: + yield x + self.next() + finally: + self.finish() + + +class Progress(Infinite): + def __init__(self, *args, **kwargs): + super(Progress, self).__init__(*args, **kwargs) + self.max = kwargs.get('max', 100) + + @property + def eta(self): + return int(ceil(self.avg * self.remaining)) + + @property + def eta_td(self): + return timedelta(seconds=self.eta) + + @property + def percent(self): + return self.progress * 100 + + @property + def progress(self): + return min(1, self.index / self.max) + + @property + def remaining(self): + return max(self.max - self.index, 0) + + def start(self): + self.update() + + def goto(self, index): + incr = index - self.index + self.next(incr) + + def iter(self, it): + try: + self.max = len(it) + except TypeError: + pass + + try: + for x in it: + yield x + self.next() + finally: + self.finish() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..bb2d38a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc new file mode 100644 index 0000000..2ffb7bc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000..9b93572 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc new file mode 100644 index 0000000..487ba41 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/bar.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/bar.py new file mode 100644 index 0000000..5ee968f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/bar.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Progress +from .helpers import WritelnMixin + + +class Bar(WritelnMixin, Progress): + width = 32 + message = '' + suffix = '%(index)d/%(max)d' + bar_prefix = ' |' + bar_suffix = '| ' + empty_fill = ' ' + fill = '#' + hide_cursor = True + + def update(self): + filled_length = int(self.width * self.progress) + empty_length = self.width - filled_length + + message = self.message % self + bar = self.fill * filled_length + empty = self.empty_fill * empty_length + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, + suffix]) + self.writeln(line) + + +class ChargingBar(Bar): + suffix = '%(percent)d%%' + bar_prefix = ' ' + bar_suffix = ' ' + empty_fill = '∙' + fill = '█' + + +class FillingSquaresBar(ChargingBar): + empty_fill = '▢' + fill = '▣' + + +class FillingCirclesBar(ChargingBar): + empty_fill = '◯' + fill = '◉' + + +class IncrementalBar(Bar): + phases = (' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█') + + def update(self): + nphases = len(self.phases) + filled_len = self.width * self.progress + nfull = int(filled_len) # Number of full chars + phase = int((filled_len - nfull) * nphases) # Phase of last char + nempty = self.width - nfull # Number of empty chars + + message = self.message % self + bar = self.phases[-1] * nfull + current = self.phases[phase] if phase > 0 else '' + empty = self.empty_fill * max(0, nempty - len(current)) + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, current, empty, + self.bar_suffix, suffix]) + self.writeln(line) + + +class PixelBar(IncrementalBar): + phases = ('⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿') + + +class ShadyBar(IncrementalBar): + phases = (' ', '░', '▒', '▓', '█') diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/counter.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/counter.py new file mode 100644 index 0000000..6b45a1e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/counter.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite, Progress +from .helpers import WriteMixin + + +class Counter(WriteMixin, Infinite): + message = '' + hide_cursor = True + + def update(self): + self.write(str(self.index)) + + +class Countdown(WriteMixin, Progress): + hide_cursor = True + + def update(self): + self.write(str(self.remaining)) + + +class Stack(WriteMixin, Progress): + phases = (' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█') + hide_cursor = True + + def update(self): + nphases = len(self.phases) + i = min(nphases - 1, int(self.progress * nphases)) + self.write(self.phases[i]) + + +class Pie(Stack): + phases = ('○', '◔', '◑', '◕', '●') diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/helpers.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/helpers.py new file mode 100644 index 0000000..9ed90b2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/helpers.py @@ -0,0 +1,91 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import print_function + + +HIDE_CURSOR = '\x1b[?25l' +SHOW_CURSOR = '\x1b[?25h' + + +class WriteMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WriteMixin, self).__init__(**kwargs) + self._width = 0 + if message: + self.message = message + + if self.file.isatty(): + if self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + print(self.message, end='', file=self.file) + self.file.flush() + + def write(self, s): + if self.file.isatty(): + b = '\b' * self._width + c = s.ljust(self._width) + print(b + c, end='', file=self.file) + self._width = max(self._width, len(s)) + self.file.flush() + + def finish(self): + if self.file.isatty() and self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +class WritelnMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WritelnMixin, self).__init__(**kwargs) + if message: + self.message = message + + if self.file.isatty() and self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + + def clearln(self): + if self.file.isatty(): + print('\r\x1b[K', end='', file=self.file) + + def writeln(self, line): + if self.file.isatty(): + self.clearln() + print(line, end='', file=self.file) + self.file.flush() + + def finish(self): + if self.file.isatty(): + print(file=self.file) + if self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +from signal import signal, SIGINT +from sys import exit + + +class SigIntMixin(object): + """Registers a signal handler that calls finish on SIGINT""" + + def __init__(self, *args, **kwargs): + super(SigIntMixin, self).__init__(*args, **kwargs) + signal(SIGINT, self._sigint_handler) + + def _sigint_handler(self, signum, frame): + self.finish() + exit(0) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/spinner.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/spinner.py new file mode 100644 index 0000000..464c7b2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/progress/spinner.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite +from .helpers import WriteMixin + + +class Spinner(WriteMixin, Infinite): + message = '' + phases = ('-', '\\', '|', '/') + hide_cursor = True + + def update(self): + i = self.index % len(self.phases) + self.write(self.phases[i]) + + +class PieSpinner(Spinner): + phases = ['◷', '◶', '◵', '◴'] + + +class MoonSpinner(Spinner): + phases = ['◑', '◒', '◐', '◓'] + + +class LineSpinner(Spinner): + phases = ['⎺', '⎻', '⎼', '⎽', '⎼', '⎻'] + +class PixelSpinner(Spinner): + phases = ['⣾','⣷', '⣯', '⣟', '⡿', '⢿', '⣻', '⣽'] diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pyparsing.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pyparsing.py new file mode 100644 index 0000000..ba2619c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pyparsing.py @@ -0,0 +1,5720 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2016 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pip._vendor.pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments +""" + +__version__ = "2.2.0" +__versionTime__ = "06 Mar 2017 02:06 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', +'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', +'CloseMatch', 'tokenMap', 'pyparsing_common', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +alphas = string.ascii_uppercase + string.ascii_lowercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join(c for c in string.printable if c not in string.whitespace) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup[0]) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,(int,slice)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return ( not not self.__toklist ) + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def _iterkeys( self ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + def keys( self ): + """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iterkeys()) + + def values( self ): + """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.itervalues()) + + def items( self ): + """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iteritems()) + + def haskeys( self ): + """Since keys() returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return bool(self.__tokdict) + + def pop( self, *args, **kwargs): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + for k,v in kwargs.items(): + if k == 'default': + args = (args[0], v) + else: + raise TypeError("pop() got an unexpected keyword argument '%s'" % k) + if (isinstance(args[0], int) or + len(args) == 1 or + args[0] in self): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def append( self, item ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + def __getattr__( self, name ): + try: + return self[name] + except KeyError: + return "" + + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = lambda a: offset if a<0 else a+offset + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + # useful for merging many ParseResults using sum() builtin + return self.copy() + else: + # this may raise a TypeError - so be it + return other + self + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + result_list = result.asList() + print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] + """ + return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """ + (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. + """ + nl = "\n" + out = [] + namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + for i,res in enumerate(self.__toklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + items = sorted((str(k), v) for k,v in self.items()) + for k,v in items: + if out: + out.append(NL) + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + elif any(isinstance(vv,ParseResults) for vv in self): + v = self + for i,vv in enumerate(v): + if isinstance(vv,ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +collections.MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + s = strg + return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'decorator to trim function calls to match the arity of the target' +def _trim_arity(func, maxargs=2): + if func in singleArgBuiltins: + return lambda s,l,t: func(t) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + if system_version[:2] >= (3,5): + def extract_stack(limit=0): + # special handling for Python 3.5.0 - extra deep call stack by 1 + offset = -3 if system_version == (3,5,0) else -2 + frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] + return [(frame_summary.filename, frame_summary.lineno)] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [(frame_summary.filename, frame_summary.lineno)] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND + # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! + this_line = extract_stack(limit=2)[-1] + pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") + integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def setParseAction( self, *fns, **kwargs ): + """ + Define one or more actions to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # note that integer fields are now ints, not strings + date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] + """ + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) + """ + msg = kwargs.get("message", "failed user-defined condition") + exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException + for fn in fns: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or loc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + from pip._vendor import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + def parseString( self, instring, parseAll=False ): + """ + Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + se._parse( instring, loc ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + """ + Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + for t,s,e in self.scanString(instring, maxMatches=maxsplit): + yield instring[last:s] + if includeSeparators: + yield t[0] + last = e + yield instring[last:] + + def __add__(self, other ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + Prints:: + Hello, World! -> ['Hello', ',', 'World', '!'] + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{MatchFirst}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + if name is not None: + return self.setResultsName(name) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + def ignore( self, other ): + """ + Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """ + Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + for t in tests: + if comment is not None and comment.matches(t, False) or comments and not t: + comments.append(t) + continue + if not t: + continue + out = ['\n'.join(comments), t] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + except ParseBaseException as pe: + fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" + if '\n' in t: + out.append(line(pe.loc, t)) + out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + def __init__( self ): + super(Token,self).__init__( savelist=False ) + + +class Empty(Token): + """ + An empty token, will always match. + """ + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # any string of non-whitespace characters, except for ',' + csv_value = Word(printables, excludeChars=",") + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): + super(Word,self).__init__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.initCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + if len(s)>4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression + roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['This is the "quote"']] + [['This is the quote with "embedded" quotes']] + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if not quoteChar: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped whitespace + if '\\' in ret and self.convertWhitespaceEscapes: + ws_map = { + r'\t' : '\t', + r'\n' : '\n', + r'\f' : '\f', + r'\r' : '\r', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) + #~ self.leaveWhitespace() + self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """ + Token to advance to a specific column of input text; useful for tabular report scraping. + """ + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +class LineEnd(_PositionToken): + """ + Matches if current position is at the end of a line within the parse string + """ + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc != 0: + # see if entire string up to here is just whitespace and ignoreables + if loc != self.preParse( instring, 0 ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class StringEnd(_PositionToken): + """ + Matches if current position is at the end of the parse string + """ + def __init__( self ): + super(StringEnd,self).__init__() + self.errmsg = "Expected end of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc < len(instring): + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class ParseExpression(ParserElement): + """ + Abstract subclass of ParserElement, for combining and post-processing parsed tokens. + """ + def __init__( self, exprs, savelist = False ): + super(ParseExpression,self).__init__(savelist) + if isinstance( exprs, _generatorType ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( exprs ) ] + elif isinstance( exprs, collections.Iterable ): + exprs = list(exprs) + # if sequence of strings provided, wrap with Literal + if all(isinstance(expr, basestring) for expr in exprs): + exprs = map(ParserElement._literalStringClass, exprs) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + self.exprs = [ e.copy() for e in self.exprs ] + for e in self.exprs: + e.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + def streamline( self ): + super(ParseExpression,self).streamline() + + for e in self.exprs: + e.streamline() + + # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) + # but only if there are no parse actions or resultsNames on the nested And's + # (likewise for Or's and MatchFirst's) + if ( len(self.exprs) == 2 ): + other = self.exprs[0] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = other.exprs[:] + [ self.exprs[1] ] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + other = self.exprs[-1] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + expr = And([integer("id"),name_expr("name"),integer("age")]) + # more easily written as: + expr = integer("id") + name_expr("name") + integer("age") + """ + + class _ErrorStop(Empty): + def __init__(self, *args, **kwargs): + super(And._ErrorStop,self).__init__(*args, **kwargs) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = True + + def parseImpl( self, instring, loc, doActions=True ): + # pass False as last arg to _parse for first element, since we already + # pre-parsed the string as part of our And pre-parsing + loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + loc, exprtokens = e._parse( instring, loc, doActions ) + if exprtokens or exprtokens.haskeys(): + resultlist += exprtokens + return loc, resultlist + + def __iadd__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #And( [ self, other ] ) + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(Or,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + matches.sort(key=lambda x: -x[0]) + for _,e in matches: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) + print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. + """ + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + if issubclass(ParserElement._literalStringClass, Token): + expr = ParserElement._literalStringClass(expr) + else: + expr = ParserElement._literalStringClass(Literal(expr)) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except Exception: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr.canParseNext(instring, loc): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + def __init__( self, expr, stopOn=None): + super(_MultipleMatch, self).__init__(expr) + self.saveAsList = True + ender = stopOn + if isinstance(ender, basestring): + ender = ParserElement._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + + def parseImpl( self, instring, loc, doActions=True ): + self_expr_parse = self.expr._parse + self_skip_ignorables = self._skipIgnorables + check_ender = self.not_ender is not None + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = (not not self.ignoreExprs) + while 1: + if check_ender: + try_not_ender(instring, loc) + if hasIgnoreExprs: + preloc = self_skip_ignorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + FAIL: Expected end of text (at char 5), (line:1, col:6) + """ + def __init__( self, expr, default=_optionalNotMatched ): + super(Optional,self).__init__( expr, savelist=False ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # no match when there are internal spaces + print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] + + func = ident + Group(Optional(delimitedList(term))) + print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +def delimitedList( expr, delim=",", combine=False ): + """ + Helper to define a delimited list of expressions - the delimiter defaults to ','. + By default, the list elements and delimiters can have intervening whitespace, and + comments, but this can be overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + intExpr = Word(nums).setParseAction(lambda t:int(t[0])) + else: + intExpr = intExpr.copy() + intExpr.setName("arrayLen") + intExpr.addParseAction(countFieldParseAction, callDuringTry=True) + return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + if theseTokens != matchTokens: + raise ParseException("",0,"") + rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def _escapeRegexRangeChars(s): + #~ escape these chars: ^-] + for c in r"\^-]": + s = s.replace(c,_bslash+c) + s = s.replace("\n",r"\n") + s = s.replace("\t",r"\t") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + Helper to quickly define a set of alternative Literals, and makes sure to do + longest-first testing when there is a conflict, regardless of the input order, + but returns a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + if isinstance(strs,basestring): + symbols = strs.split() + elif isinstance(strs, collections.Iterable): + symbols = list(strs) + else: + warnings.warn("Invalid argument to oneOf, expected string or iterable", + SyntaxWarning, stacklevel=2) + if not symbols: + return NoMatch() + + i = 0 + while i < len(symbols)-1: + cur = symbols[i] + for j,other in enumerate(symbols[i+1:]): + if ( isequal(other, cur) ): + del symbols[i+j+1] + break + elif ( masks(cur, other) ): + del symbols[i+j+1] + symbols.insert(i,other) + cur = other + break + else: + i += 1 + + if not caseless and useRegex: + #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) + else: + return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) + except Exception: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) + +def dictOf( key, value ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +def srange(s): + r""" + Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) + """ + _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +def matchOnlyAtCol(n): + """ + Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + now is the winter of our discontent made glorious summer by this sun of york + ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] + """ + def pa(s,l,t): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "align":"right"}} + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): + """ + Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + lastExpr = baseExpr | ( lpar + ret + rpar ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" + +dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") +sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") +quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| + Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + ret.setName('nested %s%s expression' % (opener,closer)) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + funcDef = Group( funcDecl + func_body ) + + rvalue = Forward() + funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") + rvalue << (funcCall | identifier | Word(nums)) + assignment = Group(identifier + "=" + rvalue) + stmt << ( funcDef | assignment | identifier ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') + PEER = Empty().setParseAction(checkPeerIndent).setName('') + UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) +_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) +commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") +def replaceHTMLEntity(t): + """Helper parser action to replace common HTML entities with their special characters""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (to end of line)}" + +_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + + Optional( Word(" \t") + + ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") +commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + integer = Word(nums).setName("integer").setParseAction(convertToInteger) + """expression that parses an unsigned integer, returns an int""" + + hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" + mixed_integer.addParseAction(sum) + + real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) + """expression that parses a floating point number and returns a float""" + + sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) + """any int or real number, returned as float""" + + identifier = Word(alphas+'_', alphanums+'_').setName("identifier") + """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" + + ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") + "IPv4 address (C{0.0.0.0 - 255.255.255.255})" + + _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") + _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) + _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") + ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + td,td_end = makeHTMLTags("TD") + table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end + + print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' + """ + return pyparsing_common._html_stripper.transformString(tokens[0]) + + _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') + + Optional( White(" \t") ) ) ).streamline().setName("commaItem") + comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py new file mode 100644 index 0000000..8dc7315 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__init__.py @@ -0,0 +1,3 @@ +from .core import TomlError +from .parser import load, loads +from .writer import dump, dumps diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..56c7a74 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000..54f180f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc new file mode 100644 index 0000000..3070e16 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc new file mode 100644 index 0000000..e81aaf4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py new file mode 100644 index 0000000..c182734 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/core.py @@ -0,0 +1,13 @@ +class TomlError(RuntimeError): + def __init__(self, message, line, col, filename): + RuntimeError.__init__(self, message, line, col, filename) + self.message = message + self.line = line + self.col = col + self.filename = filename + + def __str__(self): + return '{}({}, {}): {}'.format(self.filename, self.line, self.col, self.message) + + def __repr__(self): + return 'TomlError({!r}, {!r}, {!r}, {!r})'.format(self.message, self.line, self.col, self.filename) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py new file mode 100644 index 0000000..7fc3d34 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/parser.py @@ -0,0 +1,374 @@ +import string, re, sys, datetime +from .core import TomlError + +if sys.version_info[0] == 2: + _chr = unichr +else: + _chr = chr + +def load(fin, translate=lambda t, x, v: v): + return loads(fin.read(), translate=translate, filename=getattr(fin, 'name', repr(fin))) + +def loads(s, filename='<string>', translate=lambda t, x, v: v): + if isinstance(s, bytes): + s = s.decode('utf-8') + + s = s.replace('\r\n', '\n') + + root = {} + tables = {} + scope = root + + src = _Source(s, filename=filename) + ast = _p_toml(src) + + def error(msg): + raise TomlError(msg, pos[0], pos[1], filename) + + def process_value(v): + kind, text, value, pos = v + if kind == 'str' and value.startswith('\n'): + value = value[1:] + if kind == 'array': + if value and any(k != value[0][0] for k, t, v, p in value[1:]): + error('array-type-mismatch') + value = [process_value(item) for item in value] + elif kind == 'table': + value = dict([(k, process_value(value[k])) for k in value]) + return translate(kind, text, value) + + for kind, value, pos in ast: + if kind == 'kv': + k, v = value + if k in scope: + error('duplicate_keys. Key "{0}" was used more than once.'.format(k)) + scope[k] = process_value(v) + else: + is_table_array = (kind == 'table_array') + cur = tables + for name in value[:-1]: + if isinstance(cur.get(name), list): + d, cur = cur[name][-1] + else: + d, cur = cur.setdefault(name, (None, {})) + + scope = {} + name = value[-1] + if name not in cur: + if is_table_array: + cur[name] = [(scope, {})] + else: + cur[name] = (scope, {}) + elif isinstance(cur[name], list): + if not is_table_array: + error('table_type_mismatch') + cur[name].append((scope, {})) + else: + if is_table_array: + error('table_type_mismatch') + old_scope, next_table = cur[name] + if old_scope is not None: + error('duplicate_tables') + cur[name] = (scope, next_table) + + def merge_tables(scope, tables): + if scope is None: + scope = {} + for k in tables: + if k in scope: + error('key_table_conflict') + v = tables[k] + if isinstance(v, list): + scope[k] = [merge_tables(sc, tbl) for sc, tbl in v] + else: + scope[k] = merge_tables(v[0], v[1]) + return scope + + return merge_tables(root, tables) + +class _Source: + def __init__(self, s, filename=None): + self.s = s + self._pos = (1, 1) + self._last = None + self._filename = filename + self.backtrack_stack = [] + + def last(self): + return self._last + + def pos(self): + return self._pos + + def fail(self): + return self._expect(None) + + def consume_dot(self): + if self.s: + self._last = self.s[0] + self.s = self[1:] + self._advance(self._last) + return self._last + return None + + def expect_dot(self): + return self._expect(self.consume_dot()) + + def consume_eof(self): + if not self.s: + self._last = '' + return True + return False + + def expect_eof(self): + return self._expect(self.consume_eof()) + + def consume(self, s): + if self.s.startswith(s): + self.s = self.s[len(s):] + self._last = s + self._advance(s) + return True + return False + + def expect(self, s): + return self._expect(self.consume(s)) + + def consume_re(self, re): + m = re.match(self.s) + if m: + self.s = self.s[len(m.group(0)):] + self._last = m + self._advance(m.group(0)) + return m + return None + + def expect_re(self, re): + return self._expect(self.consume_re(re)) + + def __enter__(self): + self.backtrack_stack.append((self.s, self._pos)) + + def __exit__(self, type, value, traceback): + if type is None: + self.backtrack_stack.pop() + else: + self.s, self._pos = self.backtrack_stack.pop() + return type == TomlError + + def commit(self): + self.backtrack_stack[-1] = (self.s, self._pos) + + def _expect(self, r): + if not r: + raise TomlError('msg', self._pos[0], self._pos[1], self._filename) + return r + + def _advance(self, s): + suffix_pos = s.rfind('\n') + if suffix_pos == -1: + self._pos = (self._pos[0], self._pos[1] + len(s)) + else: + self._pos = (self._pos[0] + s.count('\n'), len(s) - suffix_pos) + +_ews_re = re.compile(r'(?:[ \t]|#[^\n]*\n|#[^\n]*\Z|\n)*') +def _p_ews(s): + s.expect_re(_ews_re) + +_ws_re = re.compile(r'[ \t]*') +def _p_ws(s): + s.expect_re(_ws_re) + +_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', '\'': '\'', + '\\': '\\', '/': '/', 'f': '\f' } + +_basicstr_re = re.compile(r'[^"\\\000-\037]*') +_short_uni_re = re.compile(r'u([0-9a-fA-F]{4})') +_long_uni_re = re.compile(r'U([0-9a-fA-F]{8})') +_escapes_re = re.compile('[bnrt"\'\\\\/f]') +_newline_esc_re = re.compile('\n[ \t\n]*') +def _p_basicstr_content(s, content=_basicstr_re): + res = [] + while True: + res.append(s.expect_re(content).group(0)) + if not s.consume('\\'): + break + if s.consume_re(_newline_esc_re): + pass + elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re): + res.append(_chr(int(s.last().group(1), 16))) + else: + s.expect_re(_escapes_re) + res.append(_escapes[s.last().group(0)]) + return ''.join(res) + +_key_re = re.compile(r'[0-9a-zA-Z-_]+') +def _p_key(s): + with s: + s.expect('"') + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return r + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return r + return s.expect_re(_key_re).group(0) + +_float_re = re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?') +_datetime_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') + +_basicstr_ml_re = re.compile(r'(?:(?:|"|"")[^"\\\000-\011\013-\037])*') +_litstr_re = re.compile(r"[^'\000-\037]*") +_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\011\013-\037]))*") +def _p_value(s): + pos = s.pos() + + if s.consume('true'): + return 'bool', s.last(), True, pos + if s.consume('false'): + return 'bool', s.last(), False, pos + + if s.consume('"'): + if s.consume('""'): + r = _p_basicstr_content(s, _basicstr_ml_re) + s.expect('"""') + else: + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return 'str', r, r, pos + + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return 'str', r, r, pos + + if s.consume_re(_datetime_re): + m = s.last() + s0 = m.group(0) + r = map(int, m.groups()[:6]) + if m.group(7): + micro = float(m.group(7)) + else: + micro = 0 + + if m.group(8): + g = int(m.group(8), 10) * 60 + int(m.group(9), 10) + tz = _TimeZone(datetime.timedelta(0, g * 60)) + else: + tz = _TimeZone(datetime.timedelta(0, 0)) + + y, m, d, H, M, S = r + dt = datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) + return 'datetime', s0, dt, pos + + if s.consume_re(_float_re): + m = s.last().group(0) + r = m.replace('_','') + if '.' in m or 'e' in m or 'E' in m: + return 'float', m, float(r), pos + else: + return 'int', m, int(r, 10), pos + + if s.consume('['): + items = [] + with s: + while True: + _p_ews(s) + items.append(_p_value(s)) + s.commit() + _p_ews(s) + s.expect(',') + s.commit() + _p_ews(s) + s.expect(']') + return 'array', None, items, pos + + if s.consume('{'): + _p_ws(s) + items = {} + if not s.consume('}'): + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s) + _p_ws(s) + while s.consume(','): + _p_ws(s) + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s) + _p_ws(s) + s.expect('}') + return 'table', None, items, pos + + s.fail() + +def _p_stmt(s): + pos = s.pos() + if s.consume( '['): + is_array = s.consume('[') + _p_ws(s) + keys = [_p_key(s)] + _p_ws(s) + while s.consume('.'): + _p_ws(s) + keys.append(_p_key(s)) + _p_ws(s) + s.expect(']') + if is_array: + s.expect(']') + return 'table_array' if is_array else 'table', keys, pos + + key = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + value = _p_value(s) + return 'kv', (key, value), pos + +_stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*') +def _p_toml(s): + stmts = [] + _p_ews(s) + with s: + stmts.append(_p_stmt(s)) + while True: + s.commit() + s.expect_re(_stmtsep_re) + stmts.append(_p_stmt(s)) + _p_ews(s) + s.expect_eof() + return stmts + +class _TimeZone(datetime.tzinfo): + def __init__(self, offset): + self._offset = offset + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return None + + def tzname(self, dt): + m = self._offset.total_seconds() // 60 + if m < 0: + res = '-' + m = -m + else: + res = '+' + h = m // 60 + m = m - h * 60 + return '{}{:.02}{:.02}'.format(res, h, m) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py new file mode 100644 index 0000000..6eaf5d7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/pytoml/writer.py @@ -0,0 +1,127 @@ +from __future__ import unicode_literals +import io, datetime, math, sys + +if sys.version_info[0] == 3: + long = int + unicode = str + + +def dumps(obj, sort_keys=False): + fout = io.StringIO() + dump(obj, fout, sort_keys=sort_keys) + return fout.getvalue() + + +_escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'} + + +def _escape_string(s): + res = [] + start = 0 + + def flush(): + if start != i: + res.append(s[start:i]) + return i + 1 + + i = 0 + while i < len(s): + c = s[i] + if c in '"\\\n\r\t\b\f': + start = flush() + res.append('\\' + _escapes[c]) + elif ord(c) < 0x20: + start = flush() + res.append('\\u%04x' % ord(c)) + i += 1 + + flush() + return '"' + ''.join(res) + '"' + + +def _escape_id(s): + if any(not c.isalnum() and c not in '-_' for c in s): + return _escape_string(s) + return s + + +def _format_list(v): + return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) + +# Formula from: +# https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds +# Once support for py26 is dropped, this can be replaced by td.total_seconds() +def _total_seconds(td): + return ((td.microseconds + + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6) + +def _format_value(v): + if isinstance(v, bool): + return 'true' if v else 'false' + if isinstance(v, int) or isinstance(v, long): + return unicode(v) + if isinstance(v, float): + if math.isnan(v) or math.isinf(v): + raise ValueError("{0} is not a valid TOML value".format(v)) + else: + return repr(v) + elif isinstance(v, unicode) or isinstance(v, bytes): + return _escape_string(v) + elif isinstance(v, datetime.datetime): + offs = v.utcoffset() + offs = _total_seconds(offs) // 60 if offs is not None else 0 + + if offs == 0: + suffix = 'Z' + else: + if offs > 0: + suffix = '+' + else: + suffix = '-' + offs = -offs + suffix = '{0}{1:.02}{2:.02}'.format(suffix, offs // 60, offs % 60) + + if v.microsecond: + return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix + else: + return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix + elif isinstance(v, list): + return _format_list(v) + else: + raise RuntimeError(v) + + +def dump(obj, fout, sort_keys=False): + tables = [((), obj, False)] + + while tables: + name, table, is_array = tables.pop() + if name: + section_name = '.'.join(_escape_id(c) for c in name) + if is_array: + fout.write('[[{0}]]\n'.format(section_name)) + else: + fout.write('[{0}]\n'.format(section_name)) + + table_keys = sorted(table.keys()) if sort_keys else table.keys() + new_tables = [] + has_kv = False + for k in table_keys: + v = table[k] + if isinstance(v, dict): + new_tables.append((name + (k,), v, False)) + elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v): + new_tables.extend((name + (k,), d, True) for d in v) + elif v is None: + # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344 + fout.write( + '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k))) + has_kv = True + else: + fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v))) + has_kv = True + + tables.extend(reversed(new_tables)) + + if (name or has_kv) and tables: + fout.write('\n') diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__init__.py new file mode 100644 index 0000000..ccd361a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__init__.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- + +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / + +""" +Requests HTTP Library +~~~~~~~~~~~~~~~~~~~~~ + +Requests is an HTTP library, written in Python, for human beings. Basic GET +usage: + + >>> import requests + >>> r = requests.get('https://www.python.org') + >>> r.status_code + 200 + >>> 'Python is a programming language' in r.content + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('http://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at <http://python-requests.org>. + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +from pip._vendor import urllib3 +from pip._vendor import chardet +import warnings +from .exceptions import RequestsDependencyWarning + + +def check_compatibility(urllib3_version, chardet_version): + urllib3_version = urllib3_version.split('.') + assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append('0') + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.22 + assert major == 1 + assert minor >= 21 + assert minor <= 22 + + # Check chardet for compatibility. + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet >= 3.0.2, < 3.1.0 + assert major == 3 + assert minor < 1 + assert patch >= 2 + + +# Check imported dependencies for compatibility. +try: + check_compatibility(urllib3.__version__, chardet.__version__) +except (AssertionError, ValueError): + warnings.warn("urllib3 ({0}) or chardet ({1}) doesn't match a supported " + "version!".format(urllib3.__version__, chardet.__version__), + RequestsDependencyWarning) + +# Attempt to enable urllib3's SNI support, if possible +from pip._internal.compat import WINDOWS +if not WINDOWS: + try: + from pip._vendor.urllib3.contrib import pyopenssl + pyopenssl.inject_into_urllib3() + except ImportError: + pass + +# urllib3's DependencyWarnings should be silenced. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.simplefilter('ignore', DependencyWarning) + +from .__version__ import __title__, __description__, __url__, __version__ +from .__version__ import __build__, __author__, __author_email__, __license__ +from .__version__ import __copyright__, __cake__ + +from . import utils +from . import packages +from .models import Request, Response, PreparedRequest +from .api import request, get, head, post, patch, put, delete, options +from .sessions import session, Session +from .status_codes import codes +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError, + FileModeWarning, ConnectTimeout, ReadTimeout +) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..0d4b9bf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc new file mode 100644 index 0000000..f2b78ab Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc new file mode 100644 index 0000000..db138a5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc new file mode 100644 index 0000000..d67c0fe Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/api.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/api.cpython-37.pyc new file mode 100644 index 0000000..a7a4d91 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/api.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc new file mode 100644 index 0000000..429cf18 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc new file mode 100644 index 0000000..552134b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000..e6d6acb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc new file mode 100644 index 0000000..4cb6ef1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000..c19f7e4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc new file mode 100644 index 0000000..703c110 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/models.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000..3cb1c68 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/models.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc new file mode 100644 index 0000000..d260002 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc new file mode 100644 index 0000000..e6f46c5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc new file mode 100644 index 0000000..fdfffb1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc new file mode 100644 index 0000000..97b34f4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000..66da9f3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__version__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__version__.py new file mode 100644 index 0000000..dc33eef --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/__version__.py @@ -0,0 +1,14 @@ +# .-. .-. .-. . . .-. .-. .-. .-. +# |( |- |.| | | |- `-. | `-. +# ' ' `-' `-`.`-' `-' `-' ' `-' + +__title__ = 'requests' +__description__ = 'Python HTTP for Humans.' +__url__ = 'http://python-requests.org' +__version__ = '2.18.4' +__build__ = 0x021804 +__author__ = 'Kenneth Reitz' +__author_email__ = 'me@kennethreitz.org' +__license__ = 'Apache 2.0' +__copyright__ = 'Copyright 2017 Kenneth Reitz' +__cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/_internal_utils.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/_internal_utils.py new file mode 100644 index 0000000..759d9a5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/_internal_utils.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +""" +requests._internal_utils +~~~~~~~~~~~~~~ + +Provides utility functions that are consumed internally by Requests +which depend on extremely few external helpers (such as compat) +""" + +from .compat import is_py2, builtin_str, str + + +def to_native_string(string, encoding='ascii'): + """Given a string object, regardless of type, returns a representation of + that string in the native string type, encoding and decoding where + necessary. This assumes ASCII unless told otherwise. + """ + if isinstance(string, builtin_str): + out = string + else: + if is_py2: + out = string.encode(encoding) + else: + out = string.decode(encoding) + + return out + + +def unicode_is_ascii(u_string): + """Determine if unicode string only contains ASCII characters. + + :param str u_string: unicode string to check. Must be unicode + and not Python 2 `str`. + :rtype: bool + """ + assert isinstance(u_string, str) + try: + u_string.encode('ascii') + return True + except UnicodeEncodeError: + return False diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/adapters.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/adapters.py new file mode 100644 index 0000000..5787638 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/adapters.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- + +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket + +from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url +from pip._vendor.urllib3.response import HTTPResponse +from pip._vendor.urllib3.util import Timeout as TimeoutSauce +from pip._vendor.urllib3.util.retry import Retry +from pip._vendor.urllib3.exceptions import ClosedPoolError +from pip._vendor.urllib3.exceptions import ConnectTimeoutError +from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError +from pip._vendor.urllib3.exceptions import MaxRetryError +from pip._vendor.urllib3.exceptions import NewConnectionError +from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError +from pip._vendor.urllib3.exceptions import ProtocolError +from pip._vendor.urllib3.exceptions import ReadTimeoutError +from pip._vendor.urllib3.exceptions import SSLError as _SSLError +from pip._vendor.urllib3.exceptions import ResponseError + +from .models import Response +from .compat import urlparse, basestring +from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, + prepend_scheme_if_needed, get_auth_from_url, urldefragauth, + select_proxy) +from .structures import CaseInsensitiveDict +from .cookies import extract_cookies_to_jar +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError, InvalidSchema) +from .auth import _basic_auth_str + +try: + from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter(object): + """The Base Transport Adapter""" + + def __init__(self): + super(BaseAdapter, self).__init__() + + def send(self, request, stream=False, timeout=None, verify=True, + cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session <Session>` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', + '_pool_block'] + + def __init__(self, pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super(HTTPAdapter, self).__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return dict((attr, getattr(self, attr, None)) for attr in + self.__attrs__) + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager(self._pool_connections, self._pool_maxsize, + block=self._pool_block) + + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith('socks'): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith('https') and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = DEFAULT_CA_BUNDLE_PATH + + if not cert_loc or not os.path.exists(cert_loc): + raise IOError("Could not find a suitable TLS CA certificate bundle, " + "invalid path: {0}".format(cert_loc)) + + conn.cert_reqs = 'CERT_REQUIRED' + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise IOError("Could not find the TLS certificate file, " + "invalid path: {0}".format(conn.cert_file)) + if conn.key_file and not os.path.exists(conn.key_file): + raise IOError("Could not find the TLS key file, " + "invalid path: {0}".format(conn.key_file)) + + def build_response(self, req, resp): + """Builds a :class:`Response <requests.Response>` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>` + + :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, 'status', None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode('utf-8') + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = (proxy and scheme != 'https') + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith('socks') + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxies: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers['Proxy-Authorization'] = _basic_auth_str(username, + password) + + return headers + + def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + conn = self.get_connection(request.url, proxies) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers(request) + + chunked = not (request.body is None or 'Content-Length' in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {0}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout + ) + + # Send the request. + else: + if hasattr(conn, 'proxy_pool'): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + low_conn.putrequest(request.method, + url, + skip_accept_encoding=True) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode('utf-8')) + low_conn.send(b'\r\n') + low_conn.send(i) + low_conn.send(b'\r\n') + low_conn.send(b'0\r\n\r\n') + + # Receive the response from the server + try: + # For Python 2.7+ versions, use buffering of HTTP + # responses + r = low_conn.getresponse(buffering=True) + except TypeError: + # For compatibility with Python 2.6 versions and back + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False + ) + except: + # If we hit any problems here, clean up the connection. + # Then, reraise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/api.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/api.py new file mode 100644 index 0000000..bc2115c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/api.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- + +""" +requests.api +~~~~~~~~~~~~ + +This module implements the Requests API. + +:copyright: (c) 2012 by Kenneth Reitz. +:license: Apache2, see LICENSE for more details. +""" + +from . import sessions + + +def request(method, url, **kwargs): + """Constructs and sends a :class:`Request <Request>`. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response <Response>` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'http://httpbin.org/get') + <Response [200]> + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) + + +def head(url, **kwargs): + r"""Sends a HEAD request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('post', url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('put', url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('patch', url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('delete', url, **kwargs) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/auth.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/auth.py new file mode 100644 index 0000000..1a182df --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/auth.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- + +""" +requests.auth +~~~~~~~~~~~~~ + +This module contains the authentication handlers for Requests. +""" + +import os +import re +import time +import hashlib +import threading +import warnings + +from base64 import b64encode + +from .compat import urlparse, str, basestring +from .cookies import extract_cookies_to_jar +from ._internal_utils import to_native_string +from .utils import parse_dict_header + +CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' +CONTENT_TYPE_MULTI_PART = 'multipart/form-data' + + +def _basic_auth_str(username, password): + """Returns a Basic Auth string.""" + + # "I want us to put a big-ol' comment on top of it that + # says that this behaviour is dumb but we need to preserve + # it because people are relying on it." + # - Lukasa + # + # These are here solely to maintain backwards compatibility + # for things like ints. This will be removed in 3.0.0. + if not isinstance(username, basestring): + warnings.warn( + "Non-string usernames will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(username), + category=DeprecationWarning, + ) + username = str(username) + + if not isinstance(password, basestring): + warnings.warn( + "Non-string passwords will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(password), + category=DeprecationWarning, + ) + password = str(password) + # -- End Removal -- + + if isinstance(username, str): + username = username.encode('latin1') + + if isinstance(password, str): + password = password.encode('latin1') + + authstr = 'Basic ' + to_native_string( + b64encode(b':'.join((username, password))).strip() + ) + + return authstr + + +class AuthBase(object): + """Base class that all auth implementations derive from""" + + def __call__(self, r): + raise NotImplementedError('Auth hooks must be callable.') + + +class HTTPBasicAuth(AuthBase): + """Attaches HTTP Basic Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other + + def __call__(self, r): + r.headers['Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPProxyAuth(HTTPBasicAuth): + """Attaches HTTP Proxy Authentication to a given Request object.""" + + def __call__(self, r): + r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPDigestAuth(AuthBase): + """Attaches HTTP Digest Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + # Keep state in per-thread local storage + self._thread_local = threading.local() + + def init_per_thread_state(self): + # Ensure state is initialized just once per-thread + if not hasattr(self._thread_local, 'init'): + self._thread_local.init = True + self._thread_local.last_nonce = '' + self._thread_local.nonce_count = 0 + self._thread_local.chal = {} + self._thread_local.pos = None + self._thread_local.num_401_calls = None + + def build_digest_header(self, method, url): + """ + :rtype: str + """ + + realm = self._thread_local.chal['realm'] + nonce = self._thread_local.chal['nonce'] + qop = self._thread_local.chal.get('qop') + algorithm = self._thread_local.chal.get('algorithm') + opaque = self._thread_local.chal.get('opaque') + hash_utf8 = None + + if algorithm is None: + _algorithm = 'MD5' + else: + _algorithm = algorithm.upper() + # lambdas assume digest modules are imported at the top level + if _algorithm == 'MD5' or _algorithm == 'MD5-SESS': + def md5_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.md5(x).hexdigest() + hash_utf8 = md5_utf8 + elif _algorithm == 'SHA': + def sha_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha1(x).hexdigest() + hash_utf8 = sha_utf8 + + KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) + + if hash_utf8 is None: + return None + + # XXX not implemented yet + entdig = None + p_parsed = urlparse(url) + #: path is request-uri defined in RFC 2616 which should not be empty + path = p_parsed.path or "/" + if p_parsed.query: + path += '?' + p_parsed.query + + A1 = '%s:%s:%s' % (self.username, realm, self.password) + A2 = '%s:%s' % (method, path) + + HA1 = hash_utf8(A1) + HA2 = hash_utf8(A2) + + if nonce == self._thread_local.last_nonce: + self._thread_local.nonce_count += 1 + else: + self._thread_local.nonce_count = 1 + ncvalue = '%08x' % self._thread_local.nonce_count + s = str(self._thread_local.nonce_count).encode('utf-8') + s += nonce.encode('utf-8') + s += time.ctime().encode('utf-8') + s += os.urandom(8) + + cnonce = (hashlib.sha1(s).hexdigest()[:16]) + if _algorithm == 'MD5-SESS': + HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce)) + + if not qop: + respdig = KD(HA1, "%s:%s" % (nonce, HA2)) + elif qop == 'auth' or 'auth' in qop.split(','): + noncebit = "%s:%s:%s:%s:%s" % ( + nonce, ncvalue, cnonce, 'auth', HA2 + ) + respdig = KD(HA1, noncebit) + else: + # XXX handle auth-int. + return None + + self._thread_local.last_nonce = nonce + + # XXX should the partial digests be encoded too? + base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ + 'response="%s"' % (self.username, realm, nonce, path, respdig) + if opaque: + base += ', opaque="%s"' % opaque + if algorithm: + base += ', algorithm="%s"' % algorithm + if entdig: + base += ', digest="%s"' % entdig + if qop: + base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) + + return 'Digest %s' % (base) + + def handle_redirect(self, r, **kwargs): + """Reset num_401_calls counter on redirects.""" + if r.is_redirect: + self._thread_local.num_401_calls = 1 + + def handle_401(self, r, **kwargs): + """ + Takes the given response and tries digest-auth, if needed. + + :rtype: requests.Response + """ + + # If response is not 4xx, do not auth + # See https://github.com/requests/requests/issues/3772 + if not 400 <= r.status_code < 500: + self._thread_local.num_401_calls = 1 + return r + + if self._thread_local.pos is not None: + # Rewind the file position indicator of the body to where + # it was to resend the request. + r.request.body.seek(self._thread_local.pos) + s_auth = r.headers.get('www-authenticate', '') + + if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2: + + self._thread_local.num_401_calls += 1 + pat = re.compile(r'digest ', flags=re.IGNORECASE) + self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1)) + + # Consume content and release the original connection + # to allow our new request to reuse the same one. + r.content + r.close() + prep = r.request.copy() + extract_cookies_to_jar(prep._cookies, r.request, r.raw) + prep.prepare_cookies(prep._cookies) + + prep.headers['Authorization'] = self.build_digest_header( + prep.method, prep.url) + _r = r.connection.send(prep, **kwargs) + _r.history.append(r) + _r.request = prep + + return _r + + self._thread_local.num_401_calls = 1 + return r + + def __call__(self, r): + # Initialize per-thread state, if needed + self.init_per_thread_state() + # If we have a saved nonce, skip the 401 + if self._thread_local.last_nonce: + r.headers['Authorization'] = self.build_digest_header(r.method, r.url) + try: + self._thread_local.pos = r.body.tell() + except AttributeError: + # In the case of HTTPDigestAuth being reused and the body of + # the previous request was a file-like object, pos has the + # file position of the previous body. Ensure it's set to + # None. + self._thread_local.pos = None + r.register_hook('response', self.handle_401) + r.register_hook('response', self.handle_redirect) + self._thread_local.num_401_calls = 1 + + return r + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/certs.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/certs.py new file mode 100644 index 0000000..06a594e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/certs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +requests.certs +~~~~~~~~~~~~~~ + +This module returns the preferred default CA certificate bundle. There is +only one — the one from the certifi package. + +If you are packaging Requests, e.g., for a Linux distribution or a managed +environment, you can change the definition of where() to return a separately +packaged CA bundle. +""" +from pip._vendor.certifi import where + +if __name__ == '__main__': + print(where()) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/compat.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/compat.py new file mode 100644 index 0000000..20da3e0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/compat.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +""" +requests.compat +~~~~~~~~~~~~~~~ + +This module handles import compatibility issues between Python 2 and +Python 3. +""" + +from pip._vendor import chardet + +import sys + +# ------- +# Pythons +# ------- + +# Syntax sugar. +_ver = sys.version_info + +#: Python 2.x? +is_py2 = (_ver[0] == 2) + +#: Python 3.x? +is_py3 = (_ver[0] == 3) + +# Note: We've patched out simplejson support in pip because it prevents +# upgrading simplejson on Windows. +# try: +# import simplejson as json +# except (ImportError, SyntaxError): +# # simplejson does not support Python 3.2, it throws a SyntaxError +# # because of u'...' Unicode literals. +import json + +# --------- +# Specifics +# --------- + +if is_py2: + from urllib import ( + quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, + proxy_bypass, proxy_bypass_environment, getproxies_environment) + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag + from urllib2 import parse_http_list + import cookielib + from Cookie import Morsel + from StringIO import StringIO + + from pip._vendor.urllib3.packages.ordered_dict import OrderedDict + + builtin_str = str + bytes = str + str = unicode + basestring = basestring + numeric_types = (int, long, float) + integer_types = (int, long) + +elif is_py3: + from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag + from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment + from http import cookiejar as cookielib + from http.cookies import Morsel + from io import StringIO + from collections import OrderedDict + + builtin_str = str + str = str + bytes = bytes + basestring = (str, bytes) + numeric_types = (int, float) + integer_types = (int,) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/cookies.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/cookies.py new file mode 100644 index 0000000..ab3c88b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/cookies.py @@ -0,0 +1,542 @@ +# -*- coding: utf-8 -*- + +""" +requests.cookies +~~~~~~~~~~~~~~~~ + +Compatibility code to be able to use `cookielib.CookieJar` with requests. + +requests.utils imports from here, so be careful with imports. +""" + +import copy +import time +import calendar +import collections + +from ._internal_utils import to_native_string +from .compat import cookielib, urlparse, urlunparse, Morsel + +try: + import threading +except ImportError: + import dummy_threading as threading + + +class MockRequest(object): + """Wraps a `requests.Request` to mimic a `urllib2.Request`. + + The code in `cookielib.CookieJar` expects this interface in order to correctly + manage cookie policies, i.e., determine whether a cookie can be set, given the + domains of the request and the cookie. + + The original request object is read-only. The client is responsible for collecting + the new headers via `get_new_headers()` and interpreting them appropriately. You + probably want `get_cookie_header`, defined below. + """ + + def __init__(self, request): + self._r = request + self._new_headers = {} + self.type = urlparse(self._r.url).scheme + + def get_type(self): + return self.type + + def get_host(self): + return urlparse(self._r.url).netloc + + def get_origin_req_host(self): + return self.get_host() + + def get_full_url(self): + # Only return the response's URL if the user hadn't set the Host + # header + if not self._r.headers.get('Host'): + return self._r.url + # If they did set it, retrieve it and reconstruct the expected domain + host = to_native_string(self._r.headers['Host'], encoding='utf-8') + parsed = urlparse(self._r.url) + # Reconstruct the URL as we expect it + return urlunparse([ + parsed.scheme, host, parsed.path, parsed.params, parsed.query, + parsed.fragment + ]) + + def is_unverifiable(self): + return True + + def has_header(self, name): + return name in self._r.headers or name in self._new_headers + + def get_header(self, name, default=None): + return self._r.headers.get(name, self._new_headers.get(name, default)) + + def add_header(self, key, val): + """cookielib has no legitimate use for this method; add it back if you find one.""" + raise NotImplementedError("Cookie headers should be added with add_unredirected_header()") + + def add_unredirected_header(self, name, value): + self._new_headers[name] = value + + def get_new_headers(self): + return self._new_headers + + @property + def unverifiable(self): + return self.is_unverifiable() + + @property + def origin_req_host(self): + return self.get_origin_req_host() + + @property + def host(self): + return self.get_host() + + +class MockResponse(object): + """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. + + ...what? Basically, expose the parsed HTTP headers from the server response + the way `cookielib` expects to see them. + """ + + def __init__(self, headers): + """Make a MockResponse for `cookielib` to read. + + :param headers: a httplib.HTTPMessage or analogous carrying the headers + """ + self._headers = headers + + def info(self): + return self._headers + + def getheaders(self, name): + self._headers.getheaders(name) + + +def extract_cookies_to_jar(jar, request, response): + """Extract the cookies from the response into a CookieJar. + + :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) + :param request: our own requests.Request object + :param response: urllib3.HTTPResponse object + """ + if not (hasattr(response, '_original_response') and + response._original_response): + return + # the _original_response field is the wrapped httplib.HTTPResponse object, + req = MockRequest(request) + # pull out the HTTPMessage with the headers and put it in the mock: + res = MockResponse(response._original_response.msg) + jar.extract_cookies(res, req) + + +def get_cookie_header(jar, request): + """ + Produce an appropriate Cookie header string to be sent with `request`, or None. + + :rtype: str + """ + r = MockRequest(request) + jar.add_cookie_header(r) + return r.get_new_headers().get('Cookie') + + +def remove_cookie_by_name(cookiejar, name, domain=None, path=None): + """Unsets a cookie by name, by default over all domains and paths. + + Wraps CookieJar.clear(), is O(n). + """ + clearables = [] + for cookie in cookiejar: + if cookie.name != name: + continue + if domain is not None and domain != cookie.domain: + continue + if path is not None and path != cookie.path: + continue + clearables.append((cookie.domain, cookie.path, cookie.name)) + + for domain, path, name in clearables: + cookiejar.clear(domain, path, name) + + +class CookieConflictError(RuntimeError): + """There are two cookies that meet the criteria specified in the cookie jar. + Use .get and .set and include domain and path args in order to be more specific. + """ + + +class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. + + This is the CookieJar we create by default for requests and sessions that + don't specify one, since some clients may expect response.cookies and + session.cookies to support dict operations. + + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. + + Unlike a regular CookieJar, this class is pickleable. + + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ + + def get(self, name, default=None, domain=None, path=None): + """Dict-like get() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + + .. warning:: operation is O(n), not O(1). + """ + try: + return self._find_no_duplicates(name, domain, path) + except KeyError: + return default + + def set(self, name, value, **kwargs): + """Dict-like set() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + """ + # support client code that unsets cookies by assignment of a None value: + if value is None: + remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path')) + return + + if isinstance(value, Morsel): + c = morsel_to_cookie(value) + else: + c = create_cookie(name, value, **kwargs) + self.set_cookie(c) + return c + + def iterkeys(self): + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. + + .. seealso:: itervalues() and iteritems(). + """ + for cookie in iter(self): + yield cookie.name + + def keys(self): + """Dict-like keys() that returns a list of names of cookies from the + jar. + + .. seealso:: values() and items(). + """ + return list(self.iterkeys()) + + def itervalues(self): + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. + + .. seealso:: iterkeys() and iteritems(). + """ + for cookie in iter(self): + yield cookie.value + + def values(self): + """Dict-like values() that returns a list of values of cookies from the + jar. + + .. seealso:: keys() and items(). + """ + return list(self.itervalues()) + + def iteritems(self): + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. + + .. seealso:: iterkeys() and itervalues(). + """ + for cookie in iter(self): + yield cookie.name, cookie.value + + def items(self): + """Dict-like items() that returns a list of name-value tuples from the + jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a + vanilla python dict of key value pairs. + + .. seealso:: keys() and values(). + """ + return list(self.iteritems()) + + def list_domains(self): + """Utility method to list all the domains in the jar.""" + domains = [] + for cookie in iter(self): + if cookie.domain not in domains: + domains.append(cookie.domain) + return domains + + def list_paths(self): + """Utility method to list all the paths in the jar.""" + paths = [] + for cookie in iter(self): + if cookie.path not in paths: + paths.append(cookie.path) + return paths + + def multiple_domains(self): + """Returns True if there are multiple domains in the jar. + Returns False otherwise. + + :rtype: bool + """ + domains = [] + for cookie in iter(self): + if cookie.domain is not None and cookie.domain in domains: + return True + domains.append(cookie.domain) + return False # there is only one domain in jar + + def get_dict(self, domain=None, path=None): + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements. + + :rtype: dict + """ + dictionary = {} + for cookie in iter(self): + if ( + (domain is None or cookie.domain == domain) and + (path is None or cookie.path == path) + ): + dictionary[cookie.name] = cookie.value + return dictionary + + def __contains__(self, name): + try: + return super(RequestsCookieJar, self).__contains__(name) + except CookieConflictError: + return True + + def __getitem__(self, name): + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1). + """ + return self._find_no_duplicates(name) + + def __setitem__(self, name, value): + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead. + """ + self.set(name, value) + + def __delitem__(self, name): + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``. + """ + remove_cookie_by_name(self, name) + + def set_cookie(self, cookie, *args, **kwargs): + if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'): + cookie.value = cookie.value.replace('\\"', '') + return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs) + + def update(self, other): + """Updates this jar with cookies from another CookieJar or dict-like""" + if isinstance(other, cookielib.CookieJar): + for cookie in other: + self.set_cookie(copy.copy(cookie)) + else: + super(RequestsCookieJar, self).update(other) + + def _find(self, name, domain=None, path=None): + """Requests uses this method internally to get cookie values. + + If there are conflicting cookies, _find arbitrarily chooses one. + See _find_no_duplicates if you want an exception thrown if there are + conflicting cookies. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :return: cookie.value + """ + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + return cookie.value + + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def _find_no_duplicates(self, name, domain=None, path=None): + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :raises KeyError: if cookie is not found + :raises CookieConflictError: if there are multiple cookies + that match name and optionally domain and path + :return: cookie.value + """ + toReturn = None + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if toReturn is not None: # if there are multiple cookies that meet passed in criteria + raise CookieConflictError('There are multiple cookies with name, %r' % (name)) + toReturn = cookie.value # we will eventually return this as long as no cookie conflict + + if toReturn: + return toReturn + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def __getstate__(self): + """Unlike a normal CookieJar, this class is pickleable.""" + state = self.__dict__.copy() + # remove the unpickleable RLock object + state.pop('_cookies_lock') + return state + + def __setstate__(self, state): + """Unlike a normal CookieJar, this class is pickleable.""" + self.__dict__.update(state) + if '_cookies_lock' not in self.__dict__: + self._cookies_lock = threading.RLock() + + def copy(self): + """Return a copy of this RequestsCookieJar.""" + new_cj = RequestsCookieJar() + new_cj.update(self) + return new_cj + + +def _copy_cookie_jar(jar): + if jar is None: + return None + + if hasattr(jar, 'copy'): + # We're dealing with an instance of RequestsCookieJar + return jar.copy() + # We're dealing with a generic CookieJar instance + new_jar = copy.copy(jar) + new_jar.clear() + for cookie in jar: + new_jar.set_cookie(copy.copy(cookie)) + return new_jar + + +def create_cookie(name, value, **kwargs): + """Make a cookie from underspecified parameters. + + By default, the pair of `name` and `value` will be set for the domain '' + and sent on every request (this is sometimes called a "supercookie"). + """ + result = dict( + version=0, + name=name, + value=value, + port=None, + domain='', + path='/', + secure=False, + expires=None, + discard=True, + comment=None, + comment_url=None, + rest={'HttpOnly': None}, + rfc2109=False,) + + badargs = set(kwargs) - set(result) + if badargs: + err = 'create_cookie() got unexpected keyword arguments: %s' + raise TypeError(err % list(badargs)) + + result.update(kwargs) + result['port_specified'] = bool(result['port']) + result['domain_specified'] = bool(result['domain']) + result['domain_initial_dot'] = result['domain'].startswith('.') + result['path_specified'] = bool(result['path']) + + return cookielib.Cookie(**result) + + +def morsel_to_cookie(morsel): + """Convert a Morsel object into a Cookie containing the one k/v pair.""" + + expires = None + if morsel['max-age']: + try: + expires = int(time.time() + int(morsel['max-age'])) + except ValueError: + raise TypeError('max-age: %s must be integer' % morsel['max-age']) + elif morsel['expires']: + time_template = '%a, %d-%b-%Y %H:%M:%S GMT' + expires = calendar.timegm( + time.strptime(morsel['expires'], time_template) + ) + return create_cookie( + comment=morsel['comment'], + comment_url=bool(morsel['comment']), + discard=False, + domain=morsel['domain'], + expires=expires, + name=morsel.key, + path=morsel['path'], + port=None, + rest={'HttpOnly': morsel['httponly']}, + rfc2109=False, + secure=bool(morsel['secure']), + value=morsel.value, + version=morsel['version'] or 0, + ) + + +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): + """Returns a CookieJar from a key/value dictionary. + + :param cookie_dict: Dict of key/values to insert into CookieJar. + :param cookiejar: (optional) A cookiejar to add the cookies to. + :param overwrite: (optional) If False, will not replace cookies + already in the jar with new ones. + """ + if cookiejar is None: + cookiejar = RequestsCookieJar() + + if cookie_dict is not None: + names_from_jar = [cookie.name for cookie in cookiejar] + for name in cookie_dict: + if overwrite or (name not in names_from_jar): + cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) + + return cookiejar + + +def merge_cookies(cookiejar, cookies): + """Add cookies to cookiejar and returns a merged CookieJar. + + :param cookiejar: CookieJar object to add the cookies to. + :param cookies: Dictionary or CookieJar object to be added. + """ + if not isinstance(cookiejar, cookielib.CookieJar): + raise ValueError('You can only merge into CookieJar') + + if isinstance(cookies, dict): + cookiejar = cookiejar_from_dict( + cookies, cookiejar=cookiejar, overwrite=False) + elif isinstance(cookies, cookielib.CookieJar): + try: + cookiejar.update(cookies) + except AttributeError: + for cookie_in_jar in cookies: + cookiejar.set_cookie(cookie_in_jar) + + return cookiejar diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/exceptions.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/exceptions.py new file mode 100644 index 0000000..3e5d0b2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/exceptions.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- + +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. +""" +from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request. + """ + + def __init__(self, *args, **kwargs): + """Initialize RequestException with `request` and `response` objects.""" + response = kwargs.pop('response', None) + self.response = response + self.request = kwargs.pop('request', None) + if (response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(RequestException, self).__init__(*args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL schema (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """See defaults.py for valid schemas.""" + + +class InvalidURL(RequestException, ValueError): + """The URL provided was somehow invalid.""" + + +class InvalidHeader(RequestException, ValueError): + """The header value provided was somehow invalid.""" + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed""" + + +class RetryError(RequestException): + """Custom retries logic failed""" + + +class UnrewindableBodyError(RequestException): + """Requests encountered an error when trying to rewind a body""" + +# Warnings + + +class RequestsWarning(Warning): + """Base warning for Requests.""" + pass + + +class FileModeWarning(RequestsWarning, DeprecationWarning): + """A file was opened in text mode, but Requests determined its binary length.""" + pass + + +class RequestsDependencyWarning(RequestsWarning): + """An imported dependency doesn't match the expected version range.""" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/help.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/help.py new file mode 100644 index 0000000..7c4b193 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/help.py @@ -0,0 +1,120 @@ +"""Module containing bug report helper(s).""" +from __future__ import print_function + +import json +import platform +import sys +import ssl + +from pip._vendor import idna +from pip._vendor import urllib3 +from pip._vendor import chardet + +from . import __version__ as requests_version + +try: + from .packages.urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import OpenSSL + import cryptography + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 2.7.5 it will return + {'name': 'CPython', 'version': '2.7.5'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == 'CPython': + implementation_version = platform.python_version() + elif implementation == 'PyPy': + implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro) + if sys.pypy_version_info.releaselevel != 'final': + implementation_version = ''.join([ + implementation_version, sys.pypy_version_info.releaselevel + ]) + elif implementation == 'Jython': + implementation_version = platform.python_version() # Complete Guess + elif implementation == 'IronPython': + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = 'Unknown' + + return {'name': implementation, 'version': implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + 'system': platform.system(), + 'release': platform.release(), + } + except IOError: + platform_info = { + 'system': 'Unknown', + 'release': 'Unknown', + } + + implementation_info = _implementation() + urllib3_info = {'version': urllib3.__version__} + chardet_info = {'version': chardet.__version__} + + pyopenssl_info = { + 'version': None, + 'openssl_version': '', + } + if OpenSSL: + pyopenssl_info = { + 'version': OpenSSL.__version__, + 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, + } + cryptography_info = { + 'version': getattr(cryptography, '__version__', ''), + } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } + + # OPENSSL_VERSION_NUMBER doesn't exist in the Python 2.6 ssl module. + system_ssl = getattr(ssl, 'OPENSSL_VERSION_NUMBER', None) + system_ssl_info = { + 'version': '%x' % system_ssl if system_ssl is not None else '' + } + + return { + 'platform': platform_info, + 'implementation': implementation_info, + 'system_ssl': system_ssl_info, + 'using_pyopenssl': pyopenssl is not None, + 'pyOpenSSL': pyopenssl_info, + 'urllib3': urllib3_info, + 'chardet': chardet_info, + 'cryptography': cryptography_info, + 'idna': idna_info, + 'requests': { + 'version': requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/hooks.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/hooks.py new file mode 100644 index 0000000..32b32de --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/hooks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ['response'] + + +def default_hooks(): + return dict((event, []) for event in HOOKS) + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or dict() + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, '__call__'): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/models.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/models.py new file mode 100644 index 0000000..4ab4fec --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/models.py @@ -0,0 +1,948 @@ +# -*- coding: utf-8 -*- + +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import collections +import datetime +import sys + +# Import encoding now, to avoid implicit import later. +# Implicit import within threads may cause LookupError when standard library is in a ZIP, +# such as in Embedded Python. See https://github.com/requests/requests/issues/3578. +import encodings.idna + +from pip._vendor.urllib3.fields import RequestField +from pip._vendor.urllib3.filepost import encode_multipart_formdata +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) + +from io import UnsupportedOperation +from .hooks import default_hooks +from .structures import CaseInsensitiveDict + +from .auth import HTTPBasicAuth +from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar +from .exceptions import ( + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) +from ._internal_utils import to_native_string, unicode_is_ascii +from .utils import ( + guess_filename, get_auth_from_url, requote_uri, + stream_decode_response_unicode, to_key_val_list, parse_header_links, + iter_slices, guess_json_utf, super_len, check_header_validity) +from .compat import ( + cookielib, urlunparse, urlsplit, urlencode, str, bytes, + is_py2, chardet, builtin_str, basestring) +from .compat import json as complexjson +from .status_codes import codes + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin(object): + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = '/' + + url.append(path) + + query = p.query + if query: + url.append('?') + url.append(query) + + return ''.join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, 'read'): + return data + elif hasattr(data, '__iter__'): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): + vs = [vs] + for v in vs: + if v is not None: + result.append( + (k.encode('utf-8') if isinstance(k, str) else k, + v.encode('utf-8') if isinstance(v, str) else v)) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if (not files): + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, '__iter__'): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + (field.decode('utf-8') if isinstance(field, bytes) else field, + v.encode('utf-8') if isinstance(v, str) else v)) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + else: + fdata = fp.read() + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin(object): + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError('Unsupported event specified, with event name "%s"' % (event)) + + if isinstance(hook, collections.Callable): + self.hooks[event].append(hook) + elif hasattr(hook, '__iter__'): + self.hooks[event].extend(h for h in hook if isinstance(h, collections.Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request <Request>` object. + + Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: dictionary of URL parameters to append to the URL. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> req.prepare() + <PreparedRequest [GET]> + """ + + def __init__(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return '<Request [%s]>' % (self.method) + + def prepare(self): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest <PreparedRequest>` object, + containing the exact bytes that will be sent to the server. + + Generated from either a :class:`Request <Request>` object or manually. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> r = req.prepare() + <PreparedRequest [GET]> + + >>> s = requests.Session() + >>> s.send(r) + <Response [200]> + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return '<PreparedRequest [%s]>' % (self.method) + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + from pip._vendor import idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: We're unable to blindly call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/requests/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") + error = error.format(to_native_string(url, 'utf8')) + + raise MissingSchema(error) + + if not host: + raise InvalidURL("Invalid URL %r: No host supplied" % url) + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') + + # Carefully reconstruct the network location + netloc = auth or '' + if netloc: + netloc += '@' + netloc += host + if port: + netloc += ':' + str(port) + + # Bare domains aren't valid URLs. + if not path: + path = '/' + + if is_py2: + if isinstance(scheme, str): + scheme = scheme.encode('utf-8') + if isinstance(netloc, str): + netloc = netloc.encode('utf-8') + if isinstance(path, str): + path = path.encode('utf-8') + if isinstance(query, str): + query = query.encode('utf-8') + if isinstance(fragment, str): + fragment = fragment.encode('utf-8') + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = '%s&%s' % (query, enc_params) + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = 'application/json' + body = complexjson.dumps(json) + if not isinstance(body, bytes): + body = body.encode('utf-8') + + is_stream = all([ + hasattr(data, '__iter__'), + not isinstance(data, (basestring, list, tuple, collections.Mapping)) + ]) + + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + if is_stream: + body = data + + if getattr(body, 'tell', None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError('Streamed bodies and files are mutually exclusive.') + + if length: + self.headers['Content-Length'] = builtin_str(length) + else: + self.headers['Transfer-Encoding'] = 'chunked' + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, 'read'): + content_type = None + else: + content_type = 'application/x-www-form-urlencoded' + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ('content-type' not in self.headers): + self.headers['Content-Type'] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers['Content-Length'] = '0' + + def prepare_auth(self, auth, url=''): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers['Cookie'] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response(object): + """The :class:`Response <Response>` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + '_content', 'status_code', 'headers', 'url', 'history', + 'encoding', 'reason', 'cookies', 'elapsed', 'request' + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: File-like object representation of response (for advanced usage). + #: Use of ``raw`` requires that ``stream=True`` be set on the request. + # This requirement does not apply for use internally to Requests. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response <Response>` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest <PreparedRequest>` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return dict( + (attr, getattr(self, attr, None)) + for attr in self.__attrs__ + ) + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + setattr(self, 'raw', None) + + def __repr__(self): + return '<Response [%s]>' % (self.status_code) + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return ('location' in self.headers and self.status_code in REDIRECT_STATI) + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the chardet library.""" + return chardet.detect(self.content)['encoding'] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, 'stream'): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + for line in lines: + yield line + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError( + 'The content for this response was already consumed') + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes() + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return str('') + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors='replace') + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors='replace') + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises ValueError: If the response body does not contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using chardet to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads( + self.content.decode(encoding), **kwargs + ) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + return complexjson.loads(self.text, **kwargs) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get('link') + + # l = MultiDict() + l = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get('rel') or link.get('url') + l[key] = link + + return l + + def raise_for_status(self): + """Raises stored :class:`HTTPError`, if one occurred.""" + + http_error_msg = '' + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode('utf-8') + except UnicodeDecodeError: + reason = self.reason.decode('iso-8859-1') + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) + + elif 500 <= self.status_code < 600: + http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, 'release_conn', None) + if release_conn is not None: + release_conn() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/packages.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/packages.py new file mode 100644 index 0000000..9582fa7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/packages.py @@ -0,0 +1,16 @@ +import sys + +# This code exists for backwards compatibility reasons. +# I don't like it either. Just look the other way. :) + +for package in ('urllib3', 'idna', 'chardet'): + vendored_package = "pip._vendor." + package + locals()[package] = __import__(vendored_package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == vendored_package or mod.startswith(vendored_package + '.'): + unprefixed_mod = mod[len("pip._vendor."):] + sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] + +# Kinda cool, though, right? diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/sessions.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/sessions.py new file mode 100644 index 0000000..6570e73 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/sessions.py @@ -0,0 +1,737 @@ +# -*- coding: utf-8 -*- + +""" +requests.session +~~~~~~~~~~~~~~~~ + +This module provides a Session object to manage and persist settings across +requests (cookies, auth, proxies). +""" +import os +import platform +import time +from collections import Mapping +from datetime import timedelta + +from .auth import _basic_auth_str +from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse +from .cookies import ( + cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) +from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT +from .hooks import default_hooks, dispatch_hook +from ._internal_utils import to_native_string +from .utils import to_key_val_list, default_headers +from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) + +from .structures import CaseInsensitiveDict +from .adapters import HTTPAdapter + +from .utils import ( + requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, + get_auth_from_url, rewind_body +) + +from .status_codes import codes + +# formerly defined here, reexposed here for backward compatibility +from .models import REDIRECT_STATI + +# Preferred clock, based on which one is more accurate on a given system. +if platform.system() == 'Windows': + try: # Python 3.3+ + preferred_clock = time.perf_counter + except AttributeError: # Earlier than Python 3. + preferred_clock = time.clock +else: + preferred_clock = time.time + + +def merge_setting(request_setting, session_setting, dict_class=OrderedDict): + """Determines appropriate setting for a given request, taking into account + the explicit setting on that request, and the setting in the session. If a + setting is a dictionary, they will be merged together using `dict_class` + """ + + if session_setting is None: + return request_setting + + if request_setting is None: + return session_setting + + # Bypass if not a dictionary (e.g. verify) + if not ( + isinstance(session_setting, Mapping) and + isinstance(request_setting, Mapping) + ): + return request_setting + + merged_setting = dict_class(to_key_val_list(session_setting)) + merged_setting.update(to_key_val_list(request_setting)) + + # Remove keys that are set to None. Extract keys first to avoid altering + # the dictionary during iteration. + none_keys = [k for (k, v) in merged_setting.items() if v is None] + for key in none_keys: + del merged_setting[key] + + return merged_setting + + +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): + """Properly merges both requests and session hooks. + + This is necessary because when request_hooks == {'response': []}, the + merge breaks Session hooks entirely. + """ + if session_hooks is None or session_hooks.get('response') == []: + return request_hooks + + if request_hooks is None or request_hooks.get('response') == []: + return session_hooks + + return merge_setting(request_hooks, session_hooks, dict_class) + + +class SessionRedirectMixin(object): + + def get_redirect_target(self, resp): + """Receives a Response. Returns a redirect URI or ``None``""" + # Due to the nature of how requests processes redirects this method will + # be called at least once upon the original response and at least twice + # on each subsequent redirect response (if any). + # If a custom mixin is used to handle this logic, it may be advantageous + # to cache the redirect location onto the response object as a private + # attribute. + if resp.is_redirect: + location = resp.headers['location'] + # Currently the underlying http module on py3 decode headers + # in latin1, but empirical evidence suggests that latin1 is very + # rarely used with non-ASCII characters in HTTP headers. + # It is more likely to get UTF8 header rather than latin1. + # This causes incorrect handling of UTF8 encoded location headers. + # To solve this, we re-encode the location in latin1. + if is_py3: + location = location.encode('latin1') + return to_native_string(location, 'utf8') + return None + + def resolve_redirects(self, resp, req, stream=False, timeout=None, + verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): + """Receives a Response. Returns a generator of Responses or Requests.""" + + hist = [] # keep track of history + + url = self.get_redirect_target(resp) + while url: + prepared_request = req.copy() + + # Update history and keep track of redirects. + # resp.history must ignore the original request in this loop + hist.append(resp) + resp.history = hist[1:] + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) + + if len(resp.history) >= self.max_redirects: + raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) + + # Release the connection back into the pool. + resp.close() + + # Handle redirection without scheme (see: RFC 1808 Section 4) + if url.startswith('//'): + parsed_rurl = urlparse(resp.url) + url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url) + + # The scheme should be lower case... + parsed = urlparse(url) + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/requests/requests/issues/1084 + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): + # https://github.com/requests/requests/issues/3490 + purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') + for header in purged_headers: + prepared_request.headers.pop(header, None) + prepared_request.body = None + + headers = prepared_request.headers + try: + del headers['Cookie'] + except KeyError: + pass + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = ( + prepared_request._body_position is not None and + ('Content-Length' in headers or 'Transfer-Encoding' in headers) + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers: + # If we get redirected to a new host, we should strip out any + # authentication headers. + original_parsed = urlparse(response.request.url) + redirect_parsed = urlparse(url) + + if (original_parsed.hostname != redirect_parsed.hostname): + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + return + + def rebuild_proxies(self, prepared_request, proxies): + """This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() + no_proxy = proxies.get('no_proxy') + + bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) + if self.trust_env and not bypass_proxy: + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get('all')) + + if proxy: + new_proxies.setdefault(scheme, proxy) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # http://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != 'HEAD': + method = 'GET' + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != 'HEAD': + method = 'GET' + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == 'POST': + method = 'GET' + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('http://httpbin.org/get') + <Response [200]> + + Or as a context manager:: + + >>> with requests.Session() as s: + >>> s.get('http://httpbin.org/get') + <Response [200]> + """ + + __attrs__ = [ + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request <Request>` sent from this + #: :class:`Session <Session>`. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request <Request>`. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request <Request>`. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request <Request>`. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount('https://', HTTPAdapter()) + self.mount('http://', HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request <Request>` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, + auth=None, timeout=None, allow_redirects=True, proxies=None, + hooks=None, stream=None, verify=None, cert=None, json=None): + """Constructs a :class:`Request <Request>`, prepares it and sends it. + Returns :class:`Response <Response>` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, bytes, or file-like object to send + in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + 'timeout': timeout, + 'allow_redirects': allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('OPTIONS', url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return self.request('HEAD', url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('POST', url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PUT', url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PATCH', url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('DELETE', url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault('stream', self.stream) + kwargs.setdefault('verify', self.verify) + kwargs.setdefault('cert', self.cert) + kwargs.setdefault('proxies', self.proxies) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError('You can only send PreparedRequests.') + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop('allow_redirects', True) + stream = kwargs.get('stream') + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook('response', hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + extract_cookies_to_jar(self.cookies, request, r.raw) + + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + + # Resolve redirects if allowed. + history = [resp for resp in gen] if allow_redirects else [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get('no_proxy') if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix): + return adapter + + # Nothing matches :-/ + raise InvalidSchema("No connection adapters were found for '%s'" % url) + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + :rtype: Session + """ + + return Session() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/status_codes.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/status_codes.py new file mode 100644 index 0000000..dee8919 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/status_codes.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- + +from .structures import LookupDict + +_codes = { + + # Informational. + 100: ('continue',), + 101: ('switching_protocols',), + 102: ('processing',), + 103: ('checkpoint',), + 122: ('uri_too_long', 'request_uri_too_long'), + 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), + 201: ('created',), + 202: ('accepted',), + 203: ('non_authoritative_info', 'non_authoritative_information'), + 204: ('no_content',), + 205: ('reset_content', 'reset'), + 206: ('partial_content', 'partial'), + 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), + 208: ('already_reported',), + 226: ('im_used',), + + # Redirection. + 300: ('multiple_choices',), + 301: ('moved_permanently', 'moved', '\\o-'), + 302: ('found',), + 303: ('see_other', 'other'), + 304: ('not_modified',), + 305: ('use_proxy',), + 306: ('switch_proxy',), + 307: ('temporary_redirect', 'temporary_moved', 'temporary'), + 308: ('permanent_redirect', + 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 + + # Client Error. + 400: ('bad_request', 'bad'), + 401: ('unauthorized',), + 402: ('payment_required', 'payment'), + 403: ('forbidden',), + 404: ('not_found', '-o-'), + 405: ('method_not_allowed', 'not_allowed'), + 406: ('not_acceptable',), + 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), + 408: ('request_timeout', 'timeout'), + 409: ('conflict',), + 410: ('gone',), + 411: ('length_required',), + 412: ('precondition_failed', 'precondition'), + 413: ('request_entity_too_large',), + 414: ('request_uri_too_large',), + 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), + 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), + 417: ('expectation_failed',), + 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), + 421: ('misdirected_request',), + 422: ('unprocessable_entity', 'unprocessable'), + 423: ('locked',), + 424: ('failed_dependency', 'dependency'), + 425: ('unordered_collection', 'unordered'), + 426: ('upgrade_required', 'upgrade'), + 428: ('precondition_required', 'precondition'), + 429: ('too_many_requests', 'too_many'), + 431: ('header_fields_too_large', 'fields_too_large'), + 444: ('no_response', 'none'), + 449: ('retry_with', 'retry'), + 450: ('blocked_by_windows_parental_controls', 'parental_controls'), + 451: ('unavailable_for_legal_reasons', 'legal_reasons'), + 499: ('client_closed_request',), + + # Server Error. + 500: ('internal_server_error', 'server_error', '/o\\', '✗'), + 501: ('not_implemented',), + 502: ('bad_gateway',), + 503: ('service_unavailable', 'unavailable'), + 504: ('gateway_timeout',), + 505: ('http_version_not_supported', 'http_version'), + 506: ('variant_also_negotiates',), + 507: ('insufficient_storage',), + 509: ('bandwidth_limit_exceeded', 'bandwidth'), + 510: ('not_extended',), + 511: ('network_authentication_required', 'network_auth', 'network_authentication'), +} + +codes = LookupDict(name='status_codes') + +for code, titles in _codes.items(): + for title in titles: + setattr(codes, title, code) + if not title.startswith(('\\', '/')): + setattr(codes, title.upper(), code) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/structures.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/structures.py new file mode 100644 index 0000000..05d2b3f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/structures.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +""" +requests.structures +~~~~~~~~~~~~~~~~~~~ + +Data structures that power Requests. +""" + +import collections + +from .compat import OrderedDict + + +class CaseInsensitiveDict(collections.MutableMapping): + """A case-insensitive ``dict``-like object. + + Implements all methods and operations of + ``collections.MutableMapping`` as well as dict's ``copy``. Also + provides ``lower_items``. + + All keys are expected to be strings. The structure remembers the + case of the last key to be set, and ``iter(instance)``, + ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` + will contain case-sensitive keys. However, querying and contains + testing is case insensitive:: + + cid = CaseInsensitiveDict() + cid['Accept'] = 'application/json' + cid['aCCEPT'] == 'application/json' # True + list(cid) == ['Accept'] # True + + For example, ``headers['content-encoding']`` will return the + value of a ``'Content-Encoding'`` response header, regardless + of how the header name was originally stored. + + If the constructor, ``.update``, or equality comparison + operations are given keys that have equal ``.lower()``s, the + behavior is undefined. + """ + + def __init__(self, data=None, **kwargs): + self._store = OrderedDict() + if data is None: + data = {} + self.update(data, **kwargs) + + def __setitem__(self, key, value): + # Use the lowercased key for lookups, but store the actual + # key alongside the value. + self._store[key.lower()] = (key, value) + + def __getitem__(self, key): + return self._store[key.lower()][1] + + def __delitem__(self, key): + del self._store[key.lower()] + + def __iter__(self): + return (casedkey for casedkey, mappedvalue in self._store.values()) + + def __len__(self): + return len(self._store) + + def lower_items(self): + """Like iteritems(), but with all lowercase keys.""" + return ( + (lowerkey, keyval[1]) + for (lowerkey, keyval) + in self._store.items() + ) + + def __eq__(self, other): + if isinstance(other, collections.Mapping): + other = CaseInsensitiveDict(other) + else: + return NotImplemented + # Compare insensitively + return dict(self.lower_items()) == dict(other.lower_items()) + + # Copy is required + def copy(self): + return CaseInsensitiveDict(self._store.values()) + + def __repr__(self): + return str(dict(self.items())) + + +class LookupDict(dict): + """Dictionary lookup object.""" + + def __init__(self, name=None): + self.name = name + super(LookupDict, self).__init__() + + def __repr__(self): + return '<lookup \'%s\'>' % (self.name) + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + + return self.__dict__.get(key, None) + + def get(self, key, default=None): + return self.__dict__.get(key, default) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/utils.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/utils.py new file mode 100644 index 0000000..5c47de9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/requests/utils.py @@ -0,0 +1,904 @@ +# -*- coding: utf-8 -*- + +""" +requests.utils +~~~~~~~~~~~~~~ + +This module provides utility functions that are used within Requests +that are also useful for external consumption. +""" + +import cgi +import codecs +import collections +import contextlib +import io +import os +import platform +import re +import socket +import struct +import warnings + +from .__version__ import __version__ +from . import certs +# to_native_string is unused here, but imported here for backwards compatibility +from ._internal_utils import to_native_string +from .compat import parse_http_list as _parse_list_header +from .compat import ( + quote, urlparse, bytes, str, OrderedDict, unquote, getproxies, + proxy_bypass, urlunparse, basestring, integer_types, is_py3, + proxy_bypass_environment, getproxies_environment) +from .cookies import cookiejar_from_dict +from .structures import CaseInsensitiveDict +from .exceptions import ( + InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError) + +NETRC_FILES = ('.netrc', '_netrc') + +DEFAULT_CA_BUNDLE_PATH = certs.where() + + +if platform.system() == 'Windows': + # provide a proxy_bypass version on Windows without DNS lookups + + def proxy_bypass_registry(host): + if is_py3: + import winreg + else: + import _winreg as winreg + try: + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + proxyEnable = winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0] + proxyOverride = winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0] + except OSError: + return False + if not proxyEnable or not proxyOverride: + return False + + # make a check value list from the registry entry: replace the + # '<local>' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '<local>': + if '.' not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, 'items'): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, '__len__'): + total_length = len(o) + + elif hasattr(o, 'len'): + total_length = o.len + + elif hasattr(o, 'fileno'): + try: + fileno = o.fileno() + except io.UnsupportedOperation: + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if 'b' not in o.mode: + warnings.warn(( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode."), + FileModeWarning + ) + + if hasattr(o, 'tell'): + try: + current_position = o.tell() + except (OSError, IOError): + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, 'seek') and total_length is None: + # StringIO and BytesIO have seek but no useable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except (OSError, IOError): + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + try: + from netrc import netrc, NetrcParseError + + netrc_path = None + + for f in NETRC_FILES: + try: + loc = os.path.expanduser('~/{0}'.format(f)) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See http://bugs.python.org/issue20164 & + # https://github.com/requests/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b':' + if isinstance(url, str): + splitstr = splitstr.decode('ascii') + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = (0 if _netrc[0] else 1) + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, IOError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # AppEngine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, 'name', None) + if (name and isinstance(name, basestring) and name[0] != '<' and + name[-1] != '>'): + return os.path.basename(name) + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + ValueError: need more than 1 value to unpack + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + ValueError: cannot encode objects that are not 2-tuples. + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + if isinstance(value, collections.Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if '=' not in item: + result[item] = None + continue + name, value = item.split('=', 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != '\\\\': + return value.replace('\\\\', '\\').replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I) + pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return (charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content)) + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get('content-type') + + if not content_type: + return None + + content_type, params = cgi.parse_header(content_type) + + if 'charset' in params: + return params['charset'].strip("'\"") + + if 'text' in content_type: + return 'ISO-8859-1' + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes a iterator.""" + + if r.encoding is None: + for item in iterator: + yield item + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b'', final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos:pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors='replace') + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split('%') + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = '%' + parts[i] + else: + parts[i] = '%' + parts[i] + return ''.join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] + netaddr, bits = net.split('/') + netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xffffffff ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack('>I', bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except socket.error: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count('/') == 1: + try: + mask = int(string_network.split('/')[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split('/')[0]) + except socket.error: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy('no_proxy') + netloc = urlparse(url).netloc + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the netloc, both with and without the port. + no_proxy = ( + host for host in no_proxy.replace(' ', '').split(',') if host + ) + + ip = netloc.split(':')[0] + if is_ipv4_address(ip): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(ip, proxy_ip): + return True + elif ip == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + for host in no_proxy: + if netloc.endswith(host) or netloc.split(':')[0].endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + # If the system proxy settings indicate that this URL should be bypassed, + # don't proxy. + # The proxy_bypass function is incredibly buggy on OS X in early versions + # of Python 2.6, so allow this call to fail. Only catch the specific + # exceptions we've seen, though: this call failing in other ways can reveal + # legitimate problems. + with set_environ('no_proxy', no_proxy_arg): + try: + bypass = proxy_bypass(netloc) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get('all')) + + proxy_keys = [ + urlparts.scheme + '://' + urlparts.hostname, + urlparts.scheme, + 'all://' + urlparts.hostname, + 'all', + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return '%s/%s' % (name, __version__) + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict({ + 'User-Agent': default_user_agent(), + 'Accept-Encoding': ', '.join(('gzip', 'deflate')), + 'Accept': '*/*', + 'Connection': 'keep-alive', + }) + + +def parse_header_links(value): + """Return a dict of parsed link headers proxies. + + i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = ' \'"' + + for val in re.split(', *<', value): + try: + url, params = val.split(';', 1) + except ValueError: + url, params = val, '' + + link = {'url': url.strip('<> \'"')} + + for param in params.split(';'): + try: + key, value = param.split('=') + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return 'utf-32' # BOM included + if sample[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return 'utf-16' # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return 'utf-8' + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return 'utf-16-be' + if sample[1::2] == _null2: # 2nd and 4th are null + return 'utf-16-le' + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return 'utf-32-be' + if sample[1:] == _null3: + return 'utf-32-le' + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) + + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ('', '') + + return auth + + +# Moved outside of function to avoid recompile every call +_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') +_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') + + +def check_header_validity(header): + """Verifies that header value is a string which doesn't contain + leading whitespace or return characters. This prevents unintended + header injection. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + if isinstance(value, bytes): + pat = _CLEAN_HEADER_REGEX_BYTE + else: + pat = _CLEAN_HEADER_REGEX_STR + try: + if not pat.match(value): + raise InvalidHeader("Invalid return character or leading space in header: %s" % name) + except TypeError: + raise InvalidHeader("Value for header {%s: %s} must be of type str or " + "bytes, not %s" % (name, value, type(value))) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, 'seek', None) + if body_seek is not None and isinstance(prepared_request._body_position, integer_types): + try: + body_seek(prepared_request._body_position) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect.") + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/retrying.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/retrying.py new file mode 100644 index 0000000..6d1e627 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/retrying.py @@ -0,0 +1,267 @@ +## Copyright 2013-2014 Ray Holder +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +import random +from pip._vendor import six +import sys +import time +import traceback + + +# sys.maxint / 2, since Python 3.2 doesn't have a sys.maxint... +MAX_WAIT = 1073741823 + + +def retry(*dargs, **dkw): + """ + Decorator function that instantiates the Retrying object + @param *dargs: positional arguments passed to Retrying object + @param **dkw: keyword arguments passed to the Retrying object + """ + # support both @retry and @retry() as valid syntax + if len(dargs) == 1 and callable(dargs[0]): + def wrap_simple(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying().call(f, *args, **kw) + + return wrapped_f + + return wrap_simple(dargs[0]) + + else: + def wrap(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying(*dargs, **dkw).call(f, *args, **kw) + + return wrapped_f + + return wrap + + +class Retrying(object): + + def __init__(self, + stop=None, wait=None, + stop_max_attempt_number=None, + stop_max_delay=None, + wait_fixed=None, + wait_random_min=None, wait_random_max=None, + wait_incrementing_start=None, wait_incrementing_increment=None, + wait_exponential_multiplier=None, wait_exponential_max=None, + retry_on_exception=None, + retry_on_result=None, + wrap_exception=False, + stop_func=None, + wait_func=None, + wait_jitter_max=None): + + self._stop_max_attempt_number = 5 if stop_max_attempt_number is None else stop_max_attempt_number + self._stop_max_delay = 100 if stop_max_delay is None else stop_max_delay + self._wait_fixed = 1000 if wait_fixed is None else wait_fixed + self._wait_random_min = 0 if wait_random_min is None else wait_random_min + self._wait_random_max = 1000 if wait_random_max is None else wait_random_max + self._wait_incrementing_start = 0 if wait_incrementing_start is None else wait_incrementing_start + self._wait_incrementing_increment = 100 if wait_incrementing_increment is None else wait_incrementing_increment + self._wait_exponential_multiplier = 1 if wait_exponential_multiplier is None else wait_exponential_multiplier + self._wait_exponential_max = MAX_WAIT if wait_exponential_max is None else wait_exponential_max + self._wait_jitter_max = 0 if wait_jitter_max is None else wait_jitter_max + + # TODO add chaining of stop behaviors + # stop behavior + stop_funcs = [] + if stop_max_attempt_number is not None: + stop_funcs.append(self.stop_after_attempt) + + if stop_max_delay is not None: + stop_funcs.append(self.stop_after_delay) + + if stop_func is not None: + self.stop = stop_func + + elif stop is None: + self.stop = lambda attempts, delay: any(f(attempts, delay) for f in stop_funcs) + + else: + self.stop = getattr(self, stop) + + # TODO add chaining of wait behaviors + # wait behavior + wait_funcs = [lambda *args, **kwargs: 0] + if wait_fixed is not None: + wait_funcs.append(self.fixed_sleep) + + if wait_random_min is not None or wait_random_max is not None: + wait_funcs.append(self.random_sleep) + + if wait_incrementing_start is not None or wait_incrementing_increment is not None: + wait_funcs.append(self.incrementing_sleep) + + if wait_exponential_multiplier is not None or wait_exponential_max is not None: + wait_funcs.append(self.exponential_sleep) + + if wait_func is not None: + self.wait = wait_func + + elif wait is None: + self.wait = lambda attempts, delay: max(f(attempts, delay) for f in wait_funcs) + + else: + self.wait = getattr(self, wait) + + # retry on exception filter + if retry_on_exception is None: + self._retry_on_exception = self.always_reject + else: + self._retry_on_exception = retry_on_exception + + # TODO simplify retrying by Exception types + # retry on result filter + if retry_on_result is None: + self._retry_on_result = self.never_reject + else: + self._retry_on_result = retry_on_result + + self._wrap_exception = wrap_exception + + def stop_after_attempt(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the previous attempt >= stop_max_attempt_number.""" + return previous_attempt_number >= self._stop_max_attempt_number + + def stop_after_delay(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the time from the first attempt >= stop_max_delay.""" + return delay_since_first_attempt_ms >= self._stop_max_delay + + def no_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Don't sleep at all before retrying.""" + return 0 + + def fixed_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a fixed amount of time between each retry.""" + return self._wait_fixed + + def random_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a random amount of time between wait_random_min and wait_random_max""" + return random.randint(self._wait_random_min, self._wait_random_max) + + def incrementing_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """ + Sleep an incremental amount of time after each attempt, starting at + wait_incrementing_start and incrementing by wait_incrementing_increment + """ + result = self._wait_incrementing_start + (self._wait_incrementing_increment * (previous_attempt_number - 1)) + if result < 0: + result = 0 + return result + + def exponential_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + exp = 2 ** previous_attempt_number + result = self._wait_exponential_multiplier * exp + if result > self._wait_exponential_max: + result = self._wait_exponential_max + if result < 0: + result = 0 + return result + + def never_reject(self, result): + return False + + def always_reject(self, result): + return True + + def should_reject(self, attempt): + reject = False + if attempt.has_exception: + reject |= self._retry_on_exception(attempt.value[1]) + else: + reject |= self._retry_on_result(attempt.value) + + return reject + + def call(self, fn, *args, **kwargs): + start_time = int(round(time.time() * 1000)) + attempt_number = 1 + while True: + try: + attempt = Attempt(fn(*args, **kwargs), attempt_number, False) + except: + tb = sys.exc_info() + attempt = Attempt(tb, attempt_number, True) + + if not self.should_reject(attempt): + return attempt.get(self._wrap_exception) + + delay_since_first_attempt_ms = int(round(time.time() * 1000)) - start_time + if self.stop(attempt_number, delay_since_first_attempt_ms): + if not self._wrap_exception and attempt.has_exception: + # get() on an attempt with an exception should cause it to be raised, but raise just in case + raise attempt.get() + else: + raise RetryError(attempt) + else: + sleep = self.wait(attempt_number, delay_since_first_attempt_ms) + if self._wait_jitter_max: + jitter = random.random() * self._wait_jitter_max + sleep = sleep + max(0, jitter) + time.sleep(sleep / 1000.0) + + attempt_number += 1 + + +class Attempt(object): + """ + An Attempt encapsulates a call to a target function that may end as a + normal return value from the function or an Exception depending on what + occurred during the execution. + """ + + def __init__(self, value, attempt_number, has_exception): + self.value = value + self.attempt_number = attempt_number + self.has_exception = has_exception + + def get(self, wrap_exception=False): + """ + Return the return value of this Attempt instance or raise an Exception. + If wrap_exception is true, this Attempt is wrapped inside of a + RetryError before being raised. + """ + if self.has_exception: + if wrap_exception: + raise RetryError(self) + else: + six.reraise(self.value[0], self.value[1], self.value[2]) + else: + return self.value + + def __repr__(self): + if self.has_exception: + return "Attempts: {0}, Error:\n{1}".format(self.attempt_number, "".join(traceback.format_tb(self.value[2]))) + else: + return "Attempts: {0}, Value: {1}".format(self.attempt_number, self.value) + + +class RetryError(Exception): + """ + A RetryError encapsulates the last Attempt instance right before giving up. + """ + + def __init__(self, last_attempt): + self.last_attempt = last_attempt + + def __str__(self): + return "RetryError[{0}]".format(self.last_attempt) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/six.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/six.py new file mode 100644 index 0000000..6bf4fd3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/six.py @@ -0,0 +1,891 @@ +# Copyright (c) 2010-2017 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.11.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + try: + if from_value is None: + raise value + raise value from from_value + finally: + value = None +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(type): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__init__.py new file mode 100644 index 0000000..aaa6b1c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__init__.py @@ -0,0 +1,97 @@ +""" +urllib3 - Thread-safe connection pooling and re-using. +""" + +from __future__ import absolute_import +import warnings + +from .connectionpool import ( + HTTPConnectionPool, + HTTPSConnectionPool, + connection_from_url +) + +from . import exceptions +from .filepost import encode_multipart_formdata +from .poolmanager import PoolManager, ProxyManager, proxy_from_url +from .response import HTTPResponse +from .util.request import make_headers +from .util.url import get_host +from .util.timeout import Timeout +from .util.retry import Retry + + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' +__license__ = 'MIT' +__version__ = '1.22' + +__all__ = ( + 'HTTPConnectionPool', + 'HTTPSConnectionPool', + 'PoolManager', + 'ProxyManager', + 'HTTPResponse', + 'Retry', + 'Timeout', + 'add_stderr_logger', + 'connection_from_url', + 'disable_warnings', + 'encode_multipart_formdata', + 'get_host', + 'make_headers', + 'proxy_from_url', +) + +logging.getLogger(__name__).addHandler(NullHandler()) + + +def add_stderr_logger(level=logging.DEBUG): + """ + Helper for quickly adding a StreamHandler to the logger. Useful for + debugging. + + Returns the handler after adding it. + """ + # This method needs to be in this __init__.py to get the __name__ correct + # even if urllib3 is vendored within another package. + logger = logging.getLogger(__name__) + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) + logger.addHandler(handler) + logger.setLevel(level) + logger.debug('Added a stderr logging handler to logger: %s', __name__) + return handler + + +# ... Clean up. +del NullHandler + + +# All warning filters *must* be appended unless you're really certain that they +# shouldn't be: otherwise, it's very hard for users to use most Python +# mechanisms to silence them. +# SecurityWarning's always go off by default. +warnings.simplefilter('always', exceptions.SecurityWarning, append=True) +# SubjectAltNameWarning's should go off once per host +warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True) +# InsecurePlatformWarning's don't vary between requests, so we keep it default. +warnings.simplefilter('default', exceptions.InsecurePlatformWarning, + append=True) +# SNIMissingWarnings should go off only once. +warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) + + +def disable_warnings(category=exceptions.HTTPWarning): + """ + Helper for quickly disabling all urllib3 warnings. + """ + warnings.simplefilter('ignore', category) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..18c9150 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc new file mode 100644 index 0000000..72f439b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc new file mode 100644 index 0000000..dc0604a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc new file mode 100644 index 0000000..524366e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000..f3f9fba Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc new file mode 100644 index 0000000..c072c41 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc new file mode 100644 index 0000000..ca2a6c6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc new file mode 100644 index 0000000..9060e9e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc new file mode 100644 index 0000000..8637c02 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc new file mode 100644 index 0000000..f3410a7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/_collections.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/_collections.py new file mode 100644 index 0000000..5df2372 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/_collections.py @@ -0,0 +1,319 @@ +from __future__ import absolute_import +from collections import Mapping, MutableMapping +try: + from threading import RLock +except ImportError: # Platform-specific: No threads available + class RLock: + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_value, traceback): + pass + + +try: # Python 2.7+ + from collections import OrderedDict +except ImportError: + from .packages.ordered_dict import OrderedDict +from .packages.six import iterkeys, itervalues, PY3 + + +__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] + + +_Null = object() + + +class RecentlyUsedContainer(MutableMapping): + """ + Provides a thread-safe dict-like container which maintains up to + ``maxsize`` keys while throwing away the least-recently-used keys beyond + ``maxsize``. + + :param maxsize: + Maximum number of recent elements to retain. + + :param dispose_func: + Every time an item is evicted from the container, + ``dispose_func(value)`` is called. Callback which will get called + """ + + ContainerCls = OrderedDict + + def __init__(self, maxsize=10, dispose_func=None): + self._maxsize = maxsize + self.dispose_func = dispose_func + + self._container = self.ContainerCls() + self.lock = RLock() + + def __getitem__(self, key): + # Re-insert the item, moving it to the end of the eviction line. + with self.lock: + item = self._container.pop(key) + self._container[key] = item + return item + + def __setitem__(self, key, value): + evicted_value = _Null + with self.lock: + # Possibly evict the existing value of 'key' + evicted_value = self._container.get(key, _Null) + self._container[key] = value + + # If we didn't evict an existing value, we might have to evict the + # least recently used item from the beginning of the container. + if len(self._container) > self._maxsize: + _key, evicted_value = self._container.popitem(last=False) + + if self.dispose_func and evicted_value is not _Null: + self.dispose_func(evicted_value) + + def __delitem__(self, key): + with self.lock: + value = self._container.pop(key) + + if self.dispose_func: + self.dispose_func(value) + + def __len__(self): + with self.lock: + return len(self._container) + + def __iter__(self): + raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.') + + def clear(self): + with self.lock: + # Copy pointers to all values, then wipe the mapping + values = list(itervalues(self._container)) + self._container.clear() + + if self.dispose_func: + for value in values: + self.dispose_func(value) + + def keys(self): + with self.lock: + return list(iterkeys(self._container)) + + +class HTTPHeaderDict(MutableMapping): + """ + :param headers: + An iterable of field-value pairs. Must not contain multiple field names + when compared case-insensitively. + + :param kwargs: + Additional field-value pairs to pass in to ``dict.update``. + + A ``dict`` like container for storing HTTP Headers. + + Field names are stored and compared case-insensitively in compliance with + RFC 7230. Iteration provides the first case-sensitive key seen for each + case-insensitive pair. + + Using ``__setitem__`` syntax overwrites fields that compare equal + case-insensitively in order to maintain ``dict``'s api. For fields that + compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` + in a loop. + + If multiple fields that are equal case-insensitively are passed to the + constructor or ``.update``, the behavior is undefined and some will be + lost. + + >>> headers = HTTPHeaderDict() + >>> headers.add('Set-Cookie', 'foo=bar') + >>> headers.add('set-cookie', 'baz=quxx') + >>> headers['content-length'] = '7' + >>> headers['SET-cookie'] + 'foo=bar, baz=quxx' + >>> headers['Content-Length'] + '7' + """ + + def __init__(self, headers=None, **kwargs): + super(HTTPHeaderDict, self).__init__() + self._container = OrderedDict() + if headers is not None: + if isinstance(headers, HTTPHeaderDict): + self._copy_from(headers) + else: + self.extend(headers) + if kwargs: + self.extend(kwargs) + + def __setitem__(self, key, val): + self._container[key.lower()] = [key, val] + return self._container[key.lower()] + + def __getitem__(self, key): + val = self._container[key.lower()] + return ', '.join(val[1:]) + + def __delitem__(self, key): + del self._container[key.lower()] + + def __contains__(self, key): + return key.lower() in self._container + + def __eq__(self, other): + if not isinstance(other, Mapping) and not hasattr(other, 'keys'): + return False + if not isinstance(other, type(self)): + other = type(self)(other) + return (dict((k.lower(), v) for k, v in self.itermerged()) == + dict((k.lower(), v) for k, v in other.itermerged())) + + def __ne__(self, other): + return not self.__eq__(other) + + if not PY3: # Python 2 + iterkeys = MutableMapping.iterkeys + itervalues = MutableMapping.itervalues + + __marker = object() + + def __len__(self): + return len(self._container) + + def __iter__(self): + # Only provide the originally cased names + for vals in self._container.values(): + yield vals[0] + + def pop(self, key, default=__marker): + '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + ''' + # Using the MutableMapping function directly fails due to the private marker. + # Using ordinary dict.pop would expose the internal structures. + # So let's reinvent the wheel. + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def discard(self, key): + try: + del self[key] + except KeyError: + pass + + def add(self, key, val): + """Adds a (name, value) pair, doesn't overwrite the value if it already + exists. + + >>> headers = HTTPHeaderDict(foo='bar') + >>> headers.add('Foo', 'baz') + >>> headers['foo'] + 'bar, baz' + """ + key_lower = key.lower() + new_vals = [key, val] + # Keep the common case aka no item present as fast as possible + vals = self._container.setdefault(key_lower, new_vals) + if new_vals is not vals: + vals.append(val) + + def extend(self, *args, **kwargs): + """Generic import function for any type of header-like object. + Adapted version of MutableMapping.update in order to insert items + with self.add instead of self.__setitem__ + """ + if len(args) > 1: + raise TypeError("extend() takes at most 1 positional " + "arguments ({0} given)".format(len(args))) + other = args[0] if len(args) >= 1 else () + + if isinstance(other, HTTPHeaderDict): + for key, val in other.iteritems(): + self.add(key, val) + elif isinstance(other, Mapping): + for key in other: + self.add(key, other[key]) + elif hasattr(other, "keys"): + for key in other.keys(): + self.add(key, other[key]) + else: + for key, value in other: + self.add(key, value) + + for key, value in kwargs.items(): + self.add(key, value) + + def getlist(self, key, default=__marker): + """Returns a list of all the values for the named field. Returns an + empty list if the key doesn't exist.""" + try: + vals = self._container[key.lower()] + except KeyError: + if default is self.__marker: + return [] + return default + else: + return vals[1:] + + # Backwards compatibility for httplib + getheaders = getlist + getallmatchingheaders = getlist + iget = getlist + + # Backwards compatibility for http.cookiejar + get_all = getlist + + def __repr__(self): + return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) + + def _copy_from(self, other): + for key in other: + val = other.getlist(key) + if isinstance(val, list): + # Don't need to convert tuples + val = list(val) + self._container[key.lower()] = [key] + val + + def copy(self): + clone = type(self)() + clone._copy_from(self) + return clone + + def iteritems(self): + """Iterate over all header lines, including duplicate ones.""" + for key in self: + vals = self._container[key.lower()] + for val in vals[1:]: + yield vals[0], val + + def itermerged(self): + """Iterate over all headers, merging duplicate ones together.""" + for key in self: + val = self._container[key.lower()] + yield val[0], ', '.join(val[1:]) + + def items(self): + return list(self.iteritems()) + + @classmethod + def from_httplib(cls, message): # Python 2 + """Read headers from a Python 2 httplib message object.""" + # python2.7 does not expose a proper API for exporting multiheaders + # efficiently. This function re-reads raw lines from the message + # object and extracts the multiheaders properly. + headers = [] + + for line in message.headers: + if line.startswith((' ', '\t')): + key, value = headers[-1] + headers[-1] = (key, value + '\r\n' + line.rstrip()) + continue + + key, value = line.split(':', 1) + headers.append((key, value.strip())) + + return cls(headers) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connection.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connection.py new file mode 100644 index 0000000..c0d8329 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connection.py @@ -0,0 +1,373 @@ +from __future__ import absolute_import +import datetime +import logging +import os +import sys +import socket +from socket import error as SocketError, timeout as SocketTimeout +import warnings +from .packages import six +from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection +from .packages.six.moves.http_client import HTTPException # noqa: F401 + +try: # Compiled with SSL? + import ssl + BaseSSLError = ssl.SSLError +except (ImportError, AttributeError): # Platform-specific: No SSL. + ssl = None + + class BaseSSLError(BaseException): + pass + + +try: # Python 3: + # Not a no-op, we're adding this to the namespace so it can be imported. + ConnectionError = ConnectionError +except NameError: # Python 2: + class ConnectionError(Exception): + pass + + +from .exceptions import ( + NewConnectionError, + ConnectTimeoutError, + SubjectAltNameWarning, + SystemTimeWarning, +) +from .packages.ssl_match_hostname import match_hostname, CertificateError + +from .util.ssl_ import ( + resolve_cert_reqs, + resolve_ssl_version, + assert_fingerprint, + create_urllib3_context, + ssl_wrap_socket +) + + +from .util import connection + +from ._collections import HTTPHeaderDict + +log = logging.getLogger(__name__) + +port_by_scheme = { + 'http': 80, + 'https': 443, +} + +# When updating RECENT_DATE, move it to +# within two years of the current date, and no +# earlier than 6 months ago. +RECENT_DATE = datetime.date(2016, 1, 1) + + +class DummyConnection(object): + """Used to detect a failed ConnectionCls import.""" + pass + + +class HTTPConnection(_HTTPConnection, object): + """ + Based on httplib.HTTPConnection but provides an extra constructor + backwards-compatibility layer between older and newer Pythons. + + Additional keyword parameters are used to configure attributes of the connection. + Accepted parameters include: + + - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` + - ``source_address``: Set the source address for the current connection. + + .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x + + - ``socket_options``: Set specific options on the underlying socket. If not specified, then + defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling + Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. + + For example, if you wish to enable TCP Keep Alive in addition to the defaults, + you might pass:: + + HTTPConnection.default_socket_options + [ + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). + """ + + default_port = port_by_scheme['http'] + + #: Disable Nagle's algorithm by default. + #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` + default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] + + #: Whether this connection verifies the host's certificate. + is_verified = False + + def __init__(self, *args, **kw): + if six.PY3: # Python 3 + kw.pop('strict', None) + + # Pre-set source_address in case we have an older Python like 2.6. + self.source_address = kw.get('source_address') + + if sys.version_info < (2, 7): # Python 2.6 + # _HTTPConnection on Python 2.6 will balk at this keyword arg, but + # not newer versions. We can still use it when creating a + # connection though, so we pop it *after* we have saved it as + # self.source_address. + kw.pop('source_address', None) + + #: The socket options provided by the user. If no options are + #: provided, we use the default options. + self.socket_options = kw.pop('socket_options', self.default_socket_options) + + # Superclass also sets self.source_address in Python 2.7+. + _HTTPConnection.__init__(self, *args, **kw) + + def _new_conn(self): + """ Establish a socket connection and set nodelay settings on it. + + :return: New socket connection. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = connection.create_connection( + (self.host, self.port), self.timeout, **extra_kw) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except SocketError as e: + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + def _prepare_conn(self, conn): + self.sock = conn + # the _tunnel_host attribute was added in python 2.6.3 (via + # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do + # not have them. + if getattr(self, '_tunnel_host', None): + # TODO: Fix tunnel so it doesn't depend on self.sock state. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + def request_chunked(self, method, url, body=None, headers=None): + """ + Alternative to the common request method, which sends the + body with chunked encoding and not as one block + """ + headers = HTTPHeaderDict(headers if headers is not None else {}) + skip_accept_encoding = 'accept-encoding' in headers + skip_host = 'host' in headers + self.putrequest( + method, + url, + skip_accept_encoding=skip_accept_encoding, + skip_host=skip_host + ) + for header, value in headers.items(): + self.putheader(header, value) + if 'transfer-encoding' not in headers: + self.putheader('Transfer-Encoding', 'chunked') + self.endheaders() + + if body is not None: + stringish_types = six.string_types + (six.binary_type,) + if isinstance(body, stringish_types): + body = (body,) + for chunk in body: + if not chunk: + continue + if not isinstance(chunk, six.binary_type): + chunk = chunk.encode('utf8') + len_str = hex(len(chunk))[2:] + self.send(len_str.encode('utf-8')) + self.send(b'\r\n') + self.send(chunk) + self.send(b'\r\n') + + # After the if clause, to always have a closed body + self.send(b'0\r\n\r\n') + + +class HTTPSConnection(HTTPConnection): + default_port = port_by_scheme['https'] + + ssl_version = None + + def __init__(self, host, port=None, key_file=None, cert_file=None, + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + ssl_context=None, **kw): + + HTTPConnection.__init__(self, host, port, strict=strict, + timeout=timeout, **kw) + + self.key_file = key_file + self.cert_file = cert_file + self.ssl_context = ssl_context + + # Required property for Google AppEngine 1.9.0 which otherwise causes + # HTTPS requests to go out as HTTP. (See Issue #356) + self._protocol = 'https' + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(None), + cert_reqs=resolve_cert_reqs(None), + ) + + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ssl_context=self.ssl_context, + ) + + +class VerifiedHTTPSConnection(HTTPSConnection): + """ + Based on httplib.HTTPSConnection but wraps the socket with + SSL certification. + """ + cert_reqs = None + ca_certs = None + ca_cert_dir = None + ssl_version = None + assert_fingerprint = None + + def set_cert(self, key_file=None, cert_file=None, + cert_reqs=None, ca_certs=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None): + """ + This method should only be called once, before the connection is used. + """ + # If cert_reqs is not provided, we can try to guess. If the user gave + # us a cert database, we assume they want to use it: otherwise, if + # they gave us an SSL Context object we should use whatever is set for + # it. + if cert_reqs is None: + if ca_certs or ca_cert_dir: + cert_reqs = 'CERT_REQUIRED' + elif self.ssl_context is not None: + cert_reqs = self.ssl_context.verify_mode + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + self.ca_certs = ca_certs and os.path.expanduser(ca_certs) + self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) + + def connect(self): + # Add certificate verification + conn = self._new_conn() + + hostname = self.host + if getattr(self, '_tunnel_host', None): + # _tunnel_host was added in Python 2.6.3 + # (See: http://hg.python.org/cpython/rev/0f57b30a152f) + + self.sock = conn + # Calls self._set_hostport(), so self.host is + # self._tunnel_host below. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + # Override the host with the one we're requesting data from. + hostname = self._tunnel_host + + is_time_off = datetime.date.today() < RECENT_DATE + if is_time_off: + warnings.warn(( + 'System time is way off (before {0}). This will probably ' + 'lead to SSL verification errors').format(RECENT_DATE), + SystemTimeWarning + ) + + # Wrap socket using verification with the root certs in + # trusted_root_certs + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(self.ssl_version), + cert_reqs=resolve_cert_reqs(self.cert_reqs), + ) + + context = self.ssl_context + context.verify_mode = resolve_cert_reqs(self.cert_reqs) + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + server_hostname=hostname, + ssl_context=context) + + if self.assert_fingerprint: + assert_fingerprint(self.sock.getpeercert(binary_form=True), + self.assert_fingerprint) + elif context.verify_mode != ssl.CERT_NONE \ + and not getattr(context, 'check_hostname', False) \ + and self.assert_hostname is not False: + # While urllib3 attempts to always turn off hostname matching from + # the TLS library, this cannot always be done. So we check whether + # the TLS Library still thinks it's matching hostnames. + cert = self.sock.getpeercert() + if not cert.get('subjectAltName', ()): + warnings.warn(( + 'Certificate for {0} has no `subjectAltName`, falling back to check for a ' + '`commonName` for now. This feature is being removed by major browsers and ' + 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 ' + 'for details.)'.format(hostname)), + SubjectAltNameWarning + ) + _match_hostname(cert, self.assert_hostname or hostname) + + self.is_verified = ( + context.verify_mode == ssl.CERT_REQUIRED or + self.assert_fingerprint is not None + ) + + +def _match_hostname(cert, asserted_hostname): + try: + match_hostname(cert, asserted_hostname) + except CertificateError as e: + log.error( + 'Certificate did not match expected hostname: %s. ' + 'Certificate: %s', asserted_hostname, cert + ) + # Add cert to exception and reraise so client code can inspect + # the cert when catching the exception, if they want to + e._peer_cert = cert + raise + + +if ssl: + # Make a copy for testing. + UnverifiedHTTPSConnection = HTTPSConnection + HTTPSConnection = VerifiedHTTPSConnection +else: + HTTPSConnection = DummyConnection diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connectionpool.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connectionpool.py new file mode 100644 index 0000000..ec9600f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/connectionpool.py @@ -0,0 +1,905 @@ +from __future__ import absolute_import +import errno +import logging +import sys +import warnings + +from socket import error as SocketError, timeout as SocketTimeout +import socket + + +from .exceptions import ( + ClosedPoolError, + ProtocolError, + EmptyPoolError, + HeaderParsingError, + HostChangedError, + LocationValueError, + MaxRetryError, + ProxyError, + ReadTimeoutError, + SSLError, + TimeoutError, + InsecureRequestWarning, + NewConnectionError, +) +from .packages.ssl_match_hostname import CertificateError +from .packages import six +from .packages.six.moves import queue +from .connection import ( + port_by_scheme, + DummyConnection, + HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, + HTTPException, BaseSSLError, +) +from .request import RequestMethods +from .response import HTTPResponse + +from .util.connection import is_connection_dropped +from .util.request import set_file_position +from .util.response import assert_header_parsing +from .util.retry import Retry +from .util.timeout import Timeout +from .util.url import get_host, Url + + +if six.PY2: + # Queue is imported for side effects on MS Windows + import Queue as _unused_module_Queue # noqa: F401 + +xrange = six.moves.xrange + +log = logging.getLogger(__name__) + +_Default = object() + + +# Pool objects +class ConnectionPool(object): + """ + Base class for all connection pools, such as + :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. + """ + + scheme = None + QueueCls = queue.LifoQueue + + def __init__(self, host, port=None): + if not host: + raise LocationValueError("No host specified.") + + self.host = _ipv6_host(host).lower() + self._proxy_host = host.lower() + self.port = port + + def __str__(self): + return '%s(host=%r, port=%r)' % (type(self).__name__, + self.host, self.port) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + # Return False to re-raise any potential exceptions + return False + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + pass + + +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 +_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK]) + + +class HTTPConnectionPool(ConnectionPool, RequestMethods): + """ + Thread-safe connection pool for one host. + + :param host: + Host used for this HTTP Connection (e.g. "localhost"), passed into + :class:`httplib.HTTPConnection`. + + :param port: + Port used for this HTTP Connection (None is equivalent to 80), passed + into :class:`httplib.HTTPConnection`. + + :param strict: + Causes BadStatusLine to be raised if the status line can't be parsed + as a valid HTTP/1.0 or 1.1 status line, passed into + :class:`httplib.HTTPConnection`. + + .. note:: + Only works in Python 2. This parameter is ignored in Python 3. + + :param timeout: + Socket timeout in seconds for each individual connection. This can + be a float or integer, which sets the timeout for the HTTP request, + or an instance of :class:`urllib3.util.Timeout` which gives you more + fine-grained control over request timeouts. After the constructor has + been parsed, this is always a `urllib3.util.Timeout` object. + + :param maxsize: + Number of connections to save that can be reused. More than 1 is useful + in multithreaded situations. If ``block`` is set to False, more + connections will be created but they will not be saved once they've + been used. + + :param block: + If set to True, no more than ``maxsize`` connections will be used at + a time. When no free connections are available, the call will block + until a connection has been released. This is a useful side effect for + particular multithreaded situations where one does not want to use more + than maxsize connections per host to prevent flooding. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param retries: + Retry configuration to use by default with requests in this pool. + + :param _proxy: + Parsed proxy URL, should not be used directly, instead, see + :class:`urllib3.connectionpool.ProxyManager`" + + :param _proxy_headers: + A dictionary with proxy headers, should not be used directly, + instead, see :class:`urllib3.connectionpool.ProxyManager`" + + :param \\**conn_kw: + Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, + :class:`urllib3.connection.HTTPSConnection` instances. + """ + + scheme = 'http' + ConnectionCls = HTTPConnection + ResponseCls = HTTPResponse + + def __init__(self, host, port=None, strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, + headers=None, retries=None, + _proxy=None, _proxy_headers=None, + **conn_kw): + ConnectionPool.__init__(self, host, port) + RequestMethods.__init__(self, headers) + + self.strict = strict + + if not isinstance(timeout, Timeout): + timeout = Timeout.from_float(timeout) + + if retries is None: + retries = Retry.DEFAULT + + self.timeout = timeout + self.retries = retries + + self.pool = self.QueueCls(maxsize) + self.block = block + + self.proxy = _proxy + self.proxy_headers = _proxy_headers or {} + + # Fill the queue up so that doing get() on it will block properly + for _ in xrange(maxsize): + self.pool.put(None) + + # These are mostly for testing and debugging purposes. + self.num_connections = 0 + self.num_requests = 0 + self.conn_kw = conn_kw + + if self.proxy: + # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. + # We cannot know if the user has added default socket options, so we cannot replace the + # list. + self.conn_kw.setdefault('socket_options', []) + + def _new_conn(self): + """ + Return a fresh :class:`HTTPConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTP connection (%d): %s", + self.num_connections, self.host) + + conn = self.ConnectionCls(host=self.host, port=self.port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + return conn + + def _get_conn(self, timeout=None): + """ + Get a connection. Will return a pooled connection if one is available. + + If no connections are available and :prop:`.block` is ``False``, then a + fresh connection is returned. + + :param timeout: + Seconds to wait before giving up and raising + :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and + :prop:`.block` is ``True``. + """ + conn = None + try: + conn = self.pool.get(block=self.block, timeout=timeout) + + except AttributeError: # self.pool is None + raise ClosedPoolError(self, "Pool is closed.") + + except queue.Empty: + if self.block: + raise EmptyPoolError(self, + "Pool reached maximum size and no more " + "connections are allowed.") + pass # Oh well, we'll create a new connection then + + # If this is a persistent connection, check if it got disconnected + if conn and is_connection_dropped(conn): + log.debug("Resetting dropped connection: %s", self.host) + conn.close() + if getattr(conn, 'auto_open', 1) == 0: + # This is a proxied connection that has been mutated by + # httplib._tunnel() and cannot be reused (since it would + # attempt to bypass the proxy) + conn = None + + return conn or self._new_conn() + + def _put_conn(self, conn): + """ + Put a connection back into the pool. + + :param conn: + Connection object for the current host and port as returned by + :meth:`._new_conn` or :meth:`._get_conn`. + + If the pool is already full, the connection is closed and discarded + because we exceeded maxsize. If connections are discarded frequently, + then maxsize should be increased. + + If the pool is closed, then the connection will be closed and discarded. + """ + try: + self.pool.put(conn, block=False) + return # Everything is dandy, done. + except AttributeError: + # self.pool is None. + pass + except queue.Full: + # This should never happen if self.block == True + log.warning( + "Connection pool is full, discarding connection: %s", + self.host) + + # Connection never got put back into the pool, close it. + if conn: + conn.close() + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + pass + + def _prepare_proxy(self, conn): + # Nothing to do for HTTP connections. + pass + + def _get_timeout(self, timeout): + """ Helper that always returns a :class:`urllib3.util.Timeout` """ + if timeout is _Default: + return self.timeout.clone() + + if isinstance(timeout, Timeout): + return timeout.clone() + else: + # User passed us an int/float. This is for backwards compatibility, + # can be removed later + return Timeout.from_float(timeout) + + def _raise_timeout(self, err, url, timeout_value): + """Is the error actually a timeout? Will raise a ReadTimeout or pass""" + + if isinstance(err, SocketTimeout): + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # See the above comment about EAGAIN in Python 3. In Python 2 we have + # to specifically catch it and throw the timeout error + if hasattr(err, 'errno') and err.errno in _blocking_errnos: + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # Catch possible read timeouts thrown as SSL errors. If not the + # case, rethrow the original. We need to do this because of: + # http://bugs.python.org/issue10272 + if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6 + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + def _make_request(self, conn, method, url, timeout=_Default, chunked=False, + **httplib_request_kw): + """ + Perform a request on a given urllib connection object taken from our + pool. + + :param conn: + a connection from one of our connection pools + + :param timeout: + Socket timeout in seconds for the request. This can be a + float or integer, which will set the same timeout value for + the socket connect and the socket read, or an instance of + :class:`urllib3.util.Timeout`, which gives you more fine-grained + control over your timeouts. + """ + self.num_requests += 1 + + timeout_obj = self._get_timeout(timeout) + timeout_obj.start_connect() + conn.timeout = timeout_obj.connect_timeout + + # Trigger any extra validation we need to do. + try: + self._validate_conn(conn) + except (SocketTimeout, BaseSSLError) as e: + # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. + self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) + raise + + # conn.request() calls httplib.*.request, not the method in + # urllib3.request. It also calls makefile (recv) on the socket. + if chunked: + conn.request_chunked(method, url, **httplib_request_kw) + else: + conn.request(method, url, **httplib_request_kw) + + # Reset the timeout for the recv() on the socket + read_timeout = timeout_obj.read_timeout + + # App Engine doesn't have a sock attr + if getattr(conn, 'sock', None): + # In Python 3 socket.py will catch EAGAIN and return None when you + # try and read into the file pointer created by http.client, which + # instead raises a BadStatusLine exception. Instead of catching + # the exception and assuming all BadStatusLine exceptions are read + # timeouts, check for a zero timeout before making the request. + if read_timeout == 0: + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % read_timeout) + if read_timeout is Timeout.DEFAULT_TIMEOUT: + conn.sock.settimeout(socket.getdefaulttimeout()) + else: # None or a value + conn.sock.settimeout(read_timeout) + + # Receive the response from the server + try: + try: # Python 2.7, use buffering of HTTP responses + httplib_response = conn.getresponse(buffering=True) + except TypeError: # Python 2.6 and older, Python 3 + try: + httplib_response = conn.getresponse() + except Exception as e: + # Remove the TypeError from the exception chain in Python 3; + # otherwise it looks like a programming error was the cause. + six.raise_from(e, None) + except (SocketTimeout, BaseSSLError, SocketError) as e: + self._raise_timeout(err=e, url=url, timeout_value=read_timeout) + raise + + # AppEngine doesn't have a version attr. + http_version = getattr(conn, '_http_vsn_str', 'HTTP/?') + log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port, + method, url, http_version, httplib_response.status, + httplib_response.length) + + try: + assert_header_parsing(httplib_response.msg) + except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 + log.warning( + 'Failed to parse headers (url=%s): %s', + self._absolute_url(url), hpe, exc_info=True) + + return httplib_response + + def _absolute_url(self, path): + return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + # Disable access to the pool + old_pool, self.pool = self.pool, None + + try: + while True: + conn = old_pool.get(block=False) + if conn: + conn.close() + + except queue.Empty: + pass # Done. + + def is_same_host(self, url): + """ + Check if the given ``url`` is a member of the same host as this + connection pool. + """ + if url.startswith('/'): + return True + + # TODO: Add optional support for socket.gethostbyname checking. + scheme, host, port = get_host(url) + + host = _ipv6_host(host).lower() + + # Use explicit default port for comparison when none is given + if self.port and not port: + port = port_by_scheme.get(scheme) + elif not self.port and port == port_by_scheme.get(scheme): + port = None + + return (scheme, host, port) == (self.scheme, self.host, self.port) + + def urlopen(self, method, url, body=None, headers=None, retries=None, + redirect=True, assert_same_host=True, timeout=_Default, + pool_timeout=None, release_conn=None, chunked=False, + body_pos=None, **response_kw): + """ + Get a connection from the pool and perform an HTTP request. This is the + lowest level call for making a request, so you'll need to specify all + the raw details. + + .. note:: + + More commonly, it's appropriate to use a convenience method provided + by :class:`.RequestMethods`, such as :meth:`request`. + + .. note:: + + `release_conn` will only behave as expected if + `preload_content=False` because we want to make + `preload_content=False` the default behaviour someday soon without + breaking backwards compatibility. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param body: + Data to send in the request body (useful for creating + POST requests, see HTTPConnectionPool.post_url for + more convenience). + + :param headers: + Dictionary of custom headers to send, such as User-Agent, + If-None-Match, etc. If None, pool headers are used. If provided, + these headers completely replace any pool-specific headers. + + :param retries: + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + Pass ``None`` to retry until you receive a response. Pass a + :class:`~urllib3.util.retry.Retry` object for fine-grained control + over different types of retries. + Pass an integer number to retry connection errors that many times, + but no other types of errors. Pass zero to never retry. + + If ``False``, then retries are disabled and any exception is raised + immediately. Also, instead of raising a MaxRetryError on redirects, + the redirect response will be returned. + + :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. + + :param redirect: + If True, automatically handle redirects (status codes 301, 302, + 303, 307, 308). Each redirect counts as a retry. Disabling retries + will disable redirect, too. + + :param assert_same_host: + If ``True``, will make sure that the host of the pool requests is + consistent else will raise HostChangedError. When False, you can + use the pool on an HTTP proxy and request foreign hosts. + + :param timeout: + If specified, overrides the default timeout for this one + request. It may be a float (in seconds) or an instance of + :class:`urllib3.util.Timeout`. + + :param pool_timeout: + If set and the pool is set to block=True, then this method will + block for ``pool_timeout`` seconds and raise EmptyPoolError if no + connection is available within the time period. + + :param release_conn: + If False, then the urlopen call will not release the connection + back into the pool once a response is received (but will release if + you read the entire contents of the response such as when + `preload_content=True`). This is useful if you're not preloading + the response's content immediately. You will need to call + ``r.release_conn()`` on the response ``r`` to return the connection + back into the pool. If None, it takes the value of + ``response_kw.get('preload_content', True)``. + + :param chunked: + If True, urllib3 will send the body using chunked transfer + encoding. Otherwise, urllib3 will send the body using the standard + content-length form. Defaults to False. + + :param int body_pos: + Position to seek to in file-like body in the event of a retry or + redirect. Typically this won't need to be set because urllib3 will + auto-populate the value when needed. + + :param \\**response_kw: + Additional parameters are passed to + :meth:`urllib3.response.HTTPResponse.from_httplib` + """ + if headers is None: + headers = self.headers + + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) + + if release_conn is None: + release_conn = response_kw.get('preload_content', True) + + # Check host + if assert_same_host and not self.is_same_host(url): + raise HostChangedError(self, url, retries) + + conn = None + + # Track whether `conn` needs to be released before + # returning/raising/recursing. Update this variable if necessary, and + # leave `release_conn` constant throughout the function. That way, if + # the function recurses, the original value of `release_conn` will be + # passed down into the recursive call, and its value will be respected. + # + # See issue #651 [1] for details. + # + # [1] <https://github.com/shazow/urllib3/issues/651> + release_this_conn = release_conn + + # Merge the proxy headers. Only do this in HTTP. We have to copy the + # headers dict so we can safely change it without those changes being + # reflected in anyone else's copy. + if self.scheme == 'http': + headers = headers.copy() + headers.update(self.proxy_headers) + + # Must keep the exception bound to a separate variable or else Python 3 + # complains about UnboundLocalError. + err = None + + # Keep track of whether we cleanly exited the except block. This + # ensures we do proper cleanup in finally. + clean_exit = False + + # Rewind body position, if needed. Record current position + # for future rewinds in the event of a redirect/retry. + body_pos = set_file_position(body, body_pos) + + try: + # Request a connection from the queue. + timeout_obj = self._get_timeout(timeout) + conn = self._get_conn(timeout=pool_timeout) + + conn.timeout = timeout_obj.connect_timeout + + is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None) + if is_new_proxy_conn: + self._prepare_proxy(conn) + + # Make the request on the httplib connection object. + httplib_response = self._make_request(conn, method, url, + timeout=timeout_obj, + body=body, headers=headers, + chunked=chunked) + + # If we're going to release the connection in ``finally:``, then + # the response doesn't need to know about the connection. Otherwise + # it will also try to release it and we'll have a double-release + # mess. + response_conn = conn if not release_conn else None + + # Pass method to Response for length checking + response_kw['request_method'] = method + + # Import httplib's response into our own wrapper object + response = self.ResponseCls.from_httplib(httplib_response, + pool=self, + connection=response_conn, + retries=retries, + **response_kw) + + # Everything went great! + clean_exit = True + + except queue.Empty: + # Timed out by queue. + raise EmptyPoolError(self, "No pool connections are available.") + + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError, CertificateError) as e: + # Discard the connection for these exceptions. It will be + # replaced during the next _get_conn() call. + clean_exit = False + if isinstance(e, (BaseSSLError, CertificateError)): + e = SSLError(e) + elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: + e = ProxyError('Cannot connect to proxy.', e) + elif isinstance(e, (SocketError, HTTPException)): + e = ProtocolError('Connection aborted.', e) + + retries = retries.increment(method, url, error=e, _pool=self, + _stacktrace=sys.exc_info()[2]) + retries.sleep() + + # Keep track of the error for the retry warning. + err = e + + finally: + if not clean_exit: + # We hit some kind of exception, handled or otherwise. We need + # to throw the connection away unless explicitly told not to. + # Close the connection, set the variable to None, and make sure + # we put the None back in the pool to avoid leaking it. + conn = conn and conn.close() + release_this_conn = True + + if release_this_conn: + # Put the connection back to be reused. If the connection is + # expired then it will be None, which will get replaced with a + # fresh connection during _get_conn. + self._put_conn(conn) + + if not conn: + # Try again + log.warning("Retrying (%r) after connection " + "broken by '%r': %s", retries, err, url) + return self.urlopen(method, url, body, headers, retries, + redirect, assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + def drain_and_release_conn(response): + try: + # discard any remaining response body, the connection will be + # released back to the pool once the entire response is read + response.read() + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError) as e: + pass + + # Handle redirect? + redirect_location = redirect and response.get_redirect_location() + if redirect_location: + if response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep_for_retry(response) + log.debug("Redirecting %s -> %s", url, redirect_location) + return self.urlopen( + method, redirect_location, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(response.getheader('Retry-After')) + if retries.is_retry(method, response.status, has_retry_after): + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_status: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep(response) + log.debug("Retry: %s", url) + return self.urlopen( + method, url, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, + body_pos=body_pos, **response_kw) + + return response + + +class HTTPSConnectionPool(HTTPConnectionPool): + """ + Same as :class:`.HTTPConnectionPool`, but HTTPS. + + When Python is compiled with the :mod:`ssl` module, then + :class:`.VerifiedHTTPSConnection` is used, which *can* verify certificates, + instead of :class:`.HTTPSConnection`. + + :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``, + ``assert_hostname`` and ``host`` in this order to verify connections. + If ``assert_hostname`` is False, no verification is done. + + The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, + ``ca_cert_dir``, and ``ssl_version`` are only used if :mod:`ssl` is + available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade + the connection socket into an SSL socket. + """ + + scheme = 'https' + ConnectionCls = HTTPSConnection + + def __init__(self, host, port=None, + strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, + block=False, headers=None, retries=None, + _proxy=None, _proxy_headers=None, + key_file=None, cert_file=None, cert_reqs=None, + ca_certs=None, ssl_version=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None, **conn_kw): + + HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, + block, headers, retries, _proxy, _proxy_headers, + **conn_kw) + + if ca_certs and cert_reqs is None: + cert_reqs = 'CERT_REQUIRED' + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.ca_certs = ca_certs + self.ca_cert_dir = ca_cert_dir + self.ssl_version = ssl_version + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + + def _prepare_conn(self, conn): + """ + Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` + and establish the tunnel if proxy is used. + """ + + if isinstance(conn, VerifiedHTTPSConnection): + conn.set_cert(key_file=self.key_file, + cert_file=self.cert_file, + cert_reqs=self.cert_reqs, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + assert_hostname=self.assert_hostname, + assert_fingerprint=self.assert_fingerprint) + conn.ssl_version = self.ssl_version + return conn + + def _prepare_proxy(self, conn): + """ + Establish tunnel connection early, because otherwise httplib + would improperly set Host: header to proxy's IP:port. + """ + # Python 2.7+ + try: + set_tunnel = conn.set_tunnel + except AttributeError: # Platform-specific: Python 2.6 + set_tunnel = conn._set_tunnel + + if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older + set_tunnel(self._proxy_host, self.port) + else: + set_tunnel(self._proxy_host, self.port, self.proxy_headers) + + conn.connect() + + def _new_conn(self): + """ + Return a fresh :class:`httplib.HTTPSConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTPS connection (%d): %s", + self.num_connections, self.host) + + if not self.ConnectionCls or self.ConnectionCls is DummyConnection: + raise SSLError("Can't connect to HTTPS URL because the SSL " + "module is not available.") + + actual_host = self.host + actual_port = self.port + if self.proxy is not None: + actual_host = self.proxy.host + actual_port = self.proxy.port + + conn = self.ConnectionCls(host=actual_host, port=actual_port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + + return self._prepare_conn(conn) + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + super(HTTPSConnectionPool, self)._validate_conn(conn) + + # Force connect early to allow us to validate the connection. + if not getattr(conn, 'sock', None): # AppEngine might not have `.sock` + conn.connect() + + if not conn.is_verified: + warnings.warn(( + 'Unverified HTTPS request is being made. ' + 'Adding certificate verification is strongly advised. See: ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings'), + InsecureRequestWarning) + + +def connection_from_url(url, **kw): + """ + Given a url, return an :class:`.ConnectionPool` instance of its host. + + This is a shortcut for not having to parse out the scheme, host, and port + of the url before creating an :class:`.ConnectionPool` instance. + + :param url: + Absolute URL string that must include the scheme. Port is optional. + + :param \\**kw: + Passes additional parameters to the constructor of the appropriate + :class:`.ConnectionPool`. Useful for specifying things like + timeout, maxsize, headers, etc. + + Example:: + + >>> conn = connection_from_url('http://google.com/') + >>> r = conn.request('GET', '/') + """ + scheme, host, port = get_host(url) + port = port or port_by_scheme.get(scheme, 80) + if scheme == 'https': + return HTTPSConnectionPool(host, port=port, **kw) + else: + return HTTPConnectionPool(host, port=port, **kw) + + +def _ipv6_host(host): + """ + Process IPv6 address literals + """ + + # httplib doesn't like it when we include brackets in IPv6 addresses + # Specifically, if we include brackets but also pass the port then + # httplib crazily doubles up the square brackets on the Host header. + # Instead, we need to make sure we never pass ``None`` as the port. + # However, for backward compatibility reasons we can't actually + # *assert* that. See http://bugs.python.org/issue28539 + # + # Also if an IPv6 address literal has a zone identifier, the + # percent sign might be URIencoded, convert it back into ASCII + if host.startswith('[') and host.endswith(']'): + host = host.replace('%25', '%').strip('[]') + return host diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..a0f90a0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc new file mode 100644 index 0000000..d0109ea Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py new file mode 100644 index 0000000..bcf41c0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/bindings.py @@ -0,0 +1,593 @@ +""" +This module uses ctypes to bind a whole bunch of functions and constants from +SecureTransport. The goal here is to provide the low-level API to +SecureTransport. These are essentially the C-level functions and constants, and +they're pretty gross to work with. + +This code is a bastardised version of the code found in Will Bond's oscrypto +library. An enormous debt is owed to him for blazing this trail for us. For +that reason, this code should be considered to be covered both by urllib3's +license and by oscrypto's: + + Copyright (c) 2015-2016 Will Bond <will@wbond.net> + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +""" +from __future__ import absolute_import + +import platform +from ctypes.util import find_library +from ctypes import ( + c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_uint32, c_ulong, c_long, + c_bool +) +from ctypes import CDLL, POINTER, CFUNCTYPE + + +security_path = find_library('Security') +if not security_path: + raise ImportError('The library Security could not be found') + + +core_foundation_path = find_library('CoreFoundation') +if not core_foundation_path: + raise ImportError('The library CoreFoundation could not be found') + + +version = platform.mac_ver()[0] +version_info = tuple(map(int, version.split('.'))) +if version_info < (10, 8): + raise OSError( + 'Only OS X 10.8 and newer are supported, not %s.%s' % ( + version_info[0], version_info[1] + ) + ) + +Security = CDLL(security_path, use_errno=True) +CoreFoundation = CDLL(core_foundation_path, use_errno=True) + +Boolean = c_bool +CFIndex = c_long +CFStringEncoding = c_uint32 +CFData = c_void_p +CFString = c_void_p +CFArray = c_void_p +CFMutableArray = c_void_p +CFDictionary = c_void_p +CFError = c_void_p +CFType = c_void_p +CFTypeID = c_ulong + +CFTypeRef = POINTER(CFType) +CFAllocatorRef = c_void_p + +OSStatus = c_int32 + +CFDataRef = POINTER(CFData) +CFStringRef = POINTER(CFString) +CFArrayRef = POINTER(CFArray) +CFMutableArrayRef = POINTER(CFMutableArray) +CFDictionaryRef = POINTER(CFDictionary) +CFArrayCallBacks = c_void_p +CFDictionaryKeyCallBacks = c_void_p +CFDictionaryValueCallBacks = c_void_p + +SecCertificateRef = POINTER(c_void_p) +SecExternalFormat = c_uint32 +SecExternalItemType = c_uint32 +SecIdentityRef = POINTER(c_void_p) +SecItemImportExportFlags = c_uint32 +SecItemImportExportKeyParameters = c_void_p +SecKeychainRef = POINTER(c_void_p) +SSLProtocol = c_uint32 +SSLCipherSuite = c_uint32 +SSLContextRef = POINTER(c_void_p) +SecTrustRef = POINTER(c_void_p) +SSLConnectionRef = c_uint32 +SecTrustResultType = c_uint32 +SecTrustOptionFlags = c_uint32 +SSLProtocolSide = c_uint32 +SSLConnectionType = c_uint32 +SSLSessionOption = c_uint32 + + +try: + Security.SecItemImport.argtypes = [ + CFDataRef, + CFStringRef, + POINTER(SecExternalFormat), + POINTER(SecExternalItemType), + SecItemImportExportFlags, + POINTER(SecItemImportExportKeyParameters), + SecKeychainRef, + POINTER(CFArrayRef), + ] + Security.SecItemImport.restype = OSStatus + + Security.SecCertificateGetTypeID.argtypes = [] + Security.SecCertificateGetTypeID.restype = CFTypeID + + Security.SecIdentityGetTypeID.argtypes = [] + Security.SecIdentityGetTypeID.restype = CFTypeID + + Security.SecKeyGetTypeID.argtypes = [] + Security.SecKeyGetTypeID.restype = CFTypeID + + Security.SecCertificateCreateWithData.argtypes = [ + CFAllocatorRef, + CFDataRef + ] + Security.SecCertificateCreateWithData.restype = SecCertificateRef + + Security.SecCertificateCopyData.argtypes = [ + SecCertificateRef + ] + Security.SecCertificateCopyData.restype = CFDataRef + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SecIdentityCreateWithCertificate.argtypes = [ + CFTypeRef, + SecCertificateRef, + POINTER(SecIdentityRef) + ] + Security.SecIdentityCreateWithCertificate.restype = OSStatus + + Security.SecKeychainCreate.argtypes = [ + c_char_p, + c_uint32, + c_void_p, + Boolean, + c_void_p, + POINTER(SecKeychainRef) + ] + Security.SecKeychainCreate.restype = OSStatus + + Security.SecKeychainDelete.argtypes = [ + SecKeychainRef + ] + Security.SecKeychainDelete.restype = OSStatus + + Security.SecPKCS12Import.argtypes = [ + CFDataRef, + CFDictionaryRef, + POINTER(CFArrayRef) + ] + Security.SecPKCS12Import.restype = OSStatus + + SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) + SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) + + Security.SSLSetIOFuncs.argtypes = [ + SSLContextRef, + SSLReadFunc, + SSLWriteFunc + ] + Security.SSLSetIOFuncs.restype = OSStatus + + Security.SSLSetPeerID.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerID.restype = OSStatus + + Security.SSLSetCertificate.argtypes = [ + SSLContextRef, + CFArrayRef + ] + Security.SSLSetCertificate.restype = OSStatus + + Security.SSLSetCertificateAuthorities.argtypes = [ + SSLContextRef, + CFTypeRef, + Boolean + ] + Security.SSLSetCertificateAuthorities.restype = OSStatus + + Security.SSLSetConnection.argtypes = [ + SSLContextRef, + SSLConnectionRef + ] + Security.SSLSetConnection.restype = OSStatus + + Security.SSLSetPeerDomainName.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerDomainName.restype = OSStatus + + Security.SSLHandshake.argtypes = [ + SSLContextRef + ] + Security.SSLHandshake.restype = OSStatus + + Security.SSLRead.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLRead.restype = OSStatus + + Security.SSLWrite.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLWrite.restype = OSStatus + + Security.SSLClose.argtypes = [ + SSLContextRef + ] + Security.SSLClose.restype = OSStatus + + Security.SSLGetNumberSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberSupportedCiphers.restype = OSStatus + + Security.SSLGetSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetSupportedCiphers.restype = OSStatus + + Security.SSLSetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + c_size_t + ] + Security.SSLSetEnabledCiphers.restype = OSStatus + + Security.SSLGetNumberEnabledCiphers.argtype = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberEnabledCiphers.restype = OSStatus + + Security.SSLGetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetEnabledCiphers.restype = OSStatus + + Security.SSLGetNegotiatedCipher.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite) + ] + Security.SSLGetNegotiatedCipher.restype = OSStatus + + Security.SSLGetNegotiatedProtocolVersion.argtypes = [ + SSLContextRef, + POINTER(SSLProtocol) + ] + Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus + + Security.SSLCopyPeerTrust.argtypes = [ + SSLContextRef, + POINTER(SecTrustRef) + ] + Security.SSLCopyPeerTrust.restype = OSStatus + + Security.SecTrustSetAnchorCertificates.argtypes = [ + SecTrustRef, + CFArrayRef + ] + Security.SecTrustSetAnchorCertificates.restype = OSStatus + + Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ + SecTrustRef, + Boolean + ] + Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus + + Security.SecTrustEvaluate.argtypes = [ + SecTrustRef, + POINTER(SecTrustResultType) + ] + Security.SecTrustEvaluate.restype = OSStatus + + Security.SecTrustGetCertificateCount.argtypes = [ + SecTrustRef + ] + Security.SecTrustGetCertificateCount.restype = CFIndex + + Security.SecTrustGetCertificateAtIndex.argtypes = [ + SecTrustRef, + CFIndex + ] + Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef + + Security.SSLCreateContext.argtypes = [ + CFAllocatorRef, + SSLProtocolSide, + SSLConnectionType + ] + Security.SSLCreateContext.restype = SSLContextRef + + Security.SSLSetSessionOption.argtypes = [ + SSLContextRef, + SSLSessionOption, + Boolean + ] + Security.SSLSetSessionOption.restype = OSStatus + + Security.SSLSetProtocolVersionMin.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMin.restype = OSStatus + + Security.SSLSetProtocolVersionMax.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMax.restype = OSStatus + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SSLReadFunc = SSLReadFunc + Security.SSLWriteFunc = SSLWriteFunc + Security.SSLContextRef = SSLContextRef + Security.SSLProtocol = SSLProtocol + Security.SSLCipherSuite = SSLCipherSuite + Security.SecIdentityRef = SecIdentityRef + Security.SecKeychainRef = SecKeychainRef + Security.SecTrustRef = SecTrustRef + Security.SecTrustResultType = SecTrustResultType + Security.SecExternalFormat = SecExternalFormat + Security.OSStatus = OSStatus + + Security.kSecImportExportPassphrase = CFStringRef.in_dll( + Security, 'kSecImportExportPassphrase' + ) + Security.kSecImportItemIdentity = CFStringRef.in_dll( + Security, 'kSecImportItemIdentity' + ) + + # CoreFoundation time! + CoreFoundation.CFRetain.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRetain.restype = CFTypeRef + + CoreFoundation.CFRelease.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRelease.restype = None + + CoreFoundation.CFGetTypeID.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFGetTypeID.restype = CFTypeID + + CoreFoundation.CFStringCreateWithCString.argtypes = [ + CFAllocatorRef, + c_char_p, + CFStringEncoding + ] + CoreFoundation.CFStringCreateWithCString.restype = CFStringRef + + CoreFoundation.CFStringGetCStringPtr.argtypes = [ + CFStringRef, + CFStringEncoding + ] + CoreFoundation.CFStringGetCStringPtr.restype = c_char_p + + CoreFoundation.CFStringGetCString.argtypes = [ + CFStringRef, + c_char_p, + CFIndex, + CFStringEncoding + ] + CoreFoundation.CFStringGetCString.restype = c_bool + + CoreFoundation.CFDataCreate.argtypes = [ + CFAllocatorRef, + c_char_p, + CFIndex + ] + CoreFoundation.CFDataCreate.restype = CFDataRef + + CoreFoundation.CFDataGetLength.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetLength.restype = CFIndex + + CoreFoundation.CFDataGetBytePtr.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetBytePtr.restype = c_void_p + + CoreFoundation.CFDictionaryCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + POINTER(CFTypeRef), + CFIndex, + CFDictionaryKeyCallBacks, + CFDictionaryValueCallBacks + ] + CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef + + CoreFoundation.CFDictionaryGetValue.argtypes = [ + CFDictionaryRef, + CFTypeRef + ] + CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef + + CoreFoundation.CFArrayCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + CFIndex, + CFArrayCallBacks, + ] + CoreFoundation.CFArrayCreate.restype = CFArrayRef + + CoreFoundation.CFArrayCreateMutable.argtypes = [ + CFAllocatorRef, + CFIndex, + CFArrayCallBacks + ] + CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef + + CoreFoundation.CFArrayAppendValue.argtypes = [ + CFMutableArrayRef, + c_void_p + ] + CoreFoundation.CFArrayAppendValue.restype = None + + CoreFoundation.CFArrayGetCount.argtypes = [ + CFArrayRef + ] + CoreFoundation.CFArrayGetCount.restype = CFIndex + + CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ + CFArrayRef, + CFIndex + ] + CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p + + CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( + CoreFoundation, 'kCFAllocatorDefault' + ) + CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') + CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryKeyCallBacks' + ) + CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryValueCallBacks' + ) + + CoreFoundation.CFTypeRef = CFTypeRef + CoreFoundation.CFArrayRef = CFArrayRef + CoreFoundation.CFStringRef = CFStringRef + CoreFoundation.CFDictionaryRef = CFDictionaryRef + +except (AttributeError): + raise ImportError('Error initializing ctypes') + + +class CFConst(object): + """ + A class object that acts as essentially a namespace for CoreFoundation + constants. + """ + kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) + + +class SecurityConst(object): + """ + A class object that acts as essentially a namespace for Security constants. + """ + kSSLSessionOptionBreakOnServerAuth = 0 + + kSSLProtocol2 = 1 + kSSLProtocol3 = 2 + kTLSProtocol1 = 4 + kTLSProtocol11 = 7 + kTLSProtocol12 = 8 + + kSSLClientSide = 1 + kSSLStreamType = 0 + + kSecFormatPEMSequence = 10 + + kSecTrustResultInvalid = 0 + kSecTrustResultProceed = 1 + # This gap is present on purpose: this was kSecTrustResultConfirm, which + # is deprecated. + kSecTrustResultDeny = 3 + kSecTrustResultUnspecified = 4 + kSecTrustResultRecoverableTrustFailure = 5 + kSecTrustResultFatalTrustFailure = 6 + kSecTrustResultOtherError = 7 + + errSSLProtocol = -9800 + errSSLWouldBlock = -9803 + errSSLClosedGraceful = -9805 + errSSLClosedNoNotify = -9816 + errSSLClosedAbort = -9806 + + errSSLXCertChainInvalid = -9807 + errSSLCrypto = -9809 + errSSLInternal = -9810 + errSSLCertExpired = -9814 + errSSLCertNotYetValid = -9815 + errSSLUnknownRootCert = -9812 + errSSLNoRootCert = -9813 + errSSLHostNameMismatch = -9843 + errSSLPeerHandshakeFail = -9824 + errSSLPeerUserCancelled = -9839 + errSSLWeakPeerEphemeralDHKey = -9850 + errSSLServerAuthCompleted = -9841 + errSSLRecordOverflow = -9847 + + errSecVerifyFailed = -67808 + errSecNoTrustSettings = -25263 + errSecItemNotFound = -25300 + errSecInvalidTrustSettings = -25262 + + # Cipher suites. We only pick the ones our default cipher string allows. + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 + TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032 + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F + TLS_AES_128_GCM_SHA256 = 0x1301 + TLS_AES_256_GCM_SHA384 = 0x1302 + TLS_CHACHA20_POLY1305_SHA256 = 0x1303 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py new file mode 100644 index 0000000..5e3494b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/_securetransport/low_level.py @@ -0,0 +1,343 @@ +""" +Low-level helpers for the SecureTransport bindings. + +These are Python functions that are not directly related to the high-level APIs +but are necessary to get them to work. They include a whole bunch of low-level +CoreFoundation messing about and memory management. The concerns in this module +are almost entirely about trying to avoid memory leaks and providing +appropriate and useful assistance to the higher-level code. +""" +import base64 +import ctypes +import itertools +import re +import os +import ssl +import tempfile + +from .bindings import Security, CoreFoundation, CFConst + + +# This regular expression is used to grab PEM data out of a PEM bundle. +_PEM_CERTS_RE = re.compile( + b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL +) + + +def _cf_data_from_bytes(bytestring): + """ + Given a bytestring, create a CFData object from it. This CFData object must + be CFReleased by the caller. + """ + return CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) + ) + + +def _cf_dictionary_from_tuples(tuples): + """ + Given a list of Python tuples, create an associated CFDictionary. + """ + dictionary_size = len(tuples) + + # We need to get the dictionary keys and values out in the same order. + keys = (t[0] for t in tuples) + values = (t[1] for t in tuples) + cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) + cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) + + return CoreFoundation.CFDictionaryCreate( + CoreFoundation.kCFAllocatorDefault, + cf_keys, + cf_values, + dictionary_size, + CoreFoundation.kCFTypeDictionaryKeyCallBacks, + CoreFoundation.kCFTypeDictionaryValueCallBacks, + ) + + +def _cf_string_to_unicode(value): + """ + Creates a Unicode string from a CFString object. Used entirely for error + reporting. + + Yes, it annoys me quite a lot that this function is this complex. + """ + value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) + + string = CoreFoundation.CFStringGetCStringPtr( + value_as_void_p, + CFConst.kCFStringEncodingUTF8 + ) + if string is None: + buffer = ctypes.create_string_buffer(1024) + result = CoreFoundation.CFStringGetCString( + value_as_void_p, + buffer, + 1024, + CFConst.kCFStringEncodingUTF8 + ) + if not result: + raise OSError('Error copying C string from CFStringRef') + string = buffer.value + if string is not None: + string = string.decode('utf-8') + return string + + +def _assert_no_error(error, exception_class=None): + """ + Checks the return code and throws an exception if there is an error to + report + """ + if error == 0: + return + + cf_error_string = Security.SecCopyErrorMessageString(error, None) + output = _cf_string_to_unicode(cf_error_string) + CoreFoundation.CFRelease(cf_error_string) + + if output is None or output == u'': + output = u'OSStatus %s' % error + + if exception_class is None: + exception_class = ssl.SSLError + + raise exception_class(output) + + +def _cert_array_from_pem(pem_bundle): + """ + Given a bundle of certs in PEM format, turns them into a CFArray of certs + that can be used to validate a cert chain. + """ + der_certs = [ + base64.b64decode(match.group(1)) + for match in _PEM_CERTS_RE.finditer(pem_bundle) + ] + if not der_certs: + raise ssl.SSLError("No root certificates specified") + + cert_array = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks) + ) + if not cert_array: + raise ssl.SSLError("Unable to allocate memory!") + + try: + for der_bytes in der_certs: + certdata = _cf_data_from_bytes(der_bytes) + if not certdata: + raise ssl.SSLError("Unable to allocate memory!") + cert = Security.SecCertificateCreateWithData( + CoreFoundation.kCFAllocatorDefault, certdata + ) + CoreFoundation.CFRelease(certdata) + if not cert: + raise ssl.SSLError("Unable to build cert object!") + + CoreFoundation.CFArrayAppendValue(cert_array, cert) + CoreFoundation.CFRelease(cert) + except Exception: + # We need to free the array before the exception bubbles further. + # We only want to do that if an error occurs: otherwise, the caller + # should free. + CoreFoundation.CFRelease(cert_array) + + return cert_array + + +def _is_cert(item): + """ + Returns True if a given CFTypeRef is a certificate. + """ + expected = Security.SecCertificateGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _is_identity(item): + """ + Returns True if a given CFTypeRef is an identity. + """ + expected = Security.SecIdentityGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _temporary_keychain(): + """ + This function creates a temporary Mac keychain that we can use to work with + credentials. This keychain uses a one-time password and a temporary file to + store the data. We expect to have one keychain per socket. The returned + SecKeychainRef must be freed by the caller, including calling + SecKeychainDelete. + + Returns a tuple of the SecKeychainRef and the path to the temporary + directory that contains it. + """ + # Unfortunately, SecKeychainCreate requires a path to a keychain. This + # means we cannot use mkstemp to use a generic temporary file. Instead, + # we're going to create a temporary directory and a filename to use there. + # This filename will be 8 random bytes expanded into base64. We also need + # some random bytes to password-protect the keychain we're creating, so we + # ask for 40 random bytes. + random_bytes = os.urandom(40) + filename = base64.b64encode(random_bytes[:8]).decode('utf-8') + password = base64.b64encode(random_bytes[8:]) # Must be valid UTF-8 + tempdirectory = tempfile.mkdtemp() + + keychain_path = os.path.join(tempdirectory, filename).encode('utf-8') + + # We now want to create the keychain itself. + keychain = Security.SecKeychainRef() + status = Security.SecKeychainCreate( + keychain_path, + len(password), + password, + False, + None, + ctypes.byref(keychain) + ) + _assert_no_error(status) + + # Having created the keychain, we want to pass it off to the caller. + return keychain, tempdirectory + + +def _load_items_from_file(keychain, path): + """ + Given a single file, loads all the trust objects from it into arrays and + the keychain. + Returns a tuple of lists: the first list is a list of identities, the + second a list of certs. + """ + certificates = [] + identities = [] + result_array = None + + with open(path, 'rb') as f: + raw_filedata = f.read() + + try: + filedata = CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, + raw_filedata, + len(raw_filedata) + ) + result_array = CoreFoundation.CFArrayRef() + result = Security.SecItemImport( + filedata, # cert data + None, # Filename, leaving it out for now + None, # What the type of the file is, we don't care + None, # what's in the file, we don't care + 0, # import flags + None, # key params, can include passphrase in the future + keychain, # The keychain to insert into + ctypes.byref(result_array) # Results + ) + _assert_no_error(result) + + # A CFArray is not very useful to us as an intermediary + # representation, so we are going to extract the objects we want + # and then free the array. We don't need to keep hold of keys: the + # keychain already has them! + result_count = CoreFoundation.CFArrayGetCount(result_array) + for index in range(result_count): + item = CoreFoundation.CFArrayGetValueAtIndex( + result_array, index + ) + item = ctypes.cast(item, CoreFoundation.CFTypeRef) + + if _is_cert(item): + CoreFoundation.CFRetain(item) + certificates.append(item) + elif _is_identity(item): + CoreFoundation.CFRetain(item) + identities.append(item) + finally: + if result_array: + CoreFoundation.CFRelease(result_array) + + CoreFoundation.CFRelease(filedata) + + return (identities, certificates) + + +def _load_client_cert_chain(keychain, *paths): + """ + Load certificates and maybe keys from a number of files. Has the end goal + of returning a CFArray containing one SecIdentityRef, and then zero or more + SecCertificateRef objects, suitable for use as a client certificate trust + chain. + """ + # Ok, the strategy. + # + # This relies on knowing that macOS will not give you a SecIdentityRef + # unless you have imported a key into a keychain. This is a somewhat + # artificial limitation of macOS (for example, it doesn't necessarily + # affect iOS), but there is nothing inside Security.framework that lets you + # get a SecIdentityRef without having a key in a keychain. + # + # So the policy here is we take all the files and iterate them in order. + # Each one will use SecItemImport to have one or more objects loaded from + # it. We will also point at a keychain that macOS can use to work with the + # private key. + # + # Once we have all the objects, we'll check what we actually have. If we + # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, + # we'll take the first certificate (which we assume to be our leaf) and + # ask the keychain to give us a SecIdentityRef with that cert's associated + # key. + # + # We'll then return a CFArray containing the trust chain: one + # SecIdentityRef and then zero-or-more SecCertificateRef objects. The + # responsibility for freeing this CFArray will be with the caller. This + # CFArray must remain alive for the entire connection, so in practice it + # will be stored with a single SSLSocket, along with the reference to the + # keychain. + certificates = [] + identities = [] + + # Filter out bad paths. + paths = (path for path in paths if path) + + try: + for file_path in paths: + new_identities, new_certs = _load_items_from_file( + keychain, file_path + ) + identities.extend(new_identities) + certificates.extend(new_certs) + + # Ok, we have everything. The question is: do we have an identity? If + # not, we want to grab one from the first cert we have. + if not identities: + new_identity = Security.SecIdentityRef() + status = Security.SecIdentityCreateWithCertificate( + keychain, + certificates[0], + ctypes.byref(new_identity) + ) + _assert_no_error(status) + identities.append(new_identity) + + # We now want to release the original certificate, as we no longer + # need it. + CoreFoundation.CFRelease(certificates.pop(0)) + + # We now need to build a new CFArray that holds the trust chain. + trust_chain = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + for item in itertools.chain(identities, certificates): + # ArrayAppendValue does a CFRetain on the item. That's fine, + # because the finally block will release our other refs to them. + CoreFoundation.CFArrayAppendValue(trust_chain, item) + + return trust_chain + finally: + for obj in itertools.chain(identities, certificates): + CoreFoundation.CFRelease(obj) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py new file mode 100644 index 0000000..ce17e83 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/appengine.py @@ -0,0 +1,296 @@ +""" +This module provides a pool manager that uses Google App Engine's +`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + +Example usage:: + + from pip._vendor.urllib3 import PoolManager + from pip._vendor.urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox + + if is_appengine_sandbox(): + # AppEngineManager uses AppEngine's URLFetch API behind the scenes + http = AppEngineManager() + else: + # PoolManager uses a socket-level API behind the scenes + http = PoolManager() + + r = http.request('GET', 'https://google.com/') + +There are `limitations <https://cloud.google.com/appengine/docs/python/\ +urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be +the best choice for your application. There are three options for using +urllib3 on Google App Engine: + +1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is + cost-effective in many circumstances as long as your usage is within the + limitations. +2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. + Sockets also have `limitations and restrictions + <https://cloud.google.com/appengine/docs/python/sockets/\ + #limitations-and-restrictions>`_ and have a lower free quota than URLFetch. + To use sockets, be sure to specify the following in your ``app.yaml``:: + + env_variables: + GAE_USE_SOCKETS_HTTPLIB : 'true' + +3. If you are using `App Engine Flexible +<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard +:class:`PoolManager` without any configuration or special environment variables. +""" + +from __future__ import absolute_import +import logging +import os +import warnings +from ..packages.six.moves.urllib.parse import urljoin + +from ..exceptions import ( + HTTPError, + HTTPWarning, + MaxRetryError, + ProtocolError, + TimeoutError, + SSLError +) + +from ..packages.six import BytesIO +from ..request import RequestMethods +from ..response import HTTPResponse +from ..util.timeout import Timeout +from ..util.retry import Retry + +try: + from google.appengine.api import urlfetch +except ImportError: + urlfetch = None + + +log = logging.getLogger(__name__) + + +class AppEnginePlatformWarning(HTTPWarning): + pass + + +class AppEnginePlatformError(HTTPError): + pass + + +class AppEngineManager(RequestMethods): + """ + Connection manager for Google App Engine sandbox applications. + + This manager uses the URLFetch service directly instead of using the + emulated httplib, and is subject to URLFetch limitations as described in + the App Engine documentation `here + <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + + Notably it will raise an :class:`AppEnginePlatformError` if: + * URLFetch is not available. + * If you attempt to use this on App Engine Flexible, as full socket + support is available. + * If a request size is more than 10 megabytes. + * If a response size is more than 32 megabtyes. + * If you use an unsupported request method such as OPTIONS. + + Beyond those cases, it will raise normal urllib3 errors. + """ + + def __init__(self, headers=None, retries=None, validate_certificate=True, + urlfetch_retries=True): + if not urlfetch: + raise AppEnginePlatformError( + "URLFetch is not available in this environment.") + + if is_prod_appengine_mvms(): + raise AppEnginePlatformError( + "Use normal urllib3.PoolManager instead of AppEngineManager" + "on Managed VMs, as using URLFetch is not necessary in " + "this environment.") + + warnings.warn( + "urllib3 is using URLFetch on Google App Engine sandbox instead " + "of sockets. To use sockets directly instead of URLFetch see " + "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.", + AppEnginePlatformWarning) + + RequestMethods.__init__(self, headers) + self.validate_certificate = validate_certificate + self.urlfetch_retries = urlfetch_retries + + self.retries = retries or Retry.DEFAULT + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + # Return False to re-raise any potential exceptions + return False + + def urlopen(self, method, url, body=None, headers=None, + retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT, + **response_kw): + + retries = self._get_retries(retries, redirect) + + try: + follow_redirects = ( + redirect and + retries.redirect != 0 and + retries.total) + response = urlfetch.fetch( + url, + payload=body, + method=method, + headers=headers or {}, + allow_truncated=False, + follow_redirects=self.urlfetch_retries and follow_redirects, + deadline=self._get_absolute_timeout(timeout), + validate_certificate=self.validate_certificate, + ) + except urlfetch.DeadlineExceededError as e: + raise TimeoutError(self, e) + + except urlfetch.InvalidURLError as e: + if 'too large' in str(e): + raise AppEnginePlatformError( + "URLFetch request too large, URLFetch only " + "supports requests up to 10mb in size.", e) + raise ProtocolError(e) + + except urlfetch.DownloadError as e: + if 'Too many redirects' in str(e): + raise MaxRetryError(self, url, reason=e) + raise ProtocolError(e) + + except urlfetch.ResponseTooLargeError as e: + raise AppEnginePlatformError( + "URLFetch response too large, URLFetch only supports" + "responses up to 32mb in size.", e) + + except urlfetch.SSLCertificateError as e: + raise SSLError(e) + + except urlfetch.InvalidMethodError as e: + raise AppEnginePlatformError( + "URLFetch does not support method: %s" % method, e) + + http_response = self._urlfetch_response_to_http_response( + response, retries=retries, **response_kw) + + # Handle redirect? + redirect_location = redirect and http_response.get_redirect_location() + if redirect_location: + # Check for redirect response + if (self.urlfetch_retries and retries.raise_on_redirect): + raise MaxRetryError(self, url, "too many redirects") + else: + if http_response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=http_response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + raise MaxRetryError(self, url, "too many redirects") + return http_response + + retries.sleep_for_retry(http_response) + log.debug("Redirecting %s -> %s", url, redirect_location) + redirect_url = urljoin(url, redirect_location) + return self.urlopen( + method, redirect_url, body, headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(http_response.getheader('Retry-After')) + if retries.is_retry(method, http_response.status, has_retry_after): + retries = retries.increment( + method, url, response=http_response, _pool=self) + log.debug("Retry: %s", url) + retries.sleep(http_response) + return self.urlopen( + method, url, + body=body, headers=headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + return http_response + + def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): + + if is_prod_appengine(): + # Production GAE handles deflate encoding automatically, but does + # not remove the encoding header. + content_encoding = urlfetch_resp.headers.get('content-encoding') + + if content_encoding == 'deflate': + del urlfetch_resp.headers['content-encoding'] + + transfer_encoding = urlfetch_resp.headers.get('transfer-encoding') + # We have a full response's content, + # so let's make sure we don't report ourselves as chunked data. + if transfer_encoding == 'chunked': + encodings = transfer_encoding.split(",") + encodings.remove('chunked') + urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings) + + return HTTPResponse( + # In order for decoding to work, we must present the content as + # a file-like object. + body=BytesIO(urlfetch_resp.content), + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + **response_kw + ) + + def _get_absolute_timeout(self, timeout): + if timeout is Timeout.DEFAULT_TIMEOUT: + return None # Defer to URLFetch's default. + if isinstance(timeout, Timeout): + if timeout._read is not None or timeout._connect is not None: + warnings.warn( + "URLFetch does not support granular timeout settings, " + "reverting to total or default URLFetch timeout.", + AppEnginePlatformWarning) + return timeout.total + return timeout + + def _get_retries(self, retries, redirect): + if not isinstance(retries, Retry): + retries = Retry.from_int( + retries, redirect=redirect, default=self.retries) + + if retries.connect or retries.read or retries.redirect: + warnings.warn( + "URLFetch only supports total retries and does not " + "recognize connect, read, or redirect retry parameters.", + AppEnginePlatformWarning) + + return retries + + +def is_appengine(): + return (is_local_appengine() or + is_prod_appengine() or + is_prod_appengine_mvms()) + + +def is_appengine_sandbox(): + return is_appengine() and not is_prod_appengine_mvms() + + +def is_local_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Development/' in os.environ['SERVER_SOFTWARE']) + + +def is_prod_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and + not is_prod_appengine_mvms()) + + +def is_prod_appengine_mvms(): + return os.environ.get('GAE_VM', False) == 'true' diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py new file mode 100644 index 0000000..642e99e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/ntlmpool.py @@ -0,0 +1,112 @@ +""" +NTLM authenticating pool, contributed by erikcederstran + +Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 +""" +from __future__ import absolute_import + +from logging import getLogger +from ntlm import ntlm + +from .. import HTTPSConnectionPool +from ..packages.six.moves.http_client import HTTPSConnection + + +log = getLogger(__name__) + + +class NTLMConnectionPool(HTTPSConnectionPool): + """ + Implements an NTLM authentication version of an urllib3 connection pool + """ + + scheme = 'https' + + def __init__(self, user, pw, authurl, *args, **kwargs): + """ + authurl is a random URL on the server that is protected by NTLM. + user is the Windows user, probably in the DOMAIN\\username format. + pw is the password for the user. + """ + super(NTLMConnectionPool, self).__init__(*args, **kwargs) + self.authurl = authurl + self.rawuser = user + user_parts = user.split('\\', 1) + self.domain = user_parts[0].upper() + self.user = user_parts[1] + self.pw = pw + + def _new_conn(self): + # Performs the NTLM handshake that secures the connection. The socket + # must be kept open while requests are performed. + self.num_connections += 1 + log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s', + self.num_connections, self.host, self.authurl) + + headers = {} + headers['Connection'] = 'Keep-Alive' + req_header = 'Authorization' + resp_header = 'www-authenticate' + + conn = HTTPSConnection(host=self.host, port=self.port) + + # Send negotiation message + headers[req_header] = ( + 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser)) + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + reshdr = dict(res.getheaders()) + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', reshdr) + log.debug('Response data: %s [...]', res.read(100)) + + # Remove the reference to the socket, so that it can not be closed by + # the response object (we want to keep the socket open) + res.fp = None + + # Server should respond with a challenge message + auth_header_values = reshdr[resp_header].split(', ') + auth_header_value = None + for s in auth_header_values: + if s[:5] == 'NTLM ': + auth_header_value = s[5:] + if auth_header_value is None: + raise Exception('Unexpected %s response header: %s' % + (resp_header, reshdr[resp_header])) + + # Send authentication message + ServerChallenge, NegotiateFlags = \ + ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value) + auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, + self.user, + self.domain, + self.pw, + NegotiateFlags) + headers[req_header] = 'NTLM %s' % auth_msg + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', dict(res.getheaders())) + log.debug('Response data: %s [...]', res.read()[:100]) + if res.status != 200: + if res.status == 401: + raise Exception('Server rejected request: wrong ' + 'username or password') + raise Exception('Wrong server response: %s %s' % + (res.status, res.reason)) + + res.fp = None + log.debug('Connection established') + return conn + + def urlopen(self, method, url, body=None, headers=None, retries=3, + redirect=True, assert_same_host=True): + if headers is None: + headers = {} + headers['Connection'] = 'Keep-Alive' + return super(NTLMConnectionPool, self).urlopen(method, url, body, + headers, retries, + redirect, + assert_same_host) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py new file mode 100644 index 0000000..1bb3787 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/pyopenssl.py @@ -0,0 +1,455 @@ +""" +SSL with SNI_-support for Python 2. Follow these instructions if you would +like to verify SSL certificates in Python 2. Note, the default libraries do +*not* do certificate checking; you need to do additional work to validate +certificates yourself. + +This needs the following packages installed: + +* pyOpenSSL (tested with 16.0.0) +* cryptography (minimum 1.3.4, from pyopenssl) +* idna (minimum 2.0, from cryptography) + +However, pyopenssl depends on cryptography, which depends on idna, so while we +use all three directly here we end up having relatively few packages required. + +You can install them with the following command: + + pip install pyopenssl cryptography idna + +To activate certificate checking, call +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code +before you begin making HTTP requests. This can be done in a ``sitecustomize`` +module, or at any other time before your application begins using ``urllib3``, +like this:: + + try: + import urllib3.contrib.pyopenssl + urllib3.contrib.pyopenssl.inject_into_urllib3() + except ImportError: + pass + +Now you can use :mod:`urllib3` as you normally would, and it will support SNI +when the required modules are installed. + +Activating this module also has the positive side effect of disabling SSL/TLS +compression in Python 2 (see `CRIME attack`_). + +If you want to configure the default list of supported cipher suites, you can +set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. + +.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication +.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) +""" +from __future__ import absolute_import + +import OpenSSL.SSL +from cryptography import x509 +from cryptography.hazmat.backends.openssl import backend as openssl_backend +from cryptography.hazmat.backends.openssl.x509 import _Certificate + +from socket import timeout, error as SocketError +from io import BytesIO + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +import logging +import ssl +from ..packages import six +import sys + +from .. import util + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works. +HAS_SNI = True + +# Map from urllib3 to PyOpenSSL compatible parameter-values. +_openssl_versions = { + ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD, + ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, +} + +if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD + +if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD + +try: + _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD}) +except AttributeError: + pass + +_stdlib_to_openssl_verify = { + ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, + ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, + ssl.CERT_REQUIRED: + OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, +} +_openssl_to_stdlib_verify = dict( + (v, k) for k, v in _stdlib_to_openssl_verify.items() +) + +# OpenSSL will only write 16K at a time +SSL_WRITE_BLOCKSIZE = 16384 + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + + +log = logging.getLogger(__name__) + + +def inject_into_urllib3(): + 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' + + _validate_dependencies_met() + + util.ssl_.SSLContext = PyOpenSSLContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_PYOPENSSL = True + util.ssl_.IS_PYOPENSSL = True + + +def extract_from_urllib3(): + 'Undo monkey-patching by :func:`inject_into_urllib3`.' + + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_PYOPENSSL = False + util.ssl_.IS_PYOPENSSL = False + + +def _validate_dependencies_met(): + """ + Verifies that PyOpenSSL's package-level dependencies have been met. + Throws `ImportError` if they are not met. + """ + # Method added in `cryptography==1.1`; not available in older versions + from cryptography.x509.extensions import Extensions + if getattr(Extensions, "get_extension_for_class", None) is None: + raise ImportError("'cryptography' module missing required functionality. " + "Try upgrading to v1.3.4 or newer.") + + # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 + # attribute is only present on those versions. + from OpenSSL.crypto import X509 + x509 = X509() + if getattr(x509, "_x509", None) is None: + raise ImportError("'pyOpenSSL' module missing required functionality. " + "Try upgrading to v0.14 or newer.") + + +def _dnsname_to_stdlib(name): + """ + Converts a dNSName SubjectAlternativeName field to the form used by the + standard library on the given Python version. + + Cryptography produces a dNSName as a unicode string that was idna-decoded + from ASCII bytes. We need to idna-encode that string to get it back, and + then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib + uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). + """ + def idna_encode(name): + """ + Borrowed wholesale from the Python Cryptography Project. It turns out + that we can't just safely call `idna.encode`: it can explode for + wildcard names. This avoids that problem. + """ + from pip._vendor import idna + + for prefix in [u'*.', u'.']: + if name.startswith(prefix): + name = name[len(prefix):] + return prefix.encode('ascii') + idna.encode(name) + return idna.encode(name) + + name = idna_encode(name) + if sys.version_info >= (3, 0): + name = name.decode('utf-8') + return name + + +def get_subj_alt_name(peer_cert): + """ + Given an PyOpenSSL certificate, provides all the subject alternative names. + """ + # Pass the cert to cryptography, which has much better APIs for this. + if hasattr(peer_cert, "to_cryptography"): + cert = peer_cert.to_cryptography() + else: + # This is technically using private APIs, but should work across all + # relevant versions before PyOpenSSL got a proper API for this. + cert = _Certificate(openssl_backend, peer_cert._x509) + + # We want to find the SAN extension. Ask Cryptography to locate it (it's + # faster than looping in Python) + try: + ext = cert.extensions.get_extension_for_class( + x509.SubjectAlternativeName + ).value + except x509.ExtensionNotFound: + # No such extension, return the empty list. + return [] + except (x509.DuplicateExtension, x509.UnsupportedExtension, + x509.UnsupportedGeneralNameType, UnicodeError) as e: + # A problem has been found with the quality of the certificate. Assume + # no SAN field is present. + log.warning( + "A problem was encountered with the certificate that prevented " + "urllib3 from finding the SubjectAlternativeName field. This can " + "affect certificate validation. The error was %s", + e, + ) + return [] + + # We want to return dNSName and iPAddress fields. We need to cast the IPs + # back to strings because the match_hostname function wants them as + # strings. + # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 + # decoded. This is pretty frustrating, but that's what the standard library + # does with certificates, and so we need to attempt to do the same. + names = [ + ('DNS', _dnsname_to_stdlib(name)) + for name in ext.get_values_for_type(x509.DNSName) + ] + names.extend( + ('IP Address', str(name)) + for name in ext.get_values_for_type(x509.IPAddress) + ) + + return names + + +class WrappedSocket(object): + '''API-compatibility wrapper for Python OpenSSL's Connection-class. + + Note: _makefile_refs, _drop() and _reuse() are needed for the garbage + collector of pypy. + ''' + + def __init__(self, connection, socket, suppress_ragged_eofs=True): + self.connection = connection + self.socket = socket + self.suppress_ragged_eofs = suppress_ragged_eofs + self._makefile_refs = 0 + self._closed = False + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, *args, **kwargs): + try: + data = self.connection.recv(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return b'' + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return b'' + else: + raise + except OpenSSL.SSL.WantReadError: + rd = util.wait_for_read(self.socket, self.socket.gettimeout()) + if not rd: + raise timeout('The read operation timed out') + else: + return self.recv(*args, **kwargs) + else: + return data + + def recv_into(self, *args, **kwargs): + try: + return self.connection.recv_into(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return 0 + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return 0 + else: + raise + except OpenSSL.SSL.WantReadError: + rd = util.wait_for_read(self.socket, self.socket.gettimeout()) + if not rd: + raise timeout('The read operation timed out') + else: + return self.recv_into(*args, **kwargs) + + def settimeout(self, timeout): + return self.socket.settimeout(timeout) + + def _send_until_done(self, data): + while True: + try: + return self.connection.send(data) + except OpenSSL.SSL.WantWriteError: + wr = util.wait_for_write(self.socket, self.socket.gettimeout()) + if not wr: + raise timeout() + continue + except OpenSSL.SSL.SysCallError as e: + raise SocketError(str(e)) + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + # FIXME rethrow compatible exceptions should we ever use this + self.connection.shutdown() + + def close(self): + if self._makefile_refs < 1: + try: + self._closed = True + return self.connection.close() + except OpenSSL.SSL.Error: + return + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + x509 = self.connection.get_peer_certificate() + + if not x509: + return x509 + + if binary_form: + return OpenSSL.crypto.dump_certificate( + OpenSSL.crypto.FILETYPE_ASN1, + x509) + + return { + 'subject': ( + (('commonName', x509.get_subject().CN),), + ), + 'subjectAltName': get_subj_alt_name(x509) + } + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + makefile = backport_makefile + +WrappedSocket.makefile = makefile + + +class PyOpenSSLContext(object): + """ + I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible + for translating the interface of the standard library ``SSLContext`` object + to calls into PyOpenSSL. + """ + def __init__(self, protocol): + self.protocol = _openssl_versions[protocol] + self._ctx = OpenSSL.SSL.Context(self.protocol) + self._options = 0 + self.check_hostname = False + + @property + def options(self): + return self._options + + @options.setter + def options(self, value): + self._options = value + self._ctx.set_options(value) + + @property + def verify_mode(self): + return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] + + @verify_mode.setter + def verify_mode(self, value): + self._ctx.set_verify( + _stdlib_to_openssl_verify[value], + _verify_callback + ) + + def set_default_verify_paths(self): + self._ctx.set_default_verify_paths() + + def set_ciphers(self, ciphers): + if isinstance(ciphers, six.text_type): + ciphers = ciphers.encode('utf-8') + self._ctx.set_cipher_list(ciphers) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + if cafile is not None: + cafile = cafile.encode('utf-8') + if capath is not None: + capath = capath.encode('utf-8') + self._ctx.load_verify_locations(cafile, capath) + if cadata is not None: + self._ctx.load_verify_locations(BytesIO(cadata)) + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._ctx.use_certificate_file(certfile) + if password is not None: + self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password) + self._ctx.use_privatekey_file(keyfile or certfile) + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + cnx = OpenSSL.SSL.Connection(self._ctx, sock) + + if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 + server_hostname = server_hostname.encode('utf-8') + + if server_hostname is not None: + cnx.set_tlsext_host_name(server_hostname) + + cnx.set_connect_state() + + while True: + try: + cnx.do_handshake() + except OpenSSL.SSL.WantReadError: + rd = util.wait_for_read(sock, sock.gettimeout()) + if not rd: + raise timeout('select timed out') + continue + except OpenSSL.SSL.Error as e: + raise ssl.SSLError('bad handshake: %r' % e) + break + + return WrappedSocket(cnx, sock) + + +def _verify_callback(cnx, x509, err_no, err_depth, return_code): + return err_no == 0 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py new file mode 100644 index 0000000..2cac70f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/securetransport.py @@ -0,0 +1,810 @@ +""" +SecureTranport support for urllib3 via ctypes. + +This makes platform-native TLS available to urllib3 users on macOS without the +use of a compiler. This is an important feature because the Python Package +Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL +that ships with macOS is not capable of doing TLSv1.2. The only way to resolve +this is to give macOS users an alternative solution to the problem, and that +solution is to use SecureTransport. + +We use ctypes here because this solution must not require a compiler. That's +because pip is not allowed to require a compiler either. + +This is not intended to be a seriously long-term solution to this problem. +The hope is that PEP 543 will eventually solve this issue for us, at which +point we can retire this contrib module. But in the short term, we need to +solve the impending tire fire that is Python on Mac without this kind of +contrib module. So...here we are. + +To use this module, simply import and inject it:: + + import urllib3.contrib.securetransport + urllib3.contrib.securetransport.inject_into_urllib3() + +Happy TLSing! +""" +from __future__ import absolute_import + +import contextlib +import ctypes +import errno +import os.path +import shutil +import socket +import ssl +import threading +import weakref + +from .. import util +from ._securetransport.bindings import ( + Security, SecurityConst, CoreFoundation +) +from ._securetransport.low_level import ( + _assert_no_error, _cert_array_from_pem, _temporary_keychain, + _load_client_cert_chain +) + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +try: + memoryview(b'') +except NameError: + raise ImportError("SecureTransport only works on Pythons with memoryview") + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works +HAS_SNI = True + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + +# This dictionary is used by the read callback to obtain a handle to the +# calling wrapped socket. This is a pretty silly approach, but for now it'll +# do. I feel like I should be able to smuggle a handle to the wrapped socket +# directly in the SSLConnectionRef, but for now this approach will work I +# guess. +# +# We need to lock around this structure for inserts, but we don't do it for +# reads/writes in the callbacks. The reasoning here goes as follows: +# +# 1. It is not possible to call into the callbacks before the dictionary is +# populated, so once in the callback the id must be in the dictionary. +# 2. The callbacks don't mutate the dictionary, they only read from it, and +# so cannot conflict with any of the insertions. +# +# This is good: if we had to lock in the callbacks we'd drastically slow down +# the performance of this code. +_connection_refs = weakref.WeakValueDictionary() +_connection_ref_lock = threading.Lock() + +# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over +# for no better reason than we need *a* limit, and this one is right there. +SSL_WRITE_BLOCKSIZE = 16384 + +# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to +# individual cipher suites. We need to do this becuase this is how +# SecureTransport wants them. +CIPHER_SUITES = [ + SecurityConst.TLS_AES_256_GCM_SHA384, + SecurityConst.TLS_CHACHA20_POLY1305_SHA256, + SecurityConst.TLS_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, +] + +# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. +_protocol_to_min_max = { + ssl.PROTOCOL_SSLv23: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), +} + +if hasattr(ssl, "PROTOCOL_SSLv2"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( + SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2 + ) +if hasattr(ssl, "PROTOCOL_SSLv3"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( + SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3 + ) +if hasattr(ssl, "PROTOCOL_TLSv1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( + SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( + SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_2"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( + SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12 + ) +if hasattr(ssl, "PROTOCOL_TLS"): + _protocol_to_min_max[ssl.PROTOCOL_TLS] = _protocol_to_min_max[ssl.PROTOCOL_SSLv23] + + +def inject_into_urllib3(): + """ + Monkey-patch urllib3 with SecureTransport-backed SSL-support. + """ + util.ssl_.SSLContext = SecureTransportContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_SECURETRANSPORT = True + util.ssl_.IS_SECURETRANSPORT = True + + +def extract_from_urllib3(): + """ + Undo monkey-patching by :func:`inject_into_urllib3`. + """ + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_SECURETRANSPORT = False + util.ssl_.IS_SECURETRANSPORT = False + + +def _read_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport read callback. This is called by ST to request that data + be returned from the socket. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + requested_length = data_length_pointer[0] + + timeout = wrapped_socket.gettimeout() + error = None + read_count = 0 + buffer = (ctypes.c_char * requested_length).from_address(data_buffer) + buffer_view = memoryview(buffer) + + try: + while read_count < requested_length: + if timeout is None or timeout >= 0: + readables = util.wait_for_read([base_socket], timeout) + if not readables: + raise socket.error(errno.EAGAIN, 'timed out') + + # We need to tell ctypes that we have a buffer that can be + # written to. Upsettingly, we do that like this: + chunk_size = base_socket.recv_into( + buffer_view[read_count:requested_length] + ) + read_count += chunk_size + if not chunk_size: + if not read_count: + return SecurityConst.errSSLClosedGraceful + break + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + if error == errno.ECONNRESET: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = read_count + + if read_count != requested_length: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +def _write_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport write callback. This is called by ST to request that data + actually be sent on the network. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + bytes_to_write = data_length_pointer[0] + data = ctypes.string_at(data_buffer, bytes_to_write) + + timeout = wrapped_socket.gettimeout() + error = None + sent = 0 + + try: + while sent < bytes_to_write: + if timeout is None or timeout >= 0: + writables = util.wait_for_write([base_socket], timeout) + if not writables: + raise socket.error(errno.EAGAIN, 'timed out') + chunk_sent = base_socket.send(data) + sent += chunk_sent + + # This has some needless copying here, but I'm not sure there's + # much value in optimising this data path. + data = data[chunk_sent:] + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + if error == errno.ECONNRESET: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = sent + if sent != bytes_to_write: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +# We need to keep these two objects references alive: if they get GC'd while +# in use then SecureTransport could attempt to call a function that is in freed +# memory. That would be...uh...bad. Yeah, that's the word. Bad. +_read_callback_pointer = Security.SSLReadFunc(_read_callback) +_write_callback_pointer = Security.SSLWriteFunc(_write_callback) + + +class WrappedSocket(object): + """ + API-compatibility wrapper for Python's OpenSSL wrapped socket object. + + Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage + collector of PyPy. + """ + def __init__(self, socket): + self.socket = socket + self.context = None + self._makefile_refs = 0 + self._closed = False + self._exception = None + self._keychain = None + self._keychain_dir = None + self._client_cert_chain = None + + # We save off the previously-configured timeout and then set it to + # zero. This is done because we use select and friends to handle the + # timeouts, but if we leave the timeout set on the lower socket then + # Python will "kindly" call select on that socket again for us. Avoid + # that by forcing the timeout to zero. + self._timeout = self.socket.gettimeout() + self.socket.settimeout(0) + + @contextlib.contextmanager + def _raise_on_error(self): + """ + A context manager that can be used to wrap calls that do I/O from + SecureTransport. If any of the I/O callbacks hit an exception, this + context manager will correctly propagate the exception after the fact. + This avoids silently swallowing those exceptions. + + It also correctly forces the socket closed. + """ + self._exception = None + + # We explicitly don't catch around this yield because in the unlikely + # event that an exception was hit in the block we don't want to swallow + # it. + yield + if self._exception is not None: + exception, self._exception = self._exception, None + self.close() + raise exception + + def _set_ciphers(self): + """ + Sets up the allowed ciphers. By default this matches the set in + util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done + custom and doesn't allow changing at this time, mostly because parsing + OpenSSL cipher strings is going to be a freaking nightmare. + """ + ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) + result = Security.SSLSetEnabledCiphers( + self.context, ciphers, len(CIPHER_SUITES) + ) + _assert_no_error(result) + + def _custom_validate(self, verify, trust_bundle): + """ + Called when we have set custom validation. We do this in two cases: + first, when cert validation is entirely disabled; and second, when + using a custom trust DB. + """ + # If we disabled cert validation, just say: cool. + if not verify: + return + + # We want data in memory, so load it up. + if os.path.isfile(trust_bundle): + with open(trust_bundle, 'rb') as f: + trust_bundle = f.read() + + cert_array = None + trust = Security.SecTrustRef() + + try: + # Get a CFArray that contains the certs we want. + cert_array = _cert_array_from_pem(trust_bundle) + + # Ok, now the hard part. We want to get the SecTrustRef that ST has + # created for this connection, shove our CAs into it, tell ST to + # ignore everything else it knows, and then ask if it can build a + # chain. This is a buuuunch of code. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + raise ssl.SSLError("Failed to copy trust reference") + + result = Security.SecTrustSetAnchorCertificates(trust, cert_array) + _assert_no_error(result) + + result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) + _assert_no_error(result) + + trust_result = Security.SecTrustResultType() + result = Security.SecTrustEvaluate( + trust, ctypes.byref(trust_result) + ) + _assert_no_error(result) + finally: + if trust: + CoreFoundation.CFRelease(trust) + + if cert_array is None: + CoreFoundation.CFRelease(cert_array) + + # Ok, now we can look at what the result was. + successes = ( + SecurityConst.kSecTrustResultUnspecified, + SecurityConst.kSecTrustResultProceed + ) + if trust_result.value not in successes: + raise ssl.SSLError( + "certificate verify failed, error code: %d" % + trust_result.value + ) + + def handshake(self, + server_hostname, + verify, + trust_bundle, + min_version, + max_version, + client_cert, + client_key, + client_key_passphrase): + """ + Actually performs the TLS handshake. This is run automatically by + wrapped socket, and shouldn't be needed in user code. + """ + # First, we do the initial bits of connection setup. We need to create + # a context, set its I/O funcs, and set the connection reference. + self.context = Security.SSLCreateContext( + None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType + ) + result = Security.SSLSetIOFuncs( + self.context, _read_callback_pointer, _write_callback_pointer + ) + _assert_no_error(result) + + # Here we need to compute the handle to use. We do this by taking the + # id of self modulo 2**31 - 1. If this is already in the dictionary, we + # just keep incrementing by one until we find a free space. + with _connection_ref_lock: + handle = id(self) % 2147483647 + while handle in _connection_refs: + handle = (handle + 1) % 2147483647 + _connection_refs[handle] = self + + result = Security.SSLSetConnection(self.context, handle) + _assert_no_error(result) + + # If we have a server hostname, we should set that too. + if server_hostname: + if not isinstance(server_hostname, bytes): + server_hostname = server_hostname.encode('utf-8') + + result = Security.SSLSetPeerDomainName( + self.context, server_hostname, len(server_hostname) + ) + _assert_no_error(result) + + # Setup the ciphers. + self._set_ciphers() + + # Set the minimum and maximum TLS versions. + result = Security.SSLSetProtocolVersionMin(self.context, min_version) + _assert_no_error(result) + result = Security.SSLSetProtocolVersionMax(self.context, max_version) + _assert_no_error(result) + + # If there's a trust DB, we need to use it. We do that by telling + # SecureTransport to break on server auth. We also do that if we don't + # want to validate the certs at all: we just won't actually do any + # authing in that case. + if not verify or trust_bundle is not None: + result = Security.SSLSetSessionOption( + self.context, + SecurityConst.kSSLSessionOptionBreakOnServerAuth, + True + ) + _assert_no_error(result) + + # If there's a client cert, we need to use it. + if client_cert: + self._keychain, self._keychain_dir = _temporary_keychain() + self._client_cert_chain = _load_client_cert_chain( + self._keychain, client_cert, client_key + ) + result = Security.SSLSetCertificate( + self.context, self._client_cert_chain + ) + _assert_no_error(result) + + while True: + with self._raise_on_error(): + result = Security.SSLHandshake(self.context) + + if result == SecurityConst.errSSLWouldBlock: + raise socket.timeout("handshake timed out") + elif result == SecurityConst.errSSLServerAuthCompleted: + self._custom_validate(verify, trust_bundle) + continue + else: + _assert_no_error(result) + break + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, bufsiz): + buffer = ctypes.create_string_buffer(bufsiz) + bytes_read = self.recv_into(buffer, bufsiz) + data = buffer[:bytes_read] + return data + + def recv_into(self, buffer, nbytes=None): + # Read short on EOF. + if self._closed: + return 0 + + if nbytes is None: + nbytes = len(buffer) + + buffer = (ctypes.c_char * nbytes).from_buffer(buffer) + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLRead( + self.context, buffer, nbytes, ctypes.byref(processed_bytes) + ) + + # There are some result codes that we want to treat as "not always + # errors". Specifically, those are errSSLWouldBlock, + # errSSLClosedGraceful, and errSSLClosedNoNotify. + if (result == SecurityConst.errSSLWouldBlock): + # If we didn't process any bytes, then this was just a time out. + # However, we can get errSSLWouldBlock in situations when we *did* + # read some data, and in those cases we should just read "short" + # and return. + if processed_bytes.value == 0: + # Timed out, no data read. + raise socket.timeout("recv timed out") + elif result in (SecurityConst.errSSLClosedGraceful, SecurityConst.errSSLClosedNoNotify): + # The remote peer has closed this connection. We should do so as + # well. Note that we don't actually return here because in + # principle this could actually be fired along with return data. + # It's unlikely though. + self.close() + else: + _assert_no_error(result) + + # Ok, we read and probably succeeded. We should return whatever data + # was actually read. + return processed_bytes.value + + def settimeout(self, timeout): + self._timeout = timeout + + def gettimeout(self): + return self._timeout + + def send(self, data): + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLWrite( + self.context, data, len(data), ctypes.byref(processed_bytes) + ) + + if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: + # Timed out + raise socket.timeout("send timed out") + else: + _assert_no_error(result) + + # We sent, and probably succeeded. Tell them how much we sent. + return processed_bytes.value + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + with self._raise_on_error(): + Security.SSLClose(self.context) + + def close(self): + # TODO: should I do clean shutdown here? Do I have to? + if self._makefile_refs < 1: + self._closed = True + if self.context: + CoreFoundation.CFRelease(self.context) + self.context = None + if self._client_cert_chain: + CoreFoundation.CFRelease(self._client_cert_chain) + self._client_cert_chain = None + if self._keychain: + Security.SecKeychainDelete(self._keychain) + CoreFoundation.CFRelease(self._keychain) + shutil.rmtree(self._keychain_dir) + self._keychain = self._keychain_dir = None + return self.socket.close() + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + # Urgh, annoying. + # + # Here's how we do this: + # + # 1. Call SSLCopyPeerTrust to get hold of the trust object for this + # connection. + # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. + # 3. To get the CN, call SecCertificateCopyCommonName and process that + # string so that it's of the appropriate type. + # 4. To get the SAN, we need to do something a bit more complex: + # a. Call SecCertificateCopyValues to get the data, requesting + # kSecOIDSubjectAltName. + # b. Mess about with this dictionary to try to get the SANs out. + # + # This is gross. Really gross. It's going to be a few hundred LoC extra + # just to repeat something that SecureTransport can *already do*. So my + # operating assumption at this time is that what we want to do is + # instead to just flag to urllib3 that it shouldn't do its own hostname + # validation when using SecureTransport. + if not binary_form: + raise ValueError( + "SecureTransport only supports dumping binary certs" + ) + trust = Security.SecTrustRef() + certdata = None + der_bytes = None + + try: + # Grab the trust store. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + # Probably we haven't done the handshake yet. No biggie. + return None + + cert_count = Security.SecTrustGetCertificateCount(trust) + if not cert_count: + # Also a case that might happen if we haven't handshaked. + # Handshook? Handshaken? + return None + + leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) + assert leaf + + # Ok, now we want the DER bytes. + certdata = Security.SecCertificateCopyData(leaf) + assert certdata + + data_length = CoreFoundation.CFDataGetLength(certdata) + data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) + der_bytes = ctypes.string_at(data_buffer, data_length) + finally: + if certdata: + CoreFoundation.CFRelease(certdata) + if trust: + CoreFoundation.CFRelease(trust) + + return der_bytes + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + def makefile(self, mode="r", buffering=None, *args, **kwargs): + # We disable buffering with SecureTransport because it conflicts with + # the buffering that ST does internally (see issue #1153 for more). + buffering = 0 + return backport_makefile(self, mode, buffering, *args, **kwargs) + +WrappedSocket.makefile = makefile + + +class SecureTransportContext(object): + """ + I am a wrapper class for the SecureTransport library, to translate the + interface of the standard library ``SSLContext`` object to calls into + SecureTransport. + """ + def __init__(self, protocol): + self._min_version, self._max_version = _protocol_to_min_max[protocol] + self._options = 0 + self._verify = False + self._trust_bundle = None + self._client_cert = None + self._client_key = None + self._client_key_passphrase = None + + @property + def check_hostname(self): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + return True + + @check_hostname.setter + def check_hostname(self, value): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + pass + + @property + def options(self): + # TODO: Well, crap. + # + # So this is the bit of the code that is the most likely to cause us + # trouble. Essentially we need to enumerate all of the SSL options that + # users might want to use and try to see if we can sensibly translate + # them, or whether we should just ignore them. + return self._options + + @options.setter + def options(self, value): + # TODO: Update in line with above. + self._options = value + + @property + def verify_mode(self): + return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE + + @verify_mode.setter + def verify_mode(self, value): + self._verify = True if value == ssl.CERT_REQUIRED else False + + def set_default_verify_paths(self): + # So, this has to do something a bit weird. Specifically, what it does + # is nothing. + # + # This means that, if we had previously had load_verify_locations + # called, this does not undo that. We need to do that because it turns + # out that the rest of the urllib3 code will attempt to load the + # default verify paths if it hasn't been told about any paths, even if + # the context itself was sometime earlier. We resolve that by just + # ignoring it. + pass + + def load_default_certs(self): + return self.set_default_verify_paths() + + def set_ciphers(self, ciphers): + # For now, we just require the default cipher string. + if ciphers != util.ssl_.DEFAULT_CIPHERS: + raise ValueError( + "SecureTransport doesn't support custom cipher strings" + ) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + # OK, we only really support cadata and cafile. + if capath is not None: + raise ValueError( + "SecureTransport does not support cert directories" + ) + + self._trust_bundle = cafile or cadata + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._client_cert = certfile + self._client_key = keyfile + self._client_cert_passphrase = password + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + # So, what do we do here? Firstly, we assert some properties. This is a + # stripped down shim, so there is some functionality we don't support. + # See PEP 543 for the real deal. + assert not server_side + assert do_handshake_on_connect + assert suppress_ragged_eofs + + # Ok, we're good to go. Now we want to create the wrapped socket object + # and store it in the appropriate place. + wrapped_socket = WrappedSocket(sock) + + # Now we can handshake + wrapped_socket.handshake( + server_hostname, self._verify, self._trust_bundle, + self._min_version, self._max_version, self._client_cert, + self._client_key, self._client_key_passphrase + ) + return wrapped_socket diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py new file mode 100644 index 0000000..39e92fd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/contrib/socks.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +""" +This module contains provisional support for SOCKS proxies from within +urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and +SOCKS5. To enable its functionality, either install PySocks or install this +module with the ``socks`` extra. + +The SOCKS implementation supports the full range of urllib3 features. It also +supports the following SOCKS features: + +- SOCKS4 +- SOCKS4a +- SOCKS5 +- Usernames and passwords for the SOCKS proxy + +Known Limitations: + +- Currently PySocks does not support contacting remote websites via literal + IPv6 addresses. Any such connection attempt will fail. You must use a domain + name. +- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any + such connection attempt will fail. +""" +from __future__ import absolute_import + +try: + import socks +except ImportError: + import warnings + from ..exceptions import DependencyWarning + + warnings.warn(( + 'SOCKS support in urllib3 requires the installation of optional ' + 'dependencies: specifically, PySocks. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies' + ), + DependencyWarning + ) + raise + +from socket import error as SocketError, timeout as SocketTimeout + +from ..connection import ( + HTTPConnection, HTTPSConnection +) +from ..connectionpool import ( + HTTPConnectionPool, HTTPSConnectionPool +) +from ..exceptions import ConnectTimeoutError, NewConnectionError +from ..poolmanager import PoolManager +from ..util.url import parse_url + +try: + import ssl +except ImportError: + ssl = None + + +class SOCKSConnection(HTTPConnection): + """ + A plain-text HTTP connection that connects via a SOCKS proxy. + """ + def __init__(self, *args, **kwargs): + self._socks_options = kwargs.pop('_socks_options') + super(SOCKSConnection, self).__init__(*args, **kwargs) + + def _new_conn(self): + """ + Establish a new connection via the SOCKS proxy. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = socks.create_connection( + (self.host, self.port), + proxy_type=self._socks_options['socks_version'], + proxy_addr=self._socks_options['proxy_host'], + proxy_port=self._socks_options['proxy_port'], + proxy_username=self._socks_options['username'], + proxy_password=self._socks_options['password'], + proxy_rdns=self._socks_options['rdns'], + timeout=self.timeout, + **extra_kw + ) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except socks.ProxyError as e: + # This is fragile as hell, but it seems to be the only way to raise + # useful errors here. + if e.socket_err: + error = e.socket_err + if isinstance(error, SocketTimeout): + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout) + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % error + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % e + ) + + except SocketError as e: # Defensive: PySocks should catch all these. + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + +# We don't need to duplicate the Verified/Unverified distinction from +# urllib3/connection.py here because the HTTPSConnection will already have been +# correctly set to either the Verified or Unverified form by that module. This +# means the SOCKSHTTPSConnection will automatically be the correct type. +class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): + pass + + +class SOCKSHTTPConnectionPool(HTTPConnectionPool): + ConnectionCls = SOCKSConnection + + +class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): + ConnectionCls = SOCKSHTTPSConnection + + +class SOCKSProxyManager(PoolManager): + """ + A version of the urllib3 ProxyManager that routes connections via the + defined SOCKS proxy. + """ + pool_classes_by_scheme = { + 'http': SOCKSHTTPConnectionPool, + 'https': SOCKSHTTPSConnectionPool, + } + + def __init__(self, proxy_url, username=None, password=None, + num_pools=10, headers=None, **connection_pool_kw): + parsed = parse_url(proxy_url) + + if parsed.scheme == 'socks5': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = False + elif parsed.scheme == 'socks5h': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = True + elif parsed.scheme == 'socks4': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = False + elif parsed.scheme == 'socks4a': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = True + else: + raise ValueError( + "Unable to determine SOCKS version from %s" % proxy_url + ) + + self.proxy_url = proxy_url + + socks_options = { + 'socks_version': socks_version, + 'proxy_host': parsed.host, + 'proxy_port': parsed.port, + 'username': username, + 'password': password, + 'rdns': rdns + } + connection_pool_kw['_socks_options'] = socks_options + + super(SOCKSProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw + ) + + self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/exceptions.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/exceptions.py new file mode 100644 index 0000000..6c4be58 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/exceptions.py @@ -0,0 +1,246 @@ +from __future__ import absolute_import +from .packages.six.moves.http_client import ( + IncompleteRead as httplib_IncompleteRead +) +# Base Exceptions + + +class HTTPError(Exception): + "Base exception used by this module." + pass + + +class HTTPWarning(Warning): + "Base warning used by this module." + pass + + +class PoolError(HTTPError): + "Base exception for errors caused within a pool." + def __init__(self, pool, message): + self.pool = pool + HTTPError.__init__(self, "%s: %s" % (pool, message)) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, None) + + +class RequestError(PoolError): + "Base exception for PoolErrors that have associated URLs." + def __init__(self, pool, url, message): + self.url = url + PoolError.__init__(self, pool, message) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, self.url, None) + + +class SSLError(HTTPError): + "Raised when SSL certificate fails in an HTTPS connection." + pass + + +class ProxyError(HTTPError): + "Raised when the connection to a proxy fails." + pass + + +class DecodeError(HTTPError): + "Raised when automatic decoding based on Content-Type fails." + pass + + +class ProtocolError(HTTPError): + "Raised when something unexpected happens mid-request/response." + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + +# Leaf Exceptions + +class MaxRetryError(RequestError): + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ + + def __init__(self, pool, url, reason=None): + self.reason = reason + + message = "Max retries exceeded with url: %s (Caused by %r)" % ( + url, reason) + + RequestError.__init__(self, pool, url, message) + + +class HostChangedError(RequestError): + "Raised when an existing pool gets a request for a foreign host." + + def __init__(self, pool, url, retries=3): + message = "Tried to open a foreign host with url: %s" % url + RequestError.__init__(self, pool, url, message) + self.retries = retries + + +class TimeoutStateError(HTTPError): + """ Raised when passing an invalid state to a timeout """ + pass + + +class TimeoutError(HTTPError): + """ Raised when a socket timeout error occurs. + + Catching this error will catch both :exc:`ReadTimeoutErrors + <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`. + """ + pass + + +class ReadTimeoutError(TimeoutError, RequestError): + "Raised when a socket timeout occurs while receiving data from a server" + pass + + +# This timeout error does not have a URL attached and needs to inherit from the +# base HTTPError +class ConnectTimeoutError(TimeoutError): + "Raised when a socket timeout occurs while connecting to a server" + pass + + +class NewConnectionError(ConnectTimeoutError, PoolError): + "Raised when we fail to establish a new connection. Usually ECONNREFUSED." + pass + + +class EmptyPoolError(PoolError): + "Raised when a pool runs out of connections and no more are allowed." + pass + + +class ClosedPoolError(PoolError): + "Raised when a request enters a pool after the pool has been closed." + pass + + +class LocationValueError(ValueError, HTTPError): + "Raised when there is something wrong with a given URL input." + pass + + +class LocationParseError(LocationValueError): + "Raised when get_host or similar fails to parse the URL input." + + def __init__(self, location): + message = "Failed to parse: %s" % location + HTTPError.__init__(self, message) + + self.location = location + + +class ResponseError(HTTPError): + "Used as a container for an error reason supplied in a MaxRetryError." + GENERIC_ERROR = 'too many error responses' + SPECIFIC_ERROR = 'too many {status_code} error responses' + + +class SecurityWarning(HTTPWarning): + "Warned when perfoming security reducing actions" + pass + + +class SubjectAltNameWarning(SecurityWarning): + "Warned when connecting to a host with a certificate missing a SAN." + pass + + +class InsecureRequestWarning(SecurityWarning): + "Warned when making an unverified HTTPS request." + pass + + +class SystemTimeWarning(SecurityWarning): + "Warned when system time is suspected to be wrong" + pass + + +class InsecurePlatformWarning(SecurityWarning): + "Warned when certain SSL configuration is not available on a platform." + pass + + +class SNIMissingWarning(HTTPWarning): + "Warned when making a HTTPS request without SNI available." + pass + + +class DependencyWarning(HTTPWarning): + """ + Warned when an attempt is made to import a module with missing optional + dependencies. + """ + pass + + +class ResponseNotChunked(ProtocolError, ValueError): + "Response needs to be chunked in order to read it as chunks." + pass + + +class BodyNotHttplibCompatible(HTTPError): + """ + Body should be httplib.HTTPResponse like (have an fp attribute which + returns raw chunks) for read_chunked(). + """ + pass + + +class IncompleteRead(HTTPError, httplib_IncompleteRead): + """ + Response length doesn't match expected Content-Length + + Subclass of http_client.IncompleteRead to allow int value + for `partial` to avoid creating large objects on streamed + reads. + """ + def __init__(self, partial, expected): + super(IncompleteRead, self).__init__(partial, expected) + + def __repr__(self): + return ('IncompleteRead(%i bytes read, ' + '%i more expected)' % (self.partial, self.expected)) + + +class InvalidHeader(HTTPError): + "The header provided was somehow invalid." + pass + + +class ProxySchemeUnknown(AssertionError, ValueError): + "ProxyManager does not support the supplied scheme" + # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. + + def __init__(self, scheme): + message = "Not supported proxy scheme %s" % scheme + super(ProxySchemeUnknown, self).__init__(message) + + +class HeaderParsingError(HTTPError): + "Raised by assert_header_parsing, but we convert it to a log.warning statement." + def __init__(self, defects, unparsed_data): + message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) + super(HeaderParsingError, self).__init__(message) + + +class UnrewindableBodyError(HTTPError): + "urllib3 encountered an error when trying to rewind a body" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/fields.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/fields.py new file mode 100644 index 0000000..19b0ae0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/fields.py @@ -0,0 +1,178 @@ +from __future__ import absolute_import +import email.utils +import mimetypes + +from .packages import six + + +def guess_content_type(filename, default='application/octet-stream'): + """ + Guess the "Content-Type" of a file. + + :param filename: + The filename to guess the "Content-Type" of using :mod:`mimetypes`. + :param default: + If no "Content-Type" can be guessed, default to `default`. + """ + if filename: + return mimetypes.guess_type(filename)[0] or default + return default + + +def format_header_param(name, value): + """ + Helper function to format and quote a single header parameter. + + Particularly useful for header parameters which might contain + non-ASCII values, like file names. This follows RFC 2231, as + suggested by RFC 2388 Section 4.4. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + if not any(ch in value for ch in '"\\\r\n'): + result = '%s="%s"' % (name, value) + try: + result.encode('ascii') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + return result + if not six.PY3 and isinstance(value, six.text_type): # Python 2: + value = value.encode('utf-8') + value = email.utils.encode_rfc2231(value, 'utf-8') + value = '%s*=%s' % (name, value) + return value + + +class RequestField(object): + """ + A data container for request body parameters. + + :param name: + The name of this request field. + :param data: + The data/value body. + :param filename: + An optional filename of the request field. + :param headers: + An optional dict-like object of headers to initially use for the field. + """ + def __init__(self, name, data, filename=None, headers=None): + self._name = name + self._filename = filename + self.data = data + self.headers = {} + if headers: + self.headers = dict(headers) + + @classmethod + def from_tuples(cls, fieldname, value): + """ + A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. + + Supports constructing :class:`~urllib3.fields.RequestField` from + parameter of key/value strings AND key/filetuple. A filetuple is a + (filename, data, MIME type) tuple where the MIME type is optional. + For example:: + + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + + Field names and filenames must be unicode. + """ + if isinstance(value, tuple): + if len(value) == 3: + filename, data, content_type = value + else: + filename, data = value + content_type = guess_content_type(filename) + else: + filename = None + content_type = None + data = value + + request_param = cls(fieldname, data, filename=filename) + request_param.make_multipart(content_type=content_type) + + return request_param + + def _render_part(self, name, value): + """ + Overridable helper function to format a single header parameter. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + return format_header_param(name, value) + + def _render_parts(self, header_parts): + """ + Helper function to format and quote a single header. + + Useful for single headers that are composed of multiple items. E.g., + 'Content-Disposition' fields. + + :param header_parts: + A sequence of (k, v) typles or a :class:`dict` of (k, v) to format + as `k1="v1"; k2="v2"; ...`. + """ + parts = [] + iterable = header_parts + if isinstance(header_parts, dict): + iterable = header_parts.items() + + for name, value in iterable: + if value is not None: + parts.append(self._render_part(name, value)) + + return '; '.join(parts) + + def render_headers(self): + """ + Renders the headers for this request field. + """ + lines = [] + + sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] + for sort_key in sort_keys: + if self.headers.get(sort_key, False): + lines.append('%s: %s' % (sort_key, self.headers[sort_key])) + + for header_name, header_value in self.headers.items(): + if header_name not in sort_keys: + if header_value: + lines.append('%s: %s' % (header_name, header_value)) + + lines.append('\r\n') + return '\r\n'.join(lines) + + def make_multipart(self, content_disposition=None, content_type=None, + content_location=None): + """ + Makes this request field into a multipart request field. + + This method overrides "Content-Disposition", "Content-Type" and + "Content-Location" headers to the request parameter. + + :param content_type: + The 'Content-Type' of the request body. + :param content_location: + The 'Content-Location' of the request body. + + """ + self.headers['Content-Disposition'] = content_disposition or 'form-data' + self.headers['Content-Disposition'] += '; '.join([ + '', self._render_parts( + (('name', self._name), ('filename', self._filename)) + ) + ]) + self.headers['Content-Type'] = content_type + self.headers['Content-Location'] = content_location diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/filepost.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/filepost.py new file mode 100644 index 0000000..cd11cee --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/filepost.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import +import codecs + +from uuid import uuid4 +from io import BytesIO + +from .packages import six +from .packages.six import b +from .fields import RequestField + +writer = codecs.lookup('utf-8')[3] + + +def choose_boundary(): + """ + Our embarrassingly-simple replacement for mimetools.choose_boundary. + """ + return uuid4().hex + + +def iter_field_objects(fields): + """ + Iterate over fields. + + Supports list of (k, v) tuples and dicts, and lists of + :class:`~urllib3.fields.RequestField`. + + """ + if isinstance(fields, dict): + i = six.iteritems(fields) + else: + i = iter(fields) + + for field in i: + if isinstance(field, RequestField): + yield field + else: + yield RequestField.from_tuples(*field) + + +def iter_fields(fields): + """ + .. deprecated:: 1.6 + + Iterate over fields. + + The addition of :class:`~urllib3.fields.RequestField` makes this function + obsolete. Instead, use :func:`iter_field_objects`, which returns + :class:`~urllib3.fields.RequestField` objects. + + Supports list of (k, v) tuples and dicts. + """ + if isinstance(fields, dict): + return ((k, v) for k, v in six.iteritems(fields)) + + return ((k, v) for k, v in fields) + + +def encode_multipart_formdata(fields, boundary=None): + """ + Encode a dictionary of ``fields`` using the multipart/form-data MIME format. + + :param fields: + Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). + + :param boundary: + If not specified, then a random boundary will be generated using + :func:`mimetools.choose_boundary`. + """ + body = BytesIO() + if boundary is None: + boundary = choose_boundary() + + for field in iter_field_objects(fields): + body.write(b('--%s\r\n' % (boundary))) + + writer(body).write(field.render_headers()) + data = field.data + + if isinstance(data, int): + data = str(data) # Backwards compatibility + + if isinstance(data, six.text_type): + writer(body).write(data) + else: + body.write(data) + + body.write(b'\r\n') + + body.write(b('--%s--\r\n' % (boundary))) + + content_type = str('multipart/form-data; boundary=%s' % boundary) + + return body.getvalue(), content_type diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py new file mode 100644 index 0000000..170e974 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from . import ssl_match_hostname + +__all__ = ('ssl_match_hostname', ) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..04415f0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000..4889e49 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py new file mode 100644 index 0000000..75b80dc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/backports/makefile.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +backports.makefile +~~~~~~~~~~~~~~~~~~ + +Backports the Python 3 ``socket.makefile`` method for use with anything that +wants to create a "fake" socket object. +""" +import io + +from socket import SocketIO + + +def backport_makefile(self, mode="r", buffering=None, encoding=None, + errors=None, newline=None): + """ + Backport of ``socket.makefile`` from Python 3.5. + """ + if not set(mode) <= set(["r", "w", "b"]): + raise ValueError( + "invalid mode %r (only r, w, b allowed)" % (mode,) + ) + writing = "w" in mode + reading = "r" in mode or not writing + assert reading or writing + binary = "b" in mode + rawmode = "" + if reading: + rawmode += "r" + if writing: + rawmode += "w" + raw = SocketIO(self, rawmode) + self._makefile_refs += 1 + if buffering is None: + buffering = -1 + if buffering < 0: + buffering = io.DEFAULT_BUFFER_SIZE + if buffering == 0: + if not binary: + raise ValueError("unbuffered streams must be binary") + return raw + if reading and writing: + buffer = io.BufferedRWPair(raw, raw, buffering) + elif reading: + buffer = io.BufferedReader(raw, buffering) + else: + assert writing + buffer = io.BufferedWriter(raw, buffering) + if binary: + return buffer + text = io.TextIOWrapper(buffer, encoding, errors, newline) + text.mode = mode + return text diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ordered_dict.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ordered_dict.py new file mode 100644 index 0000000..4479363 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ordered_dict.py @@ -0,0 +1,259 @@ +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. +# Copyright 2009 Raymond Hettinger, released under the MIT License. +# http://code.activestate.com/recipes/576693/ +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/six.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py new file mode 100644 index 0000000..d6594eb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py @@ -0,0 +1,19 @@ +import sys + +try: + # Our match_hostname function is the same as 3.5's, so we only want to + # import the match_hostname function if it's at least that good. + if sys.version_info < (3, 5): + raise ImportError("Fallback to vendored code") + + from ssl import CertificateError, match_hostname +except ImportError: + try: + # Backport of the function from a pypi module + from backports.ssl_match_hostname import CertificateError, match_hostname + except ImportError: + # Our vendored copy + from ._implementation import CertificateError, match_hostname + +# Not needed, but documenting what we provide. +__all__ = ('CertificateError', 'match_hostname') diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..92ea723 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py new file mode 100644 index 0000000..92c9bc7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py @@ -0,0 +1,157 @@ +"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" + +# Note: This file is under the PSF license as the code comes from the python +# stdlib. http://docs.python.org/3/license.html + +import re +import sys + +# ipaddress has been backported to 2.6+ in pypi. If it is installed on the +# system, use it to handle IPAddress ServerAltnames (this was added in +# python-3.5) otherwise only do DNS matching. This allows +# backports.ssl_match_hostname to continue to be used all the way back to +# python-2.4. +try: + from pip._vendor import ipaddress +except ImportError: + ipaddress = None + +__version__ = '3.5.0.1' + + +class CertificateError(ValueError): + pass + + +def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r'.') + leftmost = parts[0] + remainder = parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + +def _to_unicode(obj): + if isinstance(obj, str) and sys.version_info < (3,): + obj = unicode(obj, encoding='ascii', errors='strict') + return obj + +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + # Divergence from upstream: ipaddress can't handle byte str + ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) + return ip == host_ip + + +def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + try: + # Divergence from upstream: ipaddress can't handle byte str + host_ip = ipaddress.ip_address(_to_unicode(hostname)) + except ValueError: + # Not an IP address (common case) + host_ip = None + except UnicodeError: + # Divergence from upstream: Have to deal with ipaddress not taking + # byte strings. addresses should be all ascii, so we consider it not + # an ipaddress in this case + host_ip = None + except AttributeError: + # Divergence from upstream: Make ipaddress library optional + if ipaddress is None: + host_ip = None + else: + raise + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + elif key == 'IP Address': + if host_ip is not None and _ipaddress_match(value, host_ip): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/poolmanager.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/poolmanager.py new file mode 100644 index 0000000..4ae9174 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/poolmanager.py @@ -0,0 +1,440 @@ +from __future__ import absolute_import +import collections +import functools +import logging + +from ._collections import RecentlyUsedContainer +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool +from .connectionpool import port_by_scheme +from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown +from .packages.six.moves.urllib.parse import urljoin +from .request import RequestMethods +from .util.url import parse_url +from .util.retry import Retry + + +__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url'] + + +log = logging.getLogger(__name__) + +SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs', + 'ssl_version', 'ca_cert_dir', 'ssl_context') + +# All known keyword arguments that could be provided to the pool manager, its +# pools, or the underlying connections. This is used to construct a pool key. +_key_fields = ( + 'key_scheme', # str + 'key_host', # str + 'key_port', # int + 'key_timeout', # int or float or Timeout + 'key_retries', # int or Retry + 'key_strict', # bool + 'key_block', # bool + 'key_source_address', # str + 'key_key_file', # str + 'key_cert_file', # str + 'key_cert_reqs', # str + 'key_ca_certs', # str + 'key_ssl_version', # str + 'key_ca_cert_dir', # str + 'key_ssl_context', # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext + 'key_maxsize', # int + 'key_headers', # dict + 'key__proxy', # parsed proxy url + 'key__proxy_headers', # dict + 'key_socket_options', # list of (level (int), optname (int), value (int or str)) tuples + 'key__socks_options', # dict + 'key_assert_hostname', # bool or string + 'key_assert_fingerprint', # str +) + +#: The namedtuple class used to construct keys for the connection pool. +#: All custom key schemes should include the fields in this key at a minimum. +PoolKey = collections.namedtuple('PoolKey', _key_fields) + + +def _default_key_normalizer(key_class, request_context): + """ + Create a pool key out of a request context dictionary. + + According to RFC 3986, both the scheme and host are case-insensitive. + Therefore, this function normalizes both before constructing the pool + key for an HTTPS request. If you wish to change this behaviour, provide + alternate callables to ``key_fn_by_scheme``. + + :param key_class: + The class to use when constructing the key. This should be a namedtuple + with the ``scheme`` and ``host`` keys at a minimum. + :type key_class: namedtuple + :param request_context: + A dictionary-like object that contain the context for a request. + :type request_context: dict + + :return: A namedtuple that can be used as a connection pool key. + :rtype: PoolKey + """ + # Since we mutate the dictionary, make a copy first + context = request_context.copy() + context['scheme'] = context['scheme'].lower() + context['host'] = context['host'].lower() + + # These are both dictionaries and need to be transformed into frozensets + for key in ('headers', '_proxy_headers', '_socks_options'): + if key in context and context[key] is not None: + context[key] = frozenset(context[key].items()) + + # The socket_options key may be a list and needs to be transformed into a + # tuple. + socket_opts = context.get('socket_options') + if socket_opts is not None: + context['socket_options'] = tuple(socket_opts) + + # Map the kwargs to the names in the namedtuple - this is necessary since + # namedtuples can't have fields starting with '_'. + for key in list(context.keys()): + context['key_' + key] = context.pop(key) + + # Default to ``None`` for keys missing from the context + for field in key_class._fields: + if field not in context: + context[field] = None + + return key_class(**context) + + +#: A dictionary that maps a scheme to a callable that creates a pool key. +#: This can be used to alter the way pool keys are constructed, if desired. +#: Each PoolManager makes a copy of this dictionary so they can be configured +#: globally here, or individually on the instance. +key_fn_by_scheme = { + 'http': functools.partial(_default_key_normalizer, PoolKey), + 'https': functools.partial(_default_key_normalizer, PoolKey), +} + +pool_classes_by_scheme = { + 'http': HTTPConnectionPool, + 'https': HTTPSConnectionPool, +} + + +class PoolManager(RequestMethods): + """ + Allows for arbitrary requests while transparently keeping track of + necessary connection pools for you. + + :param num_pools: + Number of connection pools to cache before discarding the least + recently used pool. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param \\**connection_pool_kw: + Additional parameters are used to create fresh + :class:`urllib3.connectionpool.ConnectionPool` instances. + + Example:: + + >>> manager = PoolManager(num_pools=2) + >>> r = manager.request('GET', 'http://google.com/') + >>> r = manager.request('GET', 'http://google.com/mail') + >>> r = manager.request('GET', 'http://yahoo.com/') + >>> len(manager.pools) + 2 + + """ + + proxy = None + + def __init__(self, num_pools=10, headers=None, **connection_pool_kw): + RequestMethods.__init__(self, headers) + self.connection_pool_kw = connection_pool_kw + self.pools = RecentlyUsedContainer(num_pools, + dispose_func=lambda p: p.close()) + + # Locally set the pool classes and keys so other PoolManagers can + # override them. + self.pool_classes_by_scheme = pool_classes_by_scheme + self.key_fn_by_scheme = key_fn_by_scheme.copy() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.clear() + # Return False to re-raise any potential exceptions + return False + + def _new_pool(self, scheme, host, port, request_context=None): + """ + Create a new :class:`ConnectionPool` based on host, port, scheme, and + any additional pool keyword arguments. + + If ``request_context`` is provided, it is provided as keyword arguments + to the pool class used. This method is used to actually create the + connection pools handed out by :meth:`connection_from_url` and + companion methods. It is intended to be overridden for customization. + """ + pool_cls = self.pool_classes_by_scheme[scheme] + if request_context is None: + request_context = self.connection_pool_kw.copy() + + # Although the context has everything necessary to create the pool, + # this function has historically only used the scheme, host, and port + # in the positional args. When an API change is acceptable these can + # be removed. + for key in ('scheme', 'host', 'port'): + request_context.pop(key, None) + + if scheme == 'http': + for kw in SSL_KEYWORDS: + request_context.pop(kw, None) + + return pool_cls(host, port, **request_context) + + def clear(self): + """ + Empty our store of pools and direct them all to close. + + This will not affect in-flight connections, but they will not be + re-used after completion. + """ + self.pools.clear() + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + """ + Get a :class:`ConnectionPool` based on the host, port, and scheme. + + If ``port`` isn't given, it will be derived from the ``scheme`` using + ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is + provided, it is merged with the instance's ``connection_pool_kw`` + variable and used to create the new connection pool, if one is + needed. + """ + + if not host: + raise LocationValueError("No host specified.") + + request_context = self._merge_pool_kwargs(pool_kwargs) + request_context['scheme'] = scheme or 'http' + if not port: + port = port_by_scheme.get(request_context['scheme'].lower(), 80) + request_context['port'] = port + request_context['host'] = host + + return self.connection_from_context(request_context) + + def connection_from_context(self, request_context): + """ + Get a :class:`ConnectionPool` based on the request context. + + ``request_context`` must at least contain the ``scheme`` key and its + value must be a key in ``key_fn_by_scheme`` instance variable. + """ + scheme = request_context['scheme'].lower() + pool_key_constructor = self.key_fn_by_scheme[scheme] + pool_key = pool_key_constructor(request_context) + + return self.connection_from_pool_key(pool_key, request_context=request_context) + + def connection_from_pool_key(self, pool_key, request_context=None): + """ + Get a :class:`ConnectionPool` based on the provided pool key. + + ``pool_key`` should be a namedtuple that only contains immutable + objects. At a minimum it must have the ``scheme``, ``host``, and + ``port`` fields. + """ + with self.pools.lock: + # If the scheme, host, or port doesn't match existing open + # connections, open a new ConnectionPool. + pool = self.pools.get(pool_key) + if pool: + return pool + + # Make a fresh ConnectionPool of the desired type + scheme = request_context['scheme'] + host = request_context['host'] + port = request_context['port'] + pool = self._new_pool(scheme, host, port, request_context=request_context) + self.pools[pool_key] = pool + + return pool + + def connection_from_url(self, url, pool_kwargs=None): + """ + Similar to :func:`urllib3.connectionpool.connection_from_url`. + + If ``pool_kwargs`` is not provided and a new pool needs to be + constructed, ``self.connection_pool_kw`` is used to initialize + the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` + is provided, it is used instead. Note that if a new pool does not + need to be created for the request, the provided ``pool_kwargs`` are + not used. + """ + u = parse_url(url) + return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, + pool_kwargs=pool_kwargs) + + def _merge_pool_kwargs(self, override): + """ + Merge a dictionary of override values for self.connection_pool_kw. + + This does not modify self.connection_pool_kw and returns a new dict. + Any keys in the override dictionary with a value of ``None`` are + removed from the merged dictionary. + """ + base_pool_kwargs = self.connection_pool_kw.copy() + if override: + for key, value in override.items(): + if value is None: + try: + del base_pool_kwargs[key] + except KeyError: + pass + else: + base_pool_kwargs[key] = value + return base_pool_kwargs + + def urlopen(self, method, url, redirect=True, **kw): + """ + Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen` + with custom cross-host redirect logic and only sends the request-uri + portion of the ``url``. + + The given ``url`` parameter must be absolute, such that an appropriate + :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. + """ + u = parse_url(url) + conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) + + kw['assert_same_host'] = False + kw['redirect'] = False + if 'headers' not in kw: + kw['headers'] = self.headers + + if self.proxy is not None and u.scheme == "http": + response = conn.urlopen(method, url, **kw) + else: + response = conn.urlopen(method, u.request_uri, **kw) + + redirect_location = redirect and response.get_redirect_location() + if not redirect_location: + return response + + # Support relative URLs for redirecting. + redirect_location = urljoin(url, redirect_location) + + # RFC 7231, Section 6.4.4 + if response.status == 303: + method = 'GET' + + retries = kw.get('retries') + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) + except MaxRetryError: + if retries.raise_on_redirect: + raise + return response + + kw['retries'] = retries + kw['redirect'] = redirect + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method, redirect_location, **kw) + + +class ProxyManager(PoolManager): + """ + Behaves just like :class:`PoolManager`, but sends all requests through + the defined proxy, using the CONNECT method for HTTPS URLs. + + :param proxy_url: + The URL of the proxy to be used. + + :param proxy_headers: + A dictionary contaning headers that will be sent to the proxy. In case + of HTTP they are being sent with each request, while in the + HTTPS/CONNECT case they are sent only once. Could be used for proxy + authentication. + + Example: + >>> proxy = urllib3.ProxyManager('http://localhost:3128/') + >>> r1 = proxy.request('GET', 'http://google.com/') + >>> r2 = proxy.request('GET', 'http://httpbin.org/') + >>> len(proxy.pools) + 1 + >>> r3 = proxy.request('GET', 'https://httpbin.org/') + >>> r4 = proxy.request('GET', 'https://twitter.com/') + >>> len(proxy.pools) + 3 + + """ + + def __init__(self, proxy_url, num_pools=10, headers=None, + proxy_headers=None, **connection_pool_kw): + + if isinstance(proxy_url, HTTPConnectionPool): + proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host, + proxy_url.port) + proxy = parse_url(proxy_url) + if not proxy.port: + port = port_by_scheme.get(proxy.scheme, 80) + proxy = proxy._replace(port=port) + + if proxy.scheme not in ("http", "https"): + raise ProxySchemeUnknown(proxy.scheme) + + self.proxy = proxy + self.proxy_headers = proxy_headers or {} + + connection_pool_kw['_proxy'] = self.proxy + connection_pool_kw['_proxy_headers'] = self.proxy_headers + + super(ProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw) + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + if scheme == "https": + return super(ProxyManager, self).connection_from_host( + host, port, scheme, pool_kwargs=pool_kwargs) + + return super(ProxyManager, self).connection_from_host( + self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs) + + def _set_proxy_headers(self, url, headers=None): + """ + Sets headers needed by proxies: specifically, the Accept and Host + headers. Only sets headers not provided by the user. + """ + headers_ = {'Accept': '*/*'} + + netloc = parse_url(url).netloc + if netloc: + headers_['Host'] = netloc + + if headers: + headers_.update(headers) + return headers_ + + def urlopen(self, method, url, redirect=True, **kw): + "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." + u = parse_url(url) + + if u.scheme == "http": + # For proxied HTTPS requests, httplib sets the necessary headers + # on the CONNECT to the proxy. For HTTP, we'll definitely + # need to set 'Host' at the very least. + headers = kw.get('headers', self.headers) + kw['headers'] = self._set_proxy_headers(url, headers) + + return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) + + +def proxy_from_url(url, **kw): + return ProxyManager(proxy_url=url, **kw) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/request.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/request.py new file mode 100644 index 0000000..c0fddff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/request.py @@ -0,0 +1,148 @@ +from __future__ import absolute_import + +from .filepost import encode_multipart_formdata +from .packages.six.moves.urllib.parse import urlencode + + +__all__ = ['RequestMethods'] + + +class RequestMethods(object): + """ + Convenience mixin for classes who implement a :meth:`urlopen` method, such + as :class:`~urllib3.connectionpool.HTTPConnectionPool` and + :class:`~urllib3.poolmanager.PoolManager`. + + Provides behavior for making common types of HTTP request methods and + decides which type of request field encoding to use. + + Specifically, + + :meth:`.request_encode_url` is for sending requests whose fields are + encoded in the URL (such as GET, HEAD, DELETE). + + :meth:`.request_encode_body` is for sending requests whose fields are + encoded in the *body* of the request using multipart or www-form-urlencoded + (such as for POST, PUT, PATCH). + + :meth:`.request` is for making any kind of request, it will look up the + appropriate encoding format and use one of the above two methods to make + the request. + + Initializer parameters: + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + """ + + _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS']) + + def __init__(self, headers=None): + self.headers = headers or {} + + def urlopen(self, method, url, body=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **kw): # Abstract + raise NotImplemented("Classes extending RequestMethods must implement " + "their own ``urlopen`` method.") + + def request(self, method, url, fields=None, headers=None, **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the appropriate encoding of + ``fields`` based on the ``method`` used. + + This is a convenience method that requires the least amount of manual + effort. It can be used in most situations, while still having the + option to drop down to more specific methods when necessary, such as + :meth:`request_encode_url`, :meth:`request_encode_body`, + or even the lowest level :meth:`urlopen`. + """ + method = method.upper() + + if method in self._encode_url_methods: + return self.request_encode_url(method, url, fields=fields, + headers=headers, + **urlopen_kw) + else: + return self.request_encode_body(method, url, fields=fields, + headers=headers, + **urlopen_kw) + + def request_encode_url(self, method, url, fields=None, headers=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the url. This is useful for request methods like GET, HEAD, DELETE, etc. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': headers} + extra_kw.update(urlopen_kw) + + if fields: + url += '?' + urlencode(fields) + + return self.urlopen(method, url, **extra_kw) + + def request_encode_body(self, method, url, fields=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the body. This is useful for request methods like POST, PUT, PATCH, etc. + + When ``encode_multipart=True`` (default), then + :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode + the payload with the appropriate content type. Otherwise + :meth:`urllib.urlencode` is used with the + 'application/x-www-form-urlencoded' content type. + + Multipart encoding must be used when posting files, and it's reasonably + safe to use it in other times too. However, it may break request + signing, such as with OAuth. + + Supports an optional ``fields`` parameter of key/value strings AND + key/filetuple. A filetuple is a (filename, data, MIME type) tuple where + the MIME type is optional. For example:: + + fields = { + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), + 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + } + + When uploading a file, providing a filename (the first parameter of the + tuple) is optional but recommended to best mimick behavior of browsers. + + Note that if ``headers`` are supplied, the 'Content-Type' header will + be overwritten because it depends on the dynamic random boundary string + which is used to compose the body of the request. The random boundary + string can be explicitly set with the ``multipart_boundary`` parameter. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': {}} + + if fields: + if 'body' in urlopen_kw: + raise TypeError( + "request got values for both 'fields' and 'body', can only specify one.") + + if encode_multipart: + body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) + else: + body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' + + extra_kw['body'] = body + extra_kw['headers'] = {'Content-Type': content_type} + + extra_kw['headers'].update(headers) + extra_kw.update(urlopen_kw) + + return self.urlopen(method, url, **extra_kw) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/response.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/response.py new file mode 100644 index 0000000..d3e5a1e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/response.py @@ -0,0 +1,626 @@ +from __future__ import absolute_import +from contextlib import contextmanager +import zlib +import io +import logging +from socket import timeout as SocketTimeout +from socket import error as SocketError + +from ._collections import HTTPHeaderDict +from .exceptions import ( + BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError, + ResponseNotChunked, IncompleteRead, InvalidHeader +) +from .packages.six import string_types as basestring, binary_type, PY3 +from .packages.six.moves import http_client as httplib +from .connection import HTTPException, BaseSSLError +from .util.response import is_fp_closed, is_response_to_head + +log = logging.getLogger(__name__) + + +class DeflateDecoder(object): + + def __init__(self): + self._first_try = True + self._data = binary_type() + self._obj = zlib.decompressobj() + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + + if not self._first_try: + return self._obj.decompress(data) + + self._data += data + try: + decompressed = self._obj.decompress(data) + if decompressed: + self._first_try = False + self._data = None + return decompressed + except zlib.error: + self._first_try = False + self._obj = zlib.decompressobj(-zlib.MAX_WBITS) + try: + return self.decompress(self._data) + finally: + self._data = None + + +class GzipDecoder(object): + + def __init__(self): + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + return self._obj.decompress(data) + + +def _get_decoder(mode): + if mode == 'gzip': + return GzipDecoder() + + return DeflateDecoder() + + +class HTTPResponse(io.IOBase): + """ + HTTP Response container. + + Backwards-compatible to httplib's HTTPResponse but the response ``body`` is + loaded and decoded on-demand when the ``data`` property is accessed. This + class is also compatible with the Python standard library's :mod:`io` + module, and can hence be treated as a readable object in the context of that + framework. + + Extra parameters for behaviour not present in httplib.HTTPResponse: + + :param preload_content: + If True, the response's body will be preloaded during construction. + + :param decode_content: + If True, attempts to decode specific content-encoding's based on headers + (like 'gzip' and 'deflate') will be skipped and raw data will be used + instead. + + :param original_response: + When this HTTPResponse wrapper is generated from an httplib.HTTPResponse + object, it's convenient to include the original for debug purposes. It's + otherwise unused. + + :param retries: + The retries contains the last :class:`~urllib3.util.retry.Retry` that + was used during the request. + + :param enforce_content_length: + Enforce content length checking. Body returned by server must match + value of Content-Length header, if present. Otherwise, raise error. + """ + + CONTENT_DECODERS = ['gzip', 'deflate'] + REDIRECT_STATUSES = [301, 302, 303, 307, 308] + + def __init__(self, body='', headers=None, status=0, version=0, reason=None, + strict=0, preload_content=True, decode_content=True, + original_response=None, pool=None, connection=None, + retries=None, enforce_content_length=False, request_method=None): + + if isinstance(headers, HTTPHeaderDict): + self.headers = headers + else: + self.headers = HTTPHeaderDict(headers) + self.status = status + self.version = version + self.reason = reason + self.strict = strict + self.decode_content = decode_content + self.retries = retries + self.enforce_content_length = enforce_content_length + + self._decoder = None + self._body = None + self._fp = None + self._original_response = original_response + self._fp_bytes_read = 0 + + if body and isinstance(body, (basestring, binary_type)): + self._body = body + + self._pool = pool + self._connection = connection + + if hasattr(body, 'read'): + self._fp = body + + # Are we using the chunked-style of transfer encoding? + self.chunked = False + self.chunk_left = None + tr_enc = self.headers.get('transfer-encoding', '').lower() + # Don't incur the penalty of creating a list and then discarding it + encodings = (enc.strip() for enc in tr_enc.split(",")) + if "chunked" in encodings: + self.chunked = True + + # Determine length of response + self.length_remaining = self._init_length(request_method) + + # If requested, preload the body. + if preload_content and not self._body: + self._body = self.read(decode_content=decode_content) + + def get_redirect_location(self): + """ + Should we redirect and where to? + + :returns: Truthy redirect location string if we got a redirect status + code and valid location. ``None`` if redirect status and no + location. ``False`` if not a redirect status code. + """ + if self.status in self.REDIRECT_STATUSES: + return self.headers.get('location') + + return False + + def release_conn(self): + if not self._pool or not self._connection: + return + + self._pool._put_conn(self._connection) + self._connection = None + + @property + def data(self): + # For backwords-compat with earlier urllib3 0.4 and earlier. + if self._body: + return self._body + + if self._fp: + return self.read(cache_content=True) + + @property + def connection(self): + return self._connection + + def tell(self): + """ + Obtain the number of bytes pulled over the wire so far. May differ from + the amount of content returned by :meth:``HTTPResponse.read`` if bytes + are encoded on the wire (e.g, compressed). + """ + return self._fp_bytes_read + + def _init_length(self, request_method): + """ + Set initial length value for Response content if available. + """ + length = self.headers.get('content-length') + + if length is not None and self.chunked: + # This Response will fail with an IncompleteRead if it can't be + # received as chunked. This method falls back to attempt reading + # the response before raising an exception. + log.warning("Received response with both Content-Length and " + "Transfer-Encoding set. This is expressly forbidden " + "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " + "attempting to process response as Transfer-Encoding: " + "chunked.") + return None + + elif length is not None: + try: + # RFC 7230 section 3.3.2 specifies multiple content lengths can + # be sent in a single Content-Length header + # (e.g. Content-Length: 42, 42). This line ensures the values + # are all valid ints and that as long as the `set` length is 1, + # all values are the same. Otherwise, the header is invalid. + lengths = set([int(val) for val in length.split(',')]) + if len(lengths) > 1: + raise InvalidHeader("Content-Length contained multiple " + "unmatching values (%s)" % length) + length = lengths.pop() + except ValueError: + length = None + else: + if length < 0: + length = None + + # Convert status to int for comparison + # In some cases, httplib returns a status of "_UNKNOWN" + try: + status = int(self.status) + except ValueError: + status = 0 + + # Check for responses that shouldn't include a body + if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD': + length = 0 + + return length + + def _init_decoder(self): + """ + Set-up the _decoder attribute if necessary. + """ + # Note: content-encoding value should be case-insensitive, per RFC 7230 + # Section 3.2 + content_encoding = self.headers.get('content-encoding', '').lower() + if self._decoder is None and content_encoding in self.CONTENT_DECODERS: + self._decoder = _get_decoder(content_encoding) + + def _decode(self, data, decode_content, flush_decoder): + """ + Decode the data passed in and potentially flush the decoder. + """ + try: + if decode_content and self._decoder: + data = self._decoder.decompress(data) + except (IOError, zlib.error) as e: + content_encoding = self.headers.get('content-encoding', '').lower() + raise DecodeError( + "Received response with content-encoding: %s, but " + "failed to decode it." % content_encoding, e) + + if flush_decoder and decode_content: + data += self._flush_decoder() + + return data + + def _flush_decoder(self): + """ + Flushes the decoder. Should only be called if the decoder is actually + being used. + """ + if self._decoder: + buf = self._decoder.decompress(b'') + return buf + self._decoder.flush() + + return b'' + + @contextmanager + def _error_catcher(self): + """ + Catch low-level python exceptions, instead re-raising urllib3 + variants, so that low-level exceptions are not leaked in the + high-level api. + + On exit, release the connection back to the pool. + """ + clean_exit = False + + try: + try: + yield + + except SocketTimeout: + # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but + # there is yet no clean way to get at it from this context. + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except BaseSSLError as e: + # FIXME: Is there a better way to differentiate between SSLErrors? + if 'read operation timed out' not in str(e): # Defensive: + # This shouldn't happen but just in case we're missing an edge + # case, let's avoid swallowing SSL errors. + raise + + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except (HTTPException, SocketError) as e: + # This includes IncompleteRead. + raise ProtocolError('Connection broken: %r' % e, e) + + # If no exception is thrown, we should avoid cleaning up + # unnecessarily. + clean_exit = True + finally: + # If we didn't terminate cleanly, we need to throw away our + # connection. + if not clean_exit: + # The response may not be closed but we're not going to use it + # anymore so close it now to ensure that the connection is + # released back to the pool. + if self._original_response: + self._original_response.close() + + # Closing the response may not actually be sufficient to close + # everything, so if we have a hold of the connection close that + # too. + if self._connection: + self._connection.close() + + # If we hold the original response but it's closed now, we should + # return the connection back to the pool. + if self._original_response and self._original_response.isclosed(): + self.release_conn() + + def read(self, amt=None, decode_content=None, cache_content=False): + """ + Similar to :meth:`httplib.HTTPResponse.read`, but with two additional + parameters: ``decode_content`` and ``cache_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param cache_content: + If True, will save the returned data such that the same result is + returned despite of the state of the underlying file object. This + is useful if you want the ``.data`` property to continue working + after having ``.read()`` the file object. (Overridden if ``amt`` is + set.) + """ + self._init_decoder() + if decode_content is None: + decode_content = self.decode_content + + if self._fp is None: + return + + flush_decoder = False + data = None + + with self._error_catcher(): + if amt is None: + # cStringIO doesn't like amt=None + data = self._fp.read() + flush_decoder = True + else: + cache_content = False + data = self._fp.read(amt) + if amt != 0 and not data: # Platform-specific: Buggy versions of Python. + # Close the connection when no data is returned + # + # This is redundant to what httplib/http.client _should_ + # already do. However, versions of python released before + # December 15, 2012 (http://bugs.python.org/issue16298) do + # not properly close the connection in all cases. There is + # no harm in redundantly calling close. + self._fp.close() + flush_decoder = True + if self.enforce_content_length and self.length_remaining not in (0, None): + # This is an edge case that httplib failed to cover due + # to concerns of backward compatibility. We're + # addressing it here to make sure IncompleteRead is + # raised during streaming, so all calls with incorrect + # Content-Length are caught. + raise IncompleteRead(self._fp_bytes_read, self.length_remaining) + + if data: + self._fp_bytes_read += len(data) + if self.length_remaining is not None: + self.length_remaining -= len(data) + + data = self._decode(data, decode_content, flush_decoder) + + if cache_content: + self._body = data + + return data + + def stream(self, amt=2**16, decode_content=None): + """ + A generator wrapper for the read() method. A call will block until + ``amt`` bytes have been read from the connection or until the + connection is closed. + + :param amt: + How much of the content to read. The generator will return up to + much data per iteration, but may return less. This is particularly + likely when using compressed data. However, the empty string will + never be returned. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + if self.chunked and self.supports_chunked_reads(): + for line in self.read_chunked(amt, decode_content=decode_content): + yield line + else: + while not is_fp_closed(self._fp): + data = self.read(amt=amt, decode_content=decode_content) + + if data: + yield data + + @classmethod + def from_httplib(ResponseCls, r, **response_kw): + """ + Given an :class:`httplib.HTTPResponse` instance ``r``, return a + corresponding :class:`urllib3.response.HTTPResponse` object. + + Remaining parameters are passed to the HTTPResponse constructor, along + with ``original_response=r``. + """ + headers = r.msg + + if not isinstance(headers, HTTPHeaderDict): + if PY3: # Python 3 + headers = HTTPHeaderDict(headers.items()) + else: # Python 2 + headers = HTTPHeaderDict.from_httplib(headers) + + # HTTPResponse objects in Python 3 don't have a .strict attribute + strict = getattr(r, 'strict', 0) + resp = ResponseCls(body=r, + headers=headers, + status=r.status, + version=r.version, + reason=r.reason, + strict=strict, + original_response=r, + **response_kw) + return resp + + # Backwards-compatibility methods for httplib.HTTPResponse + def getheaders(self): + return self.headers + + def getheader(self, name, default=None): + return self.headers.get(name, default) + + # Backwards compatibility for http.cookiejar + def info(self): + return self.headers + + # Overrides from io.IOBase + def close(self): + if not self.closed: + self._fp.close() + + if self._connection: + self._connection.close() + + @property + def closed(self): + if self._fp is None: + return True + elif hasattr(self._fp, 'isclosed'): + return self._fp.isclosed() + elif hasattr(self._fp, 'closed'): + return self._fp.closed + else: + return True + + def fileno(self): + if self._fp is None: + raise IOError("HTTPResponse has no file to get a fileno from") + elif hasattr(self._fp, "fileno"): + return self._fp.fileno() + else: + raise IOError("The file-like object this HTTPResponse is wrapped " + "around has no file descriptor") + + def flush(self): + if self._fp is not None and hasattr(self._fp, 'flush'): + return self._fp.flush() + + def readable(self): + # This method is required for `io` module compatibility. + return True + + def readinto(self, b): + # This method is required for `io` module compatibility. + temp = self.read(len(b)) + if len(temp) == 0: + return 0 + else: + b[:len(temp)] = temp + return len(temp) + + def supports_chunked_reads(self): + """ + Checks if the underlying file-like object looks like a + httplib.HTTPResponse object. We do this by testing for the fp + attribute. If it is present we assume it returns raw chunks as + processed by read_chunked(). + """ + return hasattr(self._fp, 'fp') + + def _update_chunk_length(self): + # First, we'll figure out length of a chunk and then + # we'll try to read it from socket. + if self.chunk_left is not None: + return + line = self._fp.fp.readline() + line = line.split(b';', 1)[0] + try: + self.chunk_left = int(line, 16) + except ValueError: + # Invalid chunked protocol response, abort. + self.close() + raise httplib.IncompleteRead(line) + + def _handle_chunk(self, amt): + returned_chunk = None + if amt is None: + chunk = self._fp._safe_read(self.chunk_left) + returned_chunk = chunk + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + elif amt < self.chunk_left: + value = self._fp._safe_read(amt) + self.chunk_left = self.chunk_left - amt + returned_chunk = value + elif amt == self.chunk_left: + value = self._fp._safe_read(amt) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + returned_chunk = value + else: # amt > self.chunk_left + returned_chunk = self._fp._safe_read(self.chunk_left) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + return returned_chunk + + def read_chunked(self, amt=None, decode_content=None): + """ + Similar to :meth:`HTTPResponse.read`, but with an additional + parameter: ``decode_content``. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + self._init_decoder() + # FIXME: Rewrite this method and make it a class with a better structured logic. + if not self.chunked: + raise ResponseNotChunked( + "Response is not chunked. " + "Header 'transfer-encoding: chunked' is missing.") + if not self.supports_chunked_reads(): + raise BodyNotHttplibCompatible( + "Body should be httplib.HTTPResponse like. " + "It should have have an fp attribute which returns raw chunks.") + + # Don't bother reading the body of a HEAD request. + if self._original_response and is_response_to_head(self._original_response): + self._original_response.close() + return + + with self._error_catcher(): + while True: + self._update_chunk_length() + if self.chunk_left == 0: + break + chunk = self._handle_chunk(amt) + decoded = self._decode(chunk, decode_content=decode_content, + flush_decoder=False) + if decoded: + yield decoded + + if decode_content: + # On CPython and PyPy, we should never need to flush the + # decoder. However, on Jython we *might* need to, so + # lets defensively do it anyway. + decoded = self._flush_decoder() + if decoded: # Platform-specific: Jython. + yield decoded + + # Chunk content ends with \r\n: discard it. + while True: + line = self._fp.fp.readline() + if not line: + # Some sites may not end with '\r\n'. + break + if line == b'\r\n': + break + + # We read everything; close the "file". + if self._original_response: + self._original_response.close() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__init__.py new file mode 100644 index 0000000..2f2770b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__init__.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import +# For backwards compatibility, provide imports that used to be here. +from .connection import is_connection_dropped +from .request import make_headers +from .response import is_fp_closed +from .ssl_ import ( + SSLContext, + HAS_SNI, + IS_PYOPENSSL, + IS_SECURETRANSPORT, + assert_fingerprint, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +from .timeout import ( + current_time, + Timeout, +) + +from .retry import Retry +from .url import ( + get_host, + parse_url, + split_first, + Url, +) +from .wait import ( + wait_for_read, + wait_for_write +) + +__all__ = ( + 'HAS_SNI', + 'IS_PYOPENSSL', + 'IS_SECURETRANSPORT', + 'SSLContext', + 'Retry', + 'Timeout', + 'Url', + 'assert_fingerprint', + 'current_time', + 'is_connection_dropped', + 'is_fp_closed', + 'get_host', + 'parse_url', + 'make_headers', + 'resolve_cert_reqs', + 'resolve_ssl_version', + 'split_first', + 'ssl_wrap_socket', + 'wait_for_read', + 'wait_for_write' +) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..67cd9a6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc new file mode 100644 index 0000000..56c27a1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc new file mode 100644 index 0000000..ba2cd0e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc new file mode 100644 index 0000000..fb4640a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc new file mode 100644 index 0000000..86b7e57 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/selectors.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/selectors.cpython-37.pyc new file mode 100644 index 0000000..77e5025 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/selectors.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc new file mode 100644 index 0000000..98a69fc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc new file mode 100644 index 0000000..9335829 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc new file mode 100644 index 0000000..65ff740 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc new file mode 100644 index 0000000..66fe114 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py new file mode 100644 index 0000000..bf699cf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/connection.py @@ -0,0 +1,130 @@ +from __future__ import absolute_import +import socket +from .wait import wait_for_read +from .selectors import HAS_SELECT, SelectorError + + +def is_connection_dropped(conn): # Platform-specific + """ + Returns True if the connection is dropped and should be closed. + + :param conn: + :class:`httplib.HTTPConnection` object. + + Note: For platforms like AppEngine, this will always return ``False`` to + let the platform handle connection recycling transparently for us. + """ + sock = getattr(conn, 'sock', False) + if sock is False: # Platform-specific: AppEngine + return False + if sock is None: # Connection already closed (such as by httplib). + return True + + if not HAS_SELECT: + return False + + try: + return bool(wait_for_read(sock, timeout=0.0)) + except SelectorError: + return True + + +# This function is copied from socket.py in the Python 2.7 standard +# library test suite. Added to its signature is only `socket_options`. +# One additional modification is that we avoid binding to IPv6 servers +# discovered in DNS if the system doesn't have IPv6 functionality. +def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, socket_options=None): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + if host.startswith('['): + host = host.strip('[]') + err = None + + # Using the value from allowed_gai_family() in the context of getaddrinfo lets + # us select whether to work with IPv4 DNS records, IPv6 records, or both. + # The original create_connection function always returns all records. + family = allowed_gai_family() + + for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket.socket(af, socktype, proto) + + # If provided, set socket level options before connecting. + _set_socket_options(sock, socket_options) + + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error as e: + err = e + if sock is not None: + sock.close() + sock = None + + if err is not None: + raise err + + raise socket.error("getaddrinfo returns an empty list") + + +def _set_socket_options(sock, options): + if options is None: + return + + for opt in options: + sock.setsockopt(*opt) + + +def allowed_gai_family(): + """This function is designed to work in the context of + getaddrinfo, where family=socket.AF_UNSPEC is the default and + will perform a DNS search for both IPv6 and IPv4 records.""" + + family = socket.AF_INET + if HAS_IPV6: + family = socket.AF_UNSPEC + return family + + +def _has_ipv6(host): + """ Returns True if the system can bind an IPv6 address. """ + sock = None + has_ipv6 = False + + if socket.has_ipv6: + # has_ipv6 returns true if cPython was compiled with IPv6 support. + # It does not tell us if the system has IPv6 support enabled. To + # determine that we must bind to an IPv6 address. + # https://github.com/shazow/urllib3/pull/611 + # https://bugs.python.org/issue658327 + try: + sock = socket.socket(socket.AF_INET6) + sock.bind((host, 0)) + has_ipv6 = True + except Exception: + pass + + if sock: + sock.close() + return has_ipv6 + + +HAS_IPV6 = _has_ipv6('::1') diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/request.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/request.py new file mode 100644 index 0000000..3ddfcd5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/request.py @@ -0,0 +1,118 @@ +from __future__ import absolute_import +from base64 import b64encode + +from ..packages.six import b, integer_types +from ..exceptions import UnrewindableBodyError + +ACCEPT_ENCODING = 'gzip,deflate' +_FAILEDTELL = object() + + +def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, + basic_auth=None, proxy_basic_auth=None, disable_cache=None): + """ + Shortcuts for generating request headers. + + :param keep_alive: + If ``True``, adds 'connection: keep-alive' header. + + :param accept_encoding: + Can be a boolean, list, or string. + ``True`` translates to 'gzip,deflate'. + List will get joined by comma. + String will be used as provided. + + :param user_agent: + String representing the user-agent you want, such as + "python-urllib3/0.6" + + :param basic_auth: + Colon-separated username:password string for 'authorization: basic ...' + auth header. + + :param proxy_basic_auth: + Colon-separated username:password string for 'proxy-authorization: basic ...' + auth header. + + :param disable_cache: + If ``True``, adds 'cache-control: no-cache' header. + + Example:: + + >>> make_headers(keep_alive=True, user_agent="Batman/1.0") + {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} + >>> make_headers(accept_encoding=True) + {'accept-encoding': 'gzip,deflate'} + """ + headers = {} + if accept_encoding: + if isinstance(accept_encoding, str): + pass + elif isinstance(accept_encoding, list): + accept_encoding = ','.join(accept_encoding) + else: + accept_encoding = ACCEPT_ENCODING + headers['accept-encoding'] = accept_encoding + + if user_agent: + headers['user-agent'] = user_agent + + if keep_alive: + headers['connection'] = 'keep-alive' + + if basic_auth: + headers['authorization'] = 'Basic ' + \ + b64encode(b(basic_auth)).decode('utf-8') + + if proxy_basic_auth: + headers['proxy-authorization'] = 'Basic ' + \ + b64encode(b(proxy_basic_auth)).decode('utf-8') + + if disable_cache: + headers['cache-control'] = 'no-cache' + + return headers + + +def set_file_position(body, pos): + """ + If a position is provided, move file to that point. + Otherwise, we'll attempt to record a position for future use. + """ + if pos is not None: + rewind_body(body, pos) + elif getattr(body, 'tell', None) is not None: + try: + pos = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body. + pos = _FAILEDTELL + + return pos + + +def rewind_body(body, body_pos): + """ + Attempt to rewind body to a certain position. + Primarily used for request redirects and retries. + + :param body: + File-like object that supports seek. + + :param int pos: + Position to seek to in file. + """ + body_seek = getattr(body, 'seek', None) + if body_seek is not None and isinstance(body_pos, integer_types): + try: + body_seek(body_pos) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect/retry.") + elif body_pos is _FAILEDTELL: + raise UnrewindableBodyError("Unable to record file position for rewinding " + "request body during a redirect/retry.") + else: + raise ValueError("body_pos must be of type integer, " + "instead it was %s." % type(body_pos)) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/response.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/response.py new file mode 100644 index 0000000..67cf730 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/response.py @@ -0,0 +1,81 @@ +from __future__ import absolute_import +from ..packages.six.moves import http_client as httplib + +from ..exceptions import HeaderParsingError + + +def is_fp_closed(obj): + """ + Checks whether a given file-like object is closed. + + :param obj: + The file-like object to check. + """ + + try: + # Check `isclosed()` first, in case Python3 doesn't set `closed`. + # GH Issue #928 + return obj.isclosed() + except AttributeError: + pass + + try: + # Check via the official file-like-object way. + return obj.closed + except AttributeError: + pass + + try: + # Check if the object is a container for another file-like object that + # gets released on exhaustion (e.g. HTTPResponse). + return obj.fp is None + except AttributeError: + pass + + raise ValueError("Unable to determine whether fp is closed.") + + +def assert_header_parsing(headers): + """ + Asserts whether all headers have been successfully parsed. + Extracts encountered errors from the result of parsing headers. + + Only works on Python 3. + + :param headers: Headers to verify. + :type headers: `httplib.HTTPMessage`. + + :raises urllib3.exceptions.HeaderParsingError: + If parsing errors are found. + """ + + # This will fail silently if we pass in the wrong kind of parameter. + # To make debugging easier add an explicit check. + if not isinstance(headers, httplib.HTTPMessage): + raise TypeError('expected httplib.Message, got {0}.'.format( + type(headers))) + + defects = getattr(headers, 'defects', None) + get_payload = getattr(headers, 'get_payload', None) + + unparsed_data = None + if get_payload: # Platform-specific: Python 3. + unparsed_data = get_payload() + + if defects or unparsed_data: + raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) + + +def is_response_to_head(response): + """ + Checks whether the request of a response has been a HEAD-request. + Handles the quirks of AppEngine. + + :param conn: + :type conn: :class:`httplib.HTTPResponse` + """ + # FIXME: Can we do this somehow without accessing private httplib _method? + method = response._method + if isinstance(method, int): # Platform-specific: Appengine + return method == 3 + return method.upper() == 'HEAD' diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/retry.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/retry.py new file mode 100644 index 0000000..c603cb4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/retry.py @@ -0,0 +1,401 @@ +from __future__ import absolute_import +import time +import logging +from collections import namedtuple +from itertools import takewhile +import email +import re + +from ..exceptions import ( + ConnectTimeoutError, + MaxRetryError, + ProtocolError, + ReadTimeoutError, + ResponseError, + InvalidHeader, +) +from ..packages import six + + +log = logging.getLogger(__name__) + +# Data structure for representing the metadata of requests that result in a retry. +RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", + "status", "redirect_location"]) + + +class Retry(object): + """ Retry configuration. + + Each retry attempt will create a new Retry object with updated values, so + they can be safely reused. + + Retries can be defined as a default for a pool:: + + retries = Retry(connect=5, read=2, redirect=5) + http = PoolManager(retries=retries) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', retries=Retry(10)) + + Retries can be disabled by passing ``False``:: + + response = http.request('GET', 'http://example.com/', retries=False) + + Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless + retries are disabled, in which case the causing exception will be raised. + + :param int total: + Total number of retries to allow. Takes precedence over other counts. + + Set to ``None`` to remove this constraint and fall back on other + counts. It's a good idea to set this to some sensibly-high value to + account for unexpected edge cases and avoid infinite retry loops. + + Set to ``0`` to fail on the first retry. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int connect: + How many connection-related errors to retry on. + + These are errors raised before the request is sent to the remote server, + which we assume has not triggered the server to process the request. + + Set to ``0`` to fail on the first retry of this type. + + :param int read: + How many times to retry on read errors. + + These errors are raised after the request was sent to the server, so the + request may have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + :param int redirect: + How many redirects to perform. Limit this to avoid infinite redirect + loops. + + A redirect is a HTTP response with a status code 301, 302, 303, 307 or + 308. + + Set to ``0`` to fail on the first retry of this type. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int status: + How many times to retry on bad status codes. + + These are retries made on responses, where status code matches + ``status_forcelist``. + + Set to ``0`` to fail on the first retry of this type. + + :param iterable method_whitelist: + Set of uppercased HTTP method verbs that we should retry on. + + By default, we only retry on methods which are considered to be + idempotent (multiple requests with the same parameters end with the + same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`. + + Set to a ``False`` value to retry on any verb. + + :param iterable status_forcelist: + A set of integer HTTP status codes that we should force a retry on. + A retry is initiated if the request method is in ``method_whitelist`` + and the response status code is in ``status_forcelist``. + + By default, this is disabled with ``None``. + + :param float backoff_factor: + A backoff factor to apply between attempts after the second try + (most errors are resolved immediately by a second try without a + delay). urllib3 will sleep for:: + + {backoff factor} * (2 ^ ({number of total retries} - 1)) + + seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep + for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer + than :attr:`Retry.BACKOFF_MAX`. + + By default, backoff is disabled (set to 0). + + :param bool raise_on_redirect: Whether, if the number of redirects is + exhausted, to raise a MaxRetryError, or to return a response with a + response code in the 3xx range. + + :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: + whether we should raise an exception, or return a response, + if status falls in ``status_forcelist`` range and retries have + been exhausted. + + :param tuple history: The history of the request encountered during + each call to :meth:`~Retry.increment`. The list is in the order + the requests occurred. Each list item is of class :class:`RequestHistory`. + + :param bool respect_retry_after_header: + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ + 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) + + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + + #: Maximum backoff time. + BACKOFF_MAX = 120 + + def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, raise_on_status=True, + history=None, respect_retry_after_header=True): + + self.total = total + self.connect = connect + self.read = read + self.status = status + + if redirect is False or total is False: + redirect = 0 + raise_on_redirect = False + + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist + self.backoff_factor = backoff_factor + self.raise_on_redirect = raise_on_redirect + self.raise_on_status = raise_on_status + self.history = history or tuple() + self.respect_retry_after_header = respect_retry_after_header + + def new(self, **kw): + params = dict( + total=self.total, + connect=self.connect, read=self.read, redirect=self.redirect, status=self.status, + method_whitelist=self.method_whitelist, + status_forcelist=self.status_forcelist, + backoff_factor=self.backoff_factor, + raise_on_redirect=self.raise_on_redirect, + raise_on_status=self.raise_on_status, + history=self.history, + ) + params.update(kw) + return type(self)(**params) + + @classmethod + def from_int(cls, retries, redirect=True, default=None): + """ Backwards-compatibility for the old retries format.""" + if retries is None: + retries = default if default is not None else cls.DEFAULT + + if isinstance(retries, Retry): + return retries + + redirect = bool(redirect) and None + new_retries = cls(retries, redirect=redirect) + log.debug("Converted retries value: %r -> %r", retries, new_retries) + return new_retries + + def get_backoff_time(self): + """ Formula for computing the current backoff + + :rtype: float + """ + # We want to consider only the last consecutive errors sequence (Ignore redirects). + consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None, + reversed(self.history)))) + if consecutive_errors_len <= 1: + return 0 + + backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) + return min(self.BACKOFF_MAX, backoff_value) + + def parse_retry_after(self, retry_after): + # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 + if re.match(r"^\s*[0-9]+\s*$", retry_after): + seconds = int(retry_after) + else: + retry_date_tuple = email.utils.parsedate(retry_after) + if retry_date_tuple is None: + raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) + retry_date = time.mktime(retry_date_tuple) + seconds = retry_date - time.time() + + if seconds < 0: + seconds = 0 + + return seconds + + def get_retry_after(self, response): + """ Get the value of Retry-After in seconds. """ + + retry_after = response.getheader("Retry-After") + + if retry_after is None: + return None + + return self.parse_retry_after(retry_after) + + def sleep_for_retry(self, response=None): + retry_after = self.get_retry_after(response) + if retry_after: + time.sleep(retry_after) + return True + + return False + + def _sleep_backoff(self): + backoff = self.get_backoff_time() + if backoff <= 0: + return + time.sleep(backoff) + + def sleep(self, response=None): + """ Sleep between retry attempts. + + This method will respect a server's ``Retry-After`` response header + and sleep the duration of the time requested. If that is not present, it + will use an exponential backoff. By default, the backoff factor is 0 and + this method will return immediately. + """ + + if response: + slept = self.sleep_for_retry(response) + if slept: + return + + self._sleep_backoff() + + def _is_connection_error(self, err): + """ Errors when we're fairly sure that the server did not receive the + request, so it should be safe to retry. + """ + return isinstance(err, ConnectTimeoutError) + + def _is_read_error(self, err): + """ Errors that occur after the request has been started, so we should + assume that the server began processing it. + """ + return isinstance(err, (ReadTimeoutError, ProtocolError)) + + def _is_method_retryable(self, method): + """ Checks if a given HTTP method should be retried upon, depending if + it is included on the method whitelist. + """ + if self.method_whitelist and method.upper() not in self.method_whitelist: + return False + + return True + + def is_retry(self, method, status_code, has_retry_after=False): + """ Is this method/status code retryable? (Based on whitelists and control + variables such as the number of total retries to allow, whether to + respect the Retry-After header, whether this header is present, and + whether the returned status code is on the list of status codes to + be retried upon on the presence of the aforementioned header) + """ + if not self._is_method_retryable(method): + return False + + if self.status_forcelist and status_code in self.status_forcelist: + return True + + return (self.total and self.respect_retry_after_header and + has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES)) + + def is_exhausted(self): + """ Are we out of retries? """ + retry_counts = (self.total, self.connect, self.read, self.redirect, self.status) + retry_counts = list(filter(None, retry_counts)) + if not retry_counts: + return False + + return min(retry_counts) < 0 + + def increment(self, method=None, url=None, response=None, error=None, + _pool=None, _stacktrace=None): + """ Return a new Retry object with incremented retry counters. + + :param response: A response object, or None, if the server did not + return a response. + :type response: :class:`~urllib3.response.HTTPResponse` + :param Exception error: An error encountered during the request, or + None if the response was received successfully. + + :return: A new ``Retry`` object. + """ + if self.total is False and error: + # Disabled, indicate to re-raise the error. + raise six.reraise(type(error), error, _stacktrace) + + total = self.total + if total is not None: + total -= 1 + + connect = self.connect + read = self.read + redirect = self.redirect + status_count = self.status + cause = 'unknown' + status = None + redirect_location = None + + if error and self._is_connection_error(error): + # Connect retry? + if connect is False: + raise six.reraise(type(error), error, _stacktrace) + elif connect is not None: + connect -= 1 + + elif error and self._is_read_error(error): + # Read retry? + if read is False or not self._is_method_retryable(method): + raise six.reraise(type(error), error, _stacktrace) + elif read is not None: + read -= 1 + + elif response and response.get_redirect_location(): + # Redirect retry? + if redirect is not None: + redirect -= 1 + cause = 'too many redirects' + redirect_location = response.get_redirect_location() + status = response.status + + else: + # Incrementing because of a server error like a 500 in + # status_forcelist and a the given method is in the whitelist + cause = ResponseError.GENERIC_ERROR + if response and response.status: + if status_count is not None: + status_count -= 1 + cause = ResponseError.SPECIFIC_ERROR.format( + status_code=response.status) + status = response.status + + history = self.history + (RequestHistory(method, url, error, status, redirect_location),) + + new_retry = self.new( + total=total, + connect=connect, read=read, redirect=redirect, status=status_count, + history=history) + + if new_retry.is_exhausted(): + raise MaxRetryError(_pool, url, error or ResponseError(cause)) + + log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) + + return new_retry + + def __repr__(self): + return ('{cls.__name__}(total={self.total}, connect={self.connect}, ' + 'read={self.read}, redirect={self.redirect}, status={self.status})').format( + cls=type(self), self=self) + + +# For backwards compatibility (equivalent to pre-v1.9): +Retry.DEFAULT = Retry(3) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/selectors.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/selectors.py new file mode 100644 index 0000000..d75cb26 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/selectors.py @@ -0,0 +1,581 @@ +# Backport of selectors.py from Python 3.5+ to support Python < 3.4 +# Also has the behavior specified in PEP 475 which is to retry syscalls +# in the case of an EINTR error. This module is required because selectors34 +# does not follow this behavior and instead returns that no dile descriptor +# events have occurred rather than retry the syscall. The decision to drop +# support for select.devpoll is made to maintain 100% test coverage. + +import errno +import math +import select +import socket +import sys +import time +from collections import namedtuple, Mapping + +try: + monotonic = time.monotonic +except (AttributeError, ImportError): # Python 3.3< + monotonic = time.time + +EVENT_READ = (1 << 0) +EVENT_WRITE = (1 << 1) + +HAS_SELECT = True # Variable that shows whether the platform has a selector. +_SYSCALL_SENTINEL = object() # Sentinel in case a system call returns None. +_DEFAULT_SELECTOR = None + + +class SelectorError(Exception): + def __init__(self, errcode): + super(SelectorError, self).__init__() + self.errno = errcode + + def __repr__(self): + return "<SelectorError errno={0}>".format(self.errno) + + def __str__(self): + return self.__repr__() + + +def _fileobj_to_fd(fileobj): + """ Return a file descriptor from a file object. If + given an integer will simply return that integer back. """ + if isinstance(fileobj, int): + fd = fileobj + else: + try: + fd = int(fileobj.fileno()) + except (AttributeError, TypeError, ValueError): + raise ValueError("Invalid file object: {0!r}".format(fileobj)) + if fd < 0: + raise ValueError("Invalid file descriptor: {0}".format(fd)) + return fd + + +# Determine which function to use to wrap system calls because Python 3.5+ +# already handles the case when system calls are interrupted. +if sys.version_info >= (3, 5): + def _syscall_wrapper(func, _, *args, **kwargs): + """ This is the short-circuit version of the below logic + because in Python 3.5+ all system calls automatically restart + and recalculate their timeouts. """ + try: + return func(*args, **kwargs) + except (OSError, IOError, select.error) as e: + errcode = None + if hasattr(e, "errno"): + errcode = e.errno + raise SelectorError(errcode) +else: + def _syscall_wrapper(func, recalc_timeout, *args, **kwargs): + """ Wrapper function for syscalls that could fail due to EINTR. + All functions should be retried if there is time left in the timeout + in accordance with PEP 475. """ + timeout = kwargs.get("timeout", None) + if timeout is None: + expires = None + recalc_timeout = False + else: + timeout = float(timeout) + if timeout < 0.0: # Timeout less than 0 treated as no timeout. + expires = None + else: + expires = monotonic() + timeout + + args = list(args) + if recalc_timeout and "timeout" not in kwargs: + raise ValueError( + "Timeout must be in args or kwargs to be recalculated") + + result = _SYSCALL_SENTINEL + while result is _SYSCALL_SENTINEL: + try: + result = func(*args, **kwargs) + # OSError is thrown by select.select + # IOError is thrown by select.epoll.poll + # select.error is thrown by select.poll.poll + # Aren't we thankful for Python 3.x rework for exceptions? + except (OSError, IOError, select.error) as e: + # select.error wasn't a subclass of OSError in the past. + errcode = None + if hasattr(e, "errno"): + errcode = e.errno + elif hasattr(e, "args"): + errcode = e.args[0] + + # Also test for the Windows equivalent of EINTR. + is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and + errcode == errno.WSAEINTR)) + + if is_interrupt: + if expires is not None: + current_time = monotonic() + if current_time > expires: + raise OSError(errno=errno.ETIMEDOUT) + if recalc_timeout: + if "timeout" in kwargs: + kwargs["timeout"] = expires - current_time + continue + if errcode: + raise SelectorError(errcode) + else: + raise + return result + + +SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data']) + + +class _SelectorMapping(Mapping): + """ Mapping of file objects to selector keys """ + + def __init__(self, selector): + self._selector = selector + + def __len__(self): + return len(self._selector._fd_to_key) + + def __getitem__(self, fileobj): + try: + fd = self._selector._fileobj_lookup(fileobj) + return self._selector._fd_to_key[fd] + except KeyError: + raise KeyError("{0!r} is not registered.".format(fileobj)) + + def __iter__(self): + return iter(self._selector._fd_to_key) + + +class BaseSelector(object): + """ Abstract Selector class + + A selector supports registering file objects to be monitored + for specific I/O events. + + A file object is a file descriptor or any object with a + `fileno()` method. An arbitrary object can be attached to the + file object which can be used for example to store context info, + a callback, etc. + + A selector can use various implementations (select(), poll(), epoll(), + and kqueue()) depending on the platform. The 'DefaultSelector' class uses + the most efficient implementation for the current platform. + """ + def __init__(self): + # Maps file descriptors to keys. + self._fd_to_key = {} + + # Read-only mapping returned by get_map() + self._map = _SelectorMapping(self) + + def _fileobj_lookup(self, fileobj): + """ Return a file descriptor from a file object. + This wraps _fileobj_to_fd() to do an exhaustive + search in case the object is invalid but we still + have it in our map. Used by unregister() so we can + unregister an object that was previously registered + even if it is closed. It is also used by _SelectorMapping + """ + try: + return _fileobj_to_fd(fileobj) + except ValueError: + + # Search through all our mapped keys. + for key in self._fd_to_key.values(): + if key.fileobj is fileobj: + return key.fd + + # Raise ValueError after all. + raise + + def register(self, fileobj, events, data=None): + """ Register a file object for a set of events to monitor. """ + if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)): + raise ValueError("Invalid events: {0!r}".format(events)) + + key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data) + + if key.fd in self._fd_to_key: + raise KeyError("{0!r} (FD {1}) is already registered" + .format(fileobj, key.fd)) + + self._fd_to_key[key.fd] = key + return key + + def unregister(self, fileobj): + """ Unregister a file object from being monitored. """ + try: + key = self._fd_to_key.pop(self._fileobj_lookup(fileobj)) + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + # Getting the fileno of a closed socket on Windows errors with EBADF. + except socket.error as e: # Platform-specific: Windows. + if e.errno != errno.EBADF: + raise + else: + for key in self._fd_to_key.values(): + if key.fileobj is fileobj: + self._fd_to_key.pop(key.fd) + break + else: + raise KeyError("{0!r} is not registered".format(fileobj)) + return key + + def modify(self, fileobj, events, data=None): + """ Change a registered file object monitored events and data. """ + # NOTE: Some subclasses optimize this operation even further. + try: + key = self._fd_to_key[self._fileobj_lookup(fileobj)] + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + if events != key.events: + self.unregister(fileobj) + key = self.register(fileobj, events, data) + + elif data != key.data: + # Use a shortcut to update the data. + key = key._replace(data=data) + self._fd_to_key[key.fd] = key + + return key + + def select(self, timeout=None): + """ Perform the actual selection until some monitored file objects + are ready or the timeout expires. """ + raise NotImplementedError() + + def close(self): + """ Close the selector. This must be called to ensure that all + underlying resources are freed. """ + self._fd_to_key.clear() + self._map = None + + def get_key(self, fileobj): + """ Return the key associated with a registered file object. """ + mapping = self.get_map() + if mapping is None: + raise RuntimeError("Selector is closed") + try: + return mapping[fileobj] + except KeyError: + raise KeyError("{0!r} is not registered".format(fileobj)) + + def get_map(self): + """ Return a mapping of file objects to selector keys """ + return self._map + + def _key_from_fd(self, fd): + """ Return the key associated to a given file descriptor + Return None if it is not found. """ + try: + return self._fd_to_key[fd] + except KeyError: + return None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + +# Almost all platforms have select.select() +if hasattr(select, "select"): + class SelectSelector(BaseSelector): + """ Select-based selector. """ + def __init__(self): + super(SelectSelector, self).__init__() + self._readers = set() + self._writers = set() + + def register(self, fileobj, events, data=None): + key = super(SelectSelector, self).register(fileobj, events, data) + if events & EVENT_READ: + self._readers.add(key.fd) + if events & EVENT_WRITE: + self._writers.add(key.fd) + return key + + def unregister(self, fileobj): + key = super(SelectSelector, self).unregister(fileobj) + self._readers.discard(key.fd) + self._writers.discard(key.fd) + return key + + def _select(self, r, w, timeout=None): + """ Wrapper for select.select because timeout is a positional arg """ + return select.select(r, w, [], timeout) + + def select(self, timeout=None): + # Selecting on empty lists on Windows errors out. + if not len(self._readers) and not len(self._writers): + return [] + + timeout = None if timeout is None else max(timeout, 0.0) + ready = [] + r, w, _ = _syscall_wrapper(self._select, True, self._readers, + self._writers, timeout) + r = set(r) + w = set(w) + for fd in r | w: + events = 0 + if fd in r: + events |= EVENT_READ + if fd in w: + events |= EVENT_WRITE + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + +if hasattr(select, "poll"): + class PollSelector(BaseSelector): + """ Poll-based selector """ + def __init__(self): + super(PollSelector, self).__init__() + self._poll = select.poll() + + def register(self, fileobj, events, data=None): + key = super(PollSelector, self).register(fileobj, events, data) + event_mask = 0 + if events & EVENT_READ: + event_mask |= select.POLLIN + if events & EVENT_WRITE: + event_mask |= select.POLLOUT + self._poll.register(key.fd, event_mask) + return key + + def unregister(self, fileobj): + key = super(PollSelector, self).unregister(fileobj) + self._poll.unregister(key.fd) + return key + + def _wrap_poll(self, timeout=None): + """ Wrapper function for select.poll.poll() so that + _syscall_wrapper can work with only seconds. """ + if timeout is not None: + if timeout <= 0: + timeout = 0 + else: + # select.poll.poll() has a resolution of 1 millisecond, + # round away from zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) + + result = self._poll.poll(timeout) + return result + + def select(self, timeout=None): + ready = [] + fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout) + for fd, event_mask in fd_events: + events = 0 + if event_mask & ~select.POLLIN: + events |= EVENT_WRITE + if event_mask & ~select.POLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + + return ready + + +if hasattr(select, "epoll"): + class EpollSelector(BaseSelector): + """ Epoll-based selector """ + def __init__(self): + super(EpollSelector, self).__init__() + self._epoll = select.epoll() + + def fileno(self): + return self._epoll.fileno() + + def register(self, fileobj, events, data=None): + key = super(EpollSelector, self).register(fileobj, events, data) + events_mask = 0 + if events & EVENT_READ: + events_mask |= select.EPOLLIN + if events & EVENT_WRITE: + events_mask |= select.EPOLLOUT + _syscall_wrapper(self._epoll.register, False, key.fd, events_mask) + return key + + def unregister(self, fileobj): + key = super(EpollSelector, self).unregister(fileobj) + try: + _syscall_wrapper(self._epoll.unregister, False, key.fd) + except SelectorError: + # This can occur when the fd was closed since registry. + pass + return key + + def select(self, timeout=None): + if timeout is not None: + if timeout <= 0: + timeout = 0.0 + else: + # select.epoll.poll() has a resolution of 1 millisecond + # but luckily takes seconds so we don't need a wrapper + # like PollSelector. Just for better rounding. + timeout = math.ceil(timeout * 1e3) * 1e-3 + timeout = float(timeout) + else: + timeout = -1.0 # epoll.poll() must have a float. + + # We always want at least 1 to ensure that select can be called + # with no file descriptors registered. Otherwise will fail. + max_events = max(len(self._fd_to_key), 1) + + ready = [] + fd_events = _syscall_wrapper(self._epoll.poll, True, + timeout=timeout, + maxevents=max_events) + for fd, event_mask in fd_events: + events = 0 + if event_mask & ~select.EPOLLIN: + events |= EVENT_WRITE + if event_mask & ~select.EPOLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + def close(self): + self._epoll.close() + super(EpollSelector, self).close() + + +if hasattr(select, "kqueue"): + class KqueueSelector(BaseSelector): + """ Kqueue / Kevent-based selector """ + def __init__(self): + super(KqueueSelector, self).__init__() + self._kqueue = select.kqueue() + + def fileno(self): + return self._kqueue.fileno() + + def register(self, fileobj, events, data=None): + key = super(KqueueSelector, self).register(fileobj, events, data) + if events & EVENT_READ: + kevent = select.kevent(key.fd, + select.KQ_FILTER_READ, + select.KQ_EV_ADD) + + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + + if events & EVENT_WRITE: + kevent = select.kevent(key.fd, + select.KQ_FILTER_WRITE, + select.KQ_EV_ADD) + + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + + return key + + def unregister(self, fileobj): + key = super(KqueueSelector, self).unregister(fileobj) + if key.events & EVENT_READ: + kevent = select.kevent(key.fd, + select.KQ_FILTER_READ, + select.KQ_EV_DELETE) + try: + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + except SelectorError: + pass + if key.events & EVENT_WRITE: + kevent = select.kevent(key.fd, + select.KQ_FILTER_WRITE, + select.KQ_EV_DELETE) + try: + _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0) + except SelectorError: + pass + + return key + + def select(self, timeout=None): + if timeout is not None: + timeout = max(timeout, 0) + + max_events = len(self._fd_to_key) * 2 + ready_fds = {} + + kevent_list = _syscall_wrapper(self._kqueue.control, True, + None, max_events, timeout) + + for kevent in kevent_list: + fd = kevent.ident + event_mask = kevent.filter + events = 0 + if event_mask == select.KQ_FILTER_READ: + events |= EVENT_READ + if event_mask == select.KQ_FILTER_WRITE: + events |= EVENT_WRITE + + key = self._key_from_fd(fd) + if key: + if key.fd not in ready_fds: + ready_fds[key.fd] = (key, events & key.events) + else: + old_events = ready_fds[key.fd][1] + ready_fds[key.fd] = (key, (events | old_events) & key.events) + + return list(ready_fds.values()) + + def close(self): + self._kqueue.close() + super(KqueueSelector, self).close() + + +if not hasattr(select, 'select'): # Platform-specific: AppEngine + HAS_SELECT = False + + +def _can_allocate(struct): + """ Checks that select structs can be allocated by the underlying + operating system, not just advertised by the select module. We don't + check select() because we'll be hopeful that most platforms that + don't have it available will not advertise it. (ie: GAE) """ + try: + # select.poll() objects won't fail until used. + if struct == 'poll': + p = select.poll() + p.poll(0) + + # All others will fail on allocation. + else: + getattr(select, struct)().close() + return True + except (OSError, AttributeError) as e: + return False + + +# Choose the best implementation, roughly: +# kqueue == epoll > poll > select. Devpoll not supported. (See above) +# select() also can't accept a FD > FD_SETSIZE (usually around 1024) +def DefaultSelector(): + """ This function serves as a first call for DefaultSelector to + detect if the select module is being monkey-patched incorrectly + by eventlet, greenlet, and preserve proper behavior. """ + global _DEFAULT_SELECTOR + if _DEFAULT_SELECTOR is None: + if _can_allocate('kqueue'): + _DEFAULT_SELECTOR = KqueueSelector + elif _can_allocate('epoll'): + _DEFAULT_SELECTOR = EpollSelector + elif _can_allocate('poll'): + _DEFAULT_SELECTOR = PollSelector + elif hasattr(select, 'select'): + _DEFAULT_SELECTOR = SelectSelector + else: # Platform-specific: AppEngine + raise ValueError('Platform does not have a selector') + return _DEFAULT_SELECTOR() diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py new file mode 100644 index 0000000..dafc75b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/ssl_.py @@ -0,0 +1,341 @@ +from __future__ import absolute_import +import errno +import warnings +import hmac + +from binascii import hexlify, unhexlify +from hashlib import md5, sha1, sha256 + +from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning + + +SSLContext = None +HAS_SNI = False +IS_PYOPENSSL = False +IS_SECURETRANSPORT = False + +# Maps the length of a digest to a possible hash function producing this digest +HASHFUNC_MAP = { + 32: md5, + 40: sha1, + 64: sha256, +} + + +def _const_compare_digest_backport(a, b): + """ + Compare two digests of equal length in constant time. + + The digests must be of type str/bytes. + Returns True if the digests match, and False otherwise. + """ + result = abs(len(a) - len(b)) + for l, r in zip(bytearray(a), bytearray(b)): + result |= l ^ r + return result == 0 + + +_const_compare_digest = getattr(hmac, 'compare_digest', + _const_compare_digest_backport) + + +try: # Test for SSL features + import ssl + from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 + from ssl import HAS_SNI # Has SNI? +except ImportError: + pass + + +try: + from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION +except ImportError: + OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 + OP_NO_COMPRESSION = 0x20000 + +# A secure default. +# Sources for more information on TLS ciphers: +# +# - https://wiki.mozilla.org/Security/Server_Side_TLS +# - https://www.ssllabs.com/projects/best-practices/index.html +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +# +# The general intent is: +# - Prefer TLS 1.3 cipher suites +# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), +# - prefer ECDHE over DHE for better performance, +# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and +# security, +# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, +# - disable NULL authentication, MD5 MACs and DSS for security reasons. +DEFAULT_CIPHERS = ':'.join([ + 'TLS13-AES-256-GCM-SHA384', + 'TLS13-CHACHA20-POLY1305-SHA256', + 'TLS13-AES-128-GCM-SHA256', + 'ECDH+AESGCM', + 'ECDH+CHACHA20', + 'DH+AESGCM', + 'DH+CHACHA20', + 'ECDH+AES256', + 'DH+AES256', + 'ECDH+AES128', + 'DH+AES', + 'RSA+AESGCM', + 'RSA+AES', + '!aNULL', + '!eNULL', + '!MD5', +]) + +try: + from ssl import SSLContext # Modern SSL? +except ImportError: + import sys + + class SSLContext(object): # Platform-specific: Python 2 & 3.1 + supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or + (3, 2) <= sys.version_info) + + def __init__(self, protocol_version): + self.protocol = protocol_version + # Use default values from a real SSLContext + self.check_hostname = False + self.verify_mode = ssl.CERT_NONE + self.ca_certs = None + self.options = 0 + self.certfile = None + self.keyfile = None + self.ciphers = None + + def load_cert_chain(self, certfile, keyfile): + self.certfile = certfile + self.keyfile = keyfile + + def load_verify_locations(self, cafile=None, capath=None): + self.ca_certs = cafile + + if capath is not None: + raise SSLError("CA directories not supported in older Pythons") + + def set_ciphers(self, cipher_suite): + if not self.supports_set_ciphers: + raise TypeError( + 'Your version of Python does not support setting ' + 'a custom cipher suite. Please upgrade to Python ' + '2.7, 3.2, or later if you need this functionality.' + ) + self.ciphers = cipher_suite + + def wrap_socket(self, socket, server_hostname=None, server_side=False): + warnings.warn( + 'A true SSLContext object is not available. This prevents ' + 'urllib3 from configuring SSL appropriately and may cause ' + 'certain SSL connections to fail. You can upgrade to a newer ' + 'version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + InsecurePlatformWarning + ) + kwargs = { + 'keyfile': self.keyfile, + 'certfile': self.certfile, + 'ca_certs': self.ca_certs, + 'cert_reqs': self.verify_mode, + 'ssl_version': self.protocol, + 'server_side': server_side, + } + if self.supports_set_ciphers: # Platform-specific: Python 2.7+ + return wrap_socket(socket, ciphers=self.ciphers, **kwargs) + else: # Platform-specific: Python 2.6 + return wrap_socket(socket, **kwargs) + + +def assert_fingerprint(cert, fingerprint): + """ + Checks if given fingerprint matches the supplied certificate. + + :param cert: + Certificate as bytes object. + :param fingerprint: + Fingerprint as string of hexdigits, can be interspersed by colons. + """ + + fingerprint = fingerprint.replace(':', '').lower() + digest_length = len(fingerprint) + hashfunc = HASHFUNC_MAP.get(digest_length) + if not hashfunc: + raise SSLError( + 'Fingerprint of invalid length: {0}'.format(fingerprint)) + + # We need encode() here for py32; works on py2 and p33. + fingerprint_bytes = unhexlify(fingerprint.encode()) + + cert_digest = hashfunc(cert).digest() + + if not _const_compare_digest(cert_digest, fingerprint_bytes): + raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' + .format(fingerprint, hexlify(cert_digest))) + + +def resolve_cert_reqs(candidate): + """ + Resolves the argument to a numeric constant, which can be passed to + the wrap_socket function/method from the ssl module. + Defaults to :data:`ssl.CERT_NONE`. + If given a string it is assumed to be the name of the constant in the + :mod:`ssl` module or its abbrevation. + (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. + If it's neither `None` nor a string we assume it is already the numeric + constant which can directly be passed to wrap_socket. + """ + if candidate is None: + return CERT_NONE + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'CERT_' + candidate) + return res + + return candidate + + +def resolve_ssl_version(candidate): + """ + like resolve_cert_reqs + """ + if candidate is None: + return PROTOCOL_SSLv23 + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'PROTOCOL_' + candidate) + return res + + return candidate + + +def create_urllib3_context(ssl_version=None, cert_reqs=None, + options=None, ciphers=None): + """All arguments have the same meaning as ``ssl_wrap_socket``. + + By default, this function does a lot of the same work that + ``ssl.create_default_context`` does on Python 3.4+. It: + + - Disables SSLv2, SSLv3, and compression + - Sets a restricted set of server ciphers + + If you wish to enable SSLv3, you can do:: + + from pip._vendor.urllib3.util import ssl_ + context = ssl_.create_urllib3_context() + context.options &= ~ssl_.OP_NO_SSLv3 + + You can do the same to enable compression (substituting ``COMPRESSION`` + for ``SSLv3`` in the last line above). + + :param ssl_version: + The desired protocol version to use. This will default to + PROTOCOL_SSLv23 which will negotiate the highest protocol that both + the server and your installation of OpenSSL support. + :param cert_reqs: + Whether to require the certificate verification. This defaults to + ``ssl.CERT_REQUIRED``. + :param options: + Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, + ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``. + :param ciphers: + Which cipher suites to allow the server to select. + :returns: + Constructed SSLContext object with specified options + :rtype: SSLContext + """ + context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23) + + # Setting the default here, as we may have no ssl module on import + cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs + + if options is None: + options = 0 + # SSLv2 is easily broken and is considered harmful and dangerous + options |= OP_NO_SSLv2 + # SSLv3 has several problems and is now dangerous + options |= OP_NO_SSLv3 + # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ + # (issue #309) + options |= OP_NO_COMPRESSION + + context.options |= options + + if getattr(context, 'supports_set_ciphers', True): # Platform-specific: Python 2.6 + context.set_ciphers(ciphers or DEFAULT_CIPHERS) + + context.verify_mode = cert_reqs + if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2 + # We do our own verification, including fingerprints and alternative + # hostnames. So disable it here + context.check_hostname = False + return context + + +def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, + ca_certs=None, server_hostname=None, + ssl_version=None, ciphers=None, ssl_context=None, + ca_cert_dir=None): + """ + All arguments except for server_hostname, ssl_context, and ca_cert_dir have + the same meaning as they do when using :func:`ssl.wrap_socket`. + + :param server_hostname: + When SNI is supported, the expected hostname of the certificate + :param ssl_context: + A pre-made :class:`SSLContext` object. If none is provided, one will + be created using :func:`create_urllib3_context`. + :param ciphers: + A string of ciphers we wish the client to support. This is not + supported on Python 2.6 as the ssl module does not support it. + :param ca_cert_dir: + A directory containing CA certificates in multiple separate files, as + supported by OpenSSL's -CApath flag or the capath argument to + SSLContext.load_verify_locations(). + """ + context = ssl_context + if context is None: + # Note: This branch of code and all the variables in it are no longer + # used by urllib3 itself. We should consider deprecating and removing + # this code. + context = create_urllib3_context(ssl_version, cert_reqs, + ciphers=ciphers) + + if ca_certs or ca_cert_dir: + try: + context.load_verify_locations(ca_certs, ca_cert_dir) + except IOError as e: # Platform-specific: Python 2.6, 2.7, 3.2 + raise SSLError(e) + # Py33 raises FileNotFoundError which subclasses OSError + # These are not equivalent unless we check the errno attribute + except OSError as e: # Platform-specific: Python 3.3 and beyond + if e.errno == errno.ENOENT: + raise SSLError(e) + raise + elif getattr(context, 'load_default_certs', None) is not None: + # try to load OS default certs; works well on Windows (require Python3.4+) + context.load_default_certs() + + if certfile: + context.load_cert_chain(certfile, keyfile) + if HAS_SNI: # Platform-specific: OpenSSL with enabled SNI + return context.wrap_socket(sock, server_hostname=server_hostname) + + warnings.warn( + 'An HTTPS request has been made, but the SNI (Subject Name ' + 'Indication) extension to TLS is not available on this platform. ' + 'This may cause the server to present an incorrect TLS ' + 'certificate, which can cause validation failures. You can upgrade to ' + 'a newer version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + SNIMissingWarning + ) + return context.wrap_socket(sock) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/timeout.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/timeout.py new file mode 100644 index 0000000..cec817e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/timeout.py @@ -0,0 +1,242 @@ +from __future__ import absolute_import +# The default socket timeout, used by httplib to indicate that no timeout was +# specified by the user +from socket import _GLOBAL_DEFAULT_TIMEOUT +import time + +from ..exceptions import TimeoutStateError + +# A sentinel value to indicate that no timeout was specified by the user in +# urllib3 +_Default = object() + + +# Use time.monotonic if available. +current_time = getattr(time, "monotonic", time.time) + + +class Timeout(object): + """ Timeout configuration. + + Timeouts can be defined as a default for a pool:: + + timeout = Timeout(connect=2.0, read=7.0) + http = PoolManager(timeout=timeout) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) + + Timeouts can be disabled by setting all the parameters to ``None``:: + + no_timeout = Timeout(connect=None, read=None) + response = http.request('GET', 'http://example.com/, timeout=no_timeout) + + + :param total: + This combines the connect and read timeouts into one; the read timeout + will be set to the time leftover from the connect attempt. In the + event that both a connect timeout and a total are specified, or a read + timeout and a total are specified, the shorter timeout will be applied. + + Defaults to None. + + :type total: integer, float, or None + + :param connect: + The maximum amount of time to wait for a connection attempt to a server + to succeed. Omitting the parameter will default the connect timeout to + the system default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout for connection attempts. + + :type connect: integer, float, or None + + :param read: + The maximum amount of time to wait between consecutive + read operations for a response from the server. Omitting + the parameter will default the read timeout to the system + default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout. + + :type read: integer, float, or None + + .. note:: + + Many factors can affect the total amount of time for urllib3 to return + an HTTP response. + + For example, Python's DNS resolver does not obey the timeout specified + on the socket. Other factors that can affect total request time include + high CPU load, high swap, the program running at a low priority level, + or other behaviors. + + In addition, the read and total timeouts only measure the time between + read operations on the socket connecting the client and the server, + not the total amount of time for the request to return a complete + response. For most requests, the timeout is raised because the server + has not sent the first byte in the specified time. This is not always + the case; if a server streams one byte every fifteen seconds, a timeout + of 20 seconds will not trigger, even though the request will take + several minutes to complete. + + If your goal is to cut off any request after a set amount of wall clock + time, consider having a second "watcher" thread to cut off a slow + request. + """ + + #: A sentinel object representing the default timeout value + DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT + + def __init__(self, total=None, connect=_Default, read=_Default): + self._connect = self._validate_timeout(connect, 'connect') + self._read = self._validate_timeout(read, 'read') + self.total = self._validate_timeout(total, 'total') + self._start_connect = None + + def __str__(self): + return '%s(connect=%r, read=%r, total=%r)' % ( + type(self).__name__, self._connect, self._read, self.total) + + @classmethod + def _validate_timeout(cls, value, name): + """ Check that a timeout attribute is valid. + + :param value: The timeout value to validate + :param name: The name of the timeout attribute to validate. This is + used to specify in error messages. + :return: The validated and casted version of the given value. + :raises ValueError: If it is a numeric value less than or equal to + zero, or the type is not an integer, float, or None. + """ + if value is _Default: + return cls.DEFAULT_TIMEOUT + + if value is None or value is cls.DEFAULT_TIMEOUT: + return value + + if isinstance(value, bool): + raise ValueError("Timeout cannot be a boolean value. It must " + "be an int, float or None.") + try: + float(value) + except (TypeError, ValueError): + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + try: + if value <= 0: + raise ValueError("Attempted to set %s timeout to %s, but the " + "timeout cannot be set to a value less " + "than or equal to 0." % (name, value)) + except TypeError: # Python 3 + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + return value + + @classmethod + def from_float(cls, timeout): + """ Create a new Timeout from a legacy timeout value. + + The timeout value used by httplib.py sets the same timeout on the + connect(), and recv() socket requests. This creates a :class:`Timeout` + object that sets the individual timeouts to the ``timeout`` value + passed to this function. + + :param timeout: The legacy timeout value. + :type timeout: integer, float, sentinel default object, or None + :return: Timeout object + :rtype: :class:`Timeout` + """ + return Timeout(read=timeout, connect=timeout) + + def clone(self): + """ Create a copy of the timeout object + + Timeout properties are stored per-pool but each request needs a fresh + Timeout object to ensure each one has its own start/stop configured. + + :return: a copy of the timeout object + :rtype: :class:`Timeout` + """ + # We can't use copy.deepcopy because that will also create a new object + # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to + # detect the user default. + return Timeout(connect=self._connect, read=self._read, + total=self.total) + + def start_connect(self): + """ Start the timeout clock, used during a connect() attempt + + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to start a timer that has been started already. + """ + if self._start_connect is not None: + raise TimeoutStateError("Timeout timer has already been started.") + self._start_connect = current_time() + return self._start_connect + + def get_connect_duration(self): + """ Gets the time elapsed since the call to :meth:`start_connect`. + + :return: Elapsed time. + :rtype: float + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to get duration for a timer that hasn't been started. + """ + if self._start_connect is None: + raise TimeoutStateError("Can't get connect duration for timer " + "that has not started.") + return current_time() - self._start_connect + + @property + def connect_timeout(self): + """ Get the value to use when setting a connection timeout. + + This will be a positive float or integer, the value None + (never timeout), or the default system timeout. + + :return: Connect timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + """ + if self.total is None: + return self._connect + + if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: + return self.total + + return min(self._connect, self.total) + + @property + def read_timeout(self): + """ Get the value for the read timeout. + + This assumes some time has elapsed in the connection timeout and + computes the read timeout appropriately. + + If self.total is set, the read timeout is dependent on the amount of + time taken by the connect timeout. If the connection time has not been + established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be + raised. + + :return: Value to use for the read timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` + has not yet been called on this object. + """ + if (self.total is not None and + self.total is not self.DEFAULT_TIMEOUT and + self._read is not None and + self._read is not self.DEFAULT_TIMEOUT): + # In case the connect timeout has not yet been established. + if self._start_connect is None: + return self._read + return max(0, min(self.total - self.get_connect_duration(), + self._read)) + elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: + return max(0, self.total - self.get_connect_duration()) + else: + return self._read diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py new file mode 100644 index 0000000..6b6f996 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/url.py @@ -0,0 +1,230 @@ +from __future__ import absolute_import +from collections import namedtuple + +from ..exceptions import LocationParseError + + +url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] + +# We only want to normalize urls with an HTTP(S) scheme. +# urllib3 infers URLs without a scheme (None) to be http. +NORMALIZABLE_SCHEMES = ('http', 'https', None) + + +class Url(namedtuple('Url', url_attrs)): + """ + Datastructure for representing an HTTP URL. Used as a return value for + :func:`parse_url`. Both the scheme and host are normalized as they are + both case-insensitive according to RFC 3986. + """ + __slots__ = () + + def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, + query=None, fragment=None): + if path and not path.startswith('/'): + path = '/' + path + if scheme: + scheme = scheme.lower() + if host and scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return super(Url, cls).__new__(cls, scheme, auth, host, port, path, + query, fragment) + + @property + def hostname(self): + """For backwards-compatibility with urlparse. We're nice like that.""" + return self.host + + @property + def request_uri(self): + """Absolute path including the query string.""" + uri = self.path or '/' + + if self.query is not None: + uri += '?' + self.query + + return uri + + @property + def netloc(self): + """Network location including host and port""" + if self.port: + return '%s:%d' % (self.host, self.port) + return self.host + + @property + def url(self): + """ + Convert self into a url + + This function should more or less round-trip with :func:`.parse_url`. The + returned url may not be exactly the same as the url inputted to + :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls + with a blank port will have : removed). + + Example: :: + + >>> U = parse_url('http://google.com/mail/') + >>> U.url + 'http://google.com/mail/' + >>> Url('http', 'username:password', 'host.com', 80, + ... '/path', 'query', 'fragment').url + 'http://username:password@host.com:80/path?query#fragment' + """ + scheme, auth, host, port, path, query, fragment = self + url = '' + + # We use "is not None" we want things to happen with empty strings (or 0 port) + if scheme is not None: + url += scheme + '://' + if auth is not None: + url += auth + '@' + if host is not None: + url += host + if port is not None: + url += ':' + str(port) + if path is not None: + url += path + if query is not None: + url += '?' + query + if fragment is not None: + url += '#' + fragment + + return url + + def __str__(self): + return self.url + + +def split_first(s, delims): + """ + Given a string and an iterable of delimiters, split on the first found + delimiter. Return two split parts and the matched delimiter. + + If not found, then the first part is the full input string. + + Example:: + + >>> split_first('foo/bar?baz', '?/=') + ('foo', 'bar?baz', '/') + >>> split_first('foo/bar?baz', '123') + ('foo/bar?baz', '', None) + + Scales linearly with number of delims. Not ideal for large number of delims. + """ + min_idx = None + min_delim = None + for d in delims: + idx = s.find(d) + if idx < 0: + continue + + if min_idx is None or idx < min_idx: + min_idx = idx + min_delim = d + + if min_idx is None or min_idx < 0: + return s, '', None + + return s[:min_idx], s[min_idx + 1:], min_delim + + +def parse_url(url): + """ + Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is + performed to parse incomplete urls. Fields not provided will be None. + + Partly backwards-compatible with :mod:`urlparse`. + + Example:: + + >>> parse_url('http://google.com/mail/') + Url(scheme='http', host='google.com', port=None, path='/mail/', ...) + >>> parse_url('google.com:80') + Url(scheme=None, host='google.com', port=80, path=None, ...) + >>> parse_url('/foo?bar') + Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) + """ + + # While this code has overlap with stdlib's urlparse, it is much + # simplified for our needs and less annoying. + # Additionally, this implementations does silly things to be optimal + # on CPython. + + if not url: + # Empty + return Url() + + scheme = None + auth = None + host = None + port = None + path = None + fragment = None + query = None + + # Scheme + if '://' in url: + scheme, url = url.split('://', 1) + + # Find the earliest Authority Terminator + # (http://tools.ietf.org/html/rfc3986#section-3.2) + url, path_, delim = split_first(url, ['/', '?', '#']) + + if delim: + # Reassemble the path + path = delim + path_ + + # Auth + if '@' in url: + # Last '@' denotes end of auth part + auth, url = url.rsplit('@', 1) + + # IPv6 + if url and url[0] == '[': + host, url = url.split(']', 1) + host += ']' + + # Port + if ':' in url: + _host, port = url.split(':', 1) + + if not host: + host = _host + + if port: + # If given, ports must be integers. No whitespace, no plus or + # minus prefixes, no non-integer digits such as ^2 (superscript). + if not port.isdigit(): + raise LocationParseError(url) + try: + port = int(port) + except ValueError: + raise LocationParseError(url) + else: + # Blank ports are cool, too. (rfc3986#section-3.2.3) + port = None + + elif not host and url: + host = url + + if not path: + return Url(scheme, auth, host, port, path, query, fragment) + + # Fragment + if '#' in path: + path, fragment = path.split('#', 1) + + # Query + if '?' in path: + path, query = path.split('?', 1) + + return Url(scheme, auth, host, port, path, query, fragment) + + +def get_host(url): + """ + Deprecated. Use :func:`parse_url` instead. + """ + p = parse_url(url) + return p.scheme or 'http', p.hostname, p.port diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/wait.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/wait.py new file mode 100644 index 0000000..cb396e5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/urllib3/util/wait.py @@ -0,0 +1,40 @@ +from .selectors import ( + HAS_SELECT, + DefaultSelector, + EVENT_READ, + EVENT_WRITE +) + + +def _wait_for_io_events(socks, events, timeout=None): + """ Waits for IO events to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be interacted with immediately. """ + if not HAS_SELECT: + raise ValueError('Platform does not have a selector') + if not isinstance(socks, list): + # Probably just a single socket. + if hasattr(socks, "fileno"): + socks = [socks] + # Otherwise it might be a non-list iterable. + else: + socks = list(socks) + with DefaultSelector() as selector: + for sock in socks: + selector.register(sock, events) + return [key[0].fileobj for key in + selector.select(timeout) if key[1] & events] + + +def wait_for_read(socks, timeout=None): + """ Waits for reading to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be read from immediately. """ + return _wait_for_io_events(socks, EVENT_READ, timeout) + + +def wait_for_write(socks, timeout=None): + """ Waits for writing to be available from a list of sockets + or optionally a single socket if passed in. Returns a list of + sockets that can be written to immediately. """ + return _wait_for_io_events(socks, EVENT_WRITE, timeout) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__init__.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__init__.py new file mode 100644 index 0000000..d21d697 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__init__.py @@ -0,0 +1,342 @@ +# coding: utf-8 +""" + + webencodings + ~~~~~~~~~~~~ + + This is a Python implementation of the `WHATWG Encoding standard + <http://encoding.spec.whatwg.org/>`. See README for details. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + +from .labels import LABELS + + +VERSION = '0.5.1' + + +# Some names in Encoding are not valid Python aliases. Remap these. +PYTHON_NAMES = { + 'iso-8859-8-i': 'iso-8859-8', + 'x-mac-cyrillic': 'mac-cyrillic', + 'macintosh': 'mac-roman', + 'windows-874': 'cp874'} + +CACHE = {} + + +def ascii_lower(string): + r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. + + :param string: An Unicode string. + :returns: A new Unicode string. + + This is used for `ASCII case-insensitive + <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_ + matching of encoding labels. + The same matching is also used, among other things, + for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_. + + This is different from the :meth:`~py:str.lower` method of Unicode strings + which also affect non-ASCII characters, + sometimes mapping them into the ASCII range: + + >>> keyword = u'Bac\N{KELVIN SIGN}ground' + >>> assert keyword.lower() == u'background' + >>> assert ascii_lower(keyword) != keyword.lower() + >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' + + """ + # This turns out to be faster than unicode.translate() + return string.encode('utf8').lower().decode('utf8') + + +def lookup(label): + """ + Look for an encoding by its label. + This is the spec’s `get an encoding + <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm. + Supported labels are listed there. + + :param label: A string. + :returns: + An :class:`Encoding` object, or :obj:`None` for an unknown label. + + """ + # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. + label = ascii_lower(label.strip('\t\n\f\r ')) + name = LABELS.get(label) + if name is None: + return None + encoding = CACHE.get(name) + if encoding is None: + if name == 'x-user-defined': + from .x_user_defined import codec_info + else: + python_name = PYTHON_NAMES.get(name, name) + # Any python_name value that gets to here should be valid. + codec_info = codecs.lookup(python_name) + encoding = Encoding(name, codec_info) + CACHE[name] = encoding + return encoding + + +def _get_encoding(encoding_or_label): + """ + Accept either an encoding object or label. + + :param encoding: An :class:`Encoding` object or a label string. + :returns: An :class:`Encoding` object. + :raises: :exc:`~exceptions.LookupError` for an unknown label. + + """ + if hasattr(encoding_or_label, 'codec_info'): + return encoding_or_label + + encoding = lookup(encoding_or_label) + if encoding is None: + raise LookupError('Unknown encoding label: %r' % encoding_or_label) + return encoding + + +class Encoding(object): + """Reresents a character encoding such as UTF-8, + that can be used for decoding or encoding. + + .. attribute:: name + + Canonical name of the encoding + + .. attribute:: codec_info + + The actual implementation of the encoding, + a stdlib :class:`~codecs.CodecInfo` object. + See :func:`codecs.register`. + + """ + def __init__(self, name, codec_info): + self.name = name + self.codec_info = codec_info + + def __repr__(self): + return '<Encoding %s>' % self.name + + +#: The UTF-8 encoding. Should be used for new content and formats. +UTF8 = lookup('utf-8') + +_UTF16LE = lookup('utf-16le') +_UTF16BE = lookup('utf-16be') + + +def decode(input, fallback_encoding, errors='replace'): + """ + Decode a single string. + + :param input: A byte string + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: + A ``(output, encoding)`` tuple of an Unicode string + and an :obj:`Encoding`. + + """ + # Fail early if `encoding` is an invalid label. + fallback_encoding = _get_encoding(fallback_encoding) + bom_encoding, input = _detect_bom(input) + encoding = bom_encoding or fallback_encoding + return encoding.codec_info.decode(input, errors)[0], encoding + + +def _detect_bom(input): + """Return (bom_encoding, input), with any BOM removed from the input.""" + if input.startswith(b'\xFF\xFE'): + return _UTF16LE, input[2:] + if input.startswith(b'\xFE\xFF'): + return _UTF16BE, input[2:] + if input.startswith(b'\xEF\xBB\xBF'): + return UTF8, input[3:] + return None, input + + +def encode(input, encoding=UTF8, errors='strict'): + """ + Encode a single string. + + :param input: An Unicode string. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: A byte string. + + """ + return _get_encoding(encoding).codec_info.encode(input, errors)[0] + + +def iter_decode(input, fallback_encoding, errors='replace'): + """ + "Pull"-based decoder. + + :param input: + An iterable of byte strings. + + The input is first consumed just enough to determine the encoding + based on the precense of a BOM, + then consumed on demand when the return value is. + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: + An ``(output, encoding)`` tuple. + :obj:`output` is an iterable of Unicode strings, + :obj:`encoding` is the :obj:`Encoding` that is being used. + + """ + + decoder = IncrementalDecoder(fallback_encoding, errors) + generator = _iter_decode_generator(input, decoder) + encoding = next(generator) + return generator, encoding + + +def _iter_decode_generator(input, decoder): + """Return a generator that first yields the :obj:`Encoding`, + then yields output chukns as Unicode strings. + + """ + decode = decoder.decode + input = iter(input) + for chunck in input: + output = decode(chunck) + if output: + assert decoder.encoding is not None + yield decoder.encoding + yield output + break + else: + # Input exhausted without determining the encoding + output = decode(b'', final=True) + assert decoder.encoding is not None + yield decoder.encoding + if output: + yield output + return + + for chunck in input: + output = decode(chunck) + if output: + yield output + output = decode(b'', final=True) + if output: + yield output + + +def iter_encode(input, encoding=UTF8, errors='strict'): + """ + “Pull”-based encoder. + + :param input: An iterable of Unicode strings. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: An iterable of byte strings. + + """ + # Fail early if `encoding` is an invalid label. + encode = IncrementalEncoder(encoding, errors).encode + return _iter_encode_generator(input, encode) + + +def _iter_encode_generator(input, encode): + for chunck in input: + output = encode(chunck) + if output: + yield output + output = encode('', final=True) + if output: + yield output + + +class IncrementalDecoder(object): + """ + “Push”-based decoder. + + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + """ + def __init__(self, fallback_encoding, errors='replace'): + # Fail early if `encoding` is an invalid label. + self._fallback_encoding = _get_encoding(fallback_encoding) + self._errors = errors + self._buffer = b'' + self._decoder = None + #: The actual :class:`Encoding` that is being used, + #: or :obj:`None` if that is not determined yet. + #: (Ie. if there is not enough input yet to determine + #: if there is a BOM.) + self.encoding = None # Not known yet. + + def decode(self, input, final=False): + """Decode one chunk of the input. + + :param input: A byte string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: An Unicode string. + + """ + decoder = self._decoder + if decoder is not None: + return decoder(input, final) + + input = self._buffer + input + encoding, input = _detect_bom(input) + if encoding is None: + if len(input) < 3 and not final: # Not enough data yet. + self._buffer = input + return '' + else: # No BOM + encoding = self._fallback_encoding + decoder = encoding.codec_info.incrementaldecoder(self._errors).decode + self._decoder = decoder + self.encoding = encoding + return decoder(input, final) + + +class IncrementalEncoder(object): + """ + “Push”-based encoder. + + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + .. method:: encode(input, final=False) + + :param input: An Unicode string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: A byte string. + + """ + def __init__(self, encoding=UTF8, errors='strict'): + encoding = _get_encoding(encoding) + self.encode = encoding.codec_info.incrementalencoder(errors).encode diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..e76c5da Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc new file mode 100644 index 0000000..9a04b84 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/labels.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/labels.py new file mode 100644 index 0000000..29cbf91 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/labels.py @@ -0,0 +1,231 @@ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { + 'unicode-1-1-utf-8': 'utf-8', + 'utf-8': 'utf-8', + 'utf8': 'utf-8', + '866': 'ibm866', + 'cp866': 'ibm866', + 'csibm866': 'ibm866', + 'ibm866': 'ibm866', + 'csisolatin2': 'iso-8859-2', + 'iso-8859-2': 'iso-8859-2', + 'iso-ir-101': 'iso-8859-2', + 'iso8859-2': 'iso-8859-2', + 'iso88592': 'iso-8859-2', + 'iso_8859-2': 'iso-8859-2', + 'iso_8859-2:1987': 'iso-8859-2', + 'l2': 'iso-8859-2', + 'latin2': 'iso-8859-2', + 'csisolatin3': 'iso-8859-3', + 'iso-8859-3': 'iso-8859-3', + 'iso-ir-109': 'iso-8859-3', + 'iso8859-3': 'iso-8859-3', + 'iso88593': 'iso-8859-3', + 'iso_8859-3': 'iso-8859-3', + 'iso_8859-3:1988': 'iso-8859-3', + 'l3': 'iso-8859-3', + 'latin3': 'iso-8859-3', + 'csisolatin4': 'iso-8859-4', + 'iso-8859-4': 'iso-8859-4', + 'iso-ir-110': 'iso-8859-4', + 'iso8859-4': 'iso-8859-4', + 'iso88594': 'iso-8859-4', + 'iso_8859-4': 'iso-8859-4', + 'iso_8859-4:1988': 'iso-8859-4', + 'l4': 'iso-8859-4', + 'latin4': 'iso-8859-4', + 'csisolatincyrillic': 'iso-8859-5', + 'cyrillic': 'iso-8859-5', + 'iso-8859-5': 'iso-8859-5', + 'iso-ir-144': 'iso-8859-5', + 'iso8859-5': 'iso-8859-5', + 'iso88595': 'iso-8859-5', + 'iso_8859-5': 'iso-8859-5', + 'iso_8859-5:1988': 'iso-8859-5', + 'arabic': 'iso-8859-6', + 'asmo-708': 'iso-8859-6', + 'csiso88596e': 'iso-8859-6', + 'csiso88596i': 'iso-8859-6', + 'csisolatinarabic': 'iso-8859-6', + 'ecma-114': 'iso-8859-6', + 'iso-8859-6': 'iso-8859-6', + 'iso-8859-6-e': 'iso-8859-6', + 'iso-8859-6-i': 'iso-8859-6', + 'iso-ir-127': 'iso-8859-6', + 'iso8859-6': 'iso-8859-6', + 'iso88596': 'iso-8859-6', + 'iso_8859-6': 'iso-8859-6', + 'iso_8859-6:1987': 'iso-8859-6', + 'csisolatingreek': 'iso-8859-7', + 'ecma-118': 'iso-8859-7', + 'elot_928': 'iso-8859-7', + 'greek': 'iso-8859-7', + 'greek8': 'iso-8859-7', + 'iso-8859-7': 'iso-8859-7', + 'iso-ir-126': 'iso-8859-7', + 'iso8859-7': 'iso-8859-7', + 'iso88597': 'iso-8859-7', + 'iso_8859-7': 'iso-8859-7', + 'iso_8859-7:1987': 'iso-8859-7', + 'sun_eu_greek': 'iso-8859-7', + 'csiso88598e': 'iso-8859-8', + 'csisolatinhebrew': 'iso-8859-8', + 'hebrew': 'iso-8859-8', + 'iso-8859-8': 'iso-8859-8', + 'iso-8859-8-e': 'iso-8859-8', + 'iso-ir-138': 'iso-8859-8', + 'iso8859-8': 'iso-8859-8', + 'iso88598': 'iso-8859-8', + 'iso_8859-8': 'iso-8859-8', + 'iso_8859-8:1988': 'iso-8859-8', + 'visual': 'iso-8859-8', + 'csiso88598i': 'iso-8859-8-i', + 'iso-8859-8-i': 'iso-8859-8-i', + 'logical': 'iso-8859-8-i', + 'csisolatin6': 'iso-8859-10', + 'iso-8859-10': 'iso-8859-10', + 'iso-ir-157': 'iso-8859-10', + 'iso8859-10': 'iso-8859-10', + 'iso885910': 'iso-8859-10', + 'l6': 'iso-8859-10', + 'latin6': 'iso-8859-10', + 'iso-8859-13': 'iso-8859-13', + 'iso8859-13': 'iso-8859-13', + 'iso885913': 'iso-8859-13', + 'iso-8859-14': 'iso-8859-14', + 'iso8859-14': 'iso-8859-14', + 'iso885914': 'iso-8859-14', + 'csisolatin9': 'iso-8859-15', + 'iso-8859-15': 'iso-8859-15', + 'iso8859-15': 'iso-8859-15', + 'iso885915': 'iso-8859-15', + 'iso_8859-15': 'iso-8859-15', + 'l9': 'iso-8859-15', + 'iso-8859-16': 'iso-8859-16', + 'cskoi8r': 'koi8-r', + 'koi': 'koi8-r', + 'koi8': 'koi8-r', + 'koi8-r': 'koi8-r', + 'koi8_r': 'koi8-r', + 'koi8-u': 'koi8-u', + 'csmacintosh': 'macintosh', + 'mac': 'macintosh', + 'macintosh': 'macintosh', + 'x-mac-roman': 'macintosh', + 'dos-874': 'windows-874', + 'iso-8859-11': 'windows-874', + 'iso8859-11': 'windows-874', + 'iso885911': 'windows-874', + 'tis-620': 'windows-874', + 'windows-874': 'windows-874', + 'cp1250': 'windows-1250', + 'windows-1250': 'windows-1250', + 'x-cp1250': 'windows-1250', + 'cp1251': 'windows-1251', + 'windows-1251': 'windows-1251', + 'x-cp1251': 'windows-1251', + 'ansi_x3.4-1968': 'windows-1252', + 'ascii': 'windows-1252', + 'cp1252': 'windows-1252', + 'cp819': 'windows-1252', + 'csisolatin1': 'windows-1252', + 'ibm819': 'windows-1252', + 'iso-8859-1': 'windows-1252', + 'iso-ir-100': 'windows-1252', + 'iso8859-1': 'windows-1252', + 'iso88591': 'windows-1252', + 'iso_8859-1': 'windows-1252', + 'iso_8859-1:1987': 'windows-1252', + 'l1': 'windows-1252', + 'latin1': 'windows-1252', + 'us-ascii': 'windows-1252', + 'windows-1252': 'windows-1252', + 'x-cp1252': 'windows-1252', + 'cp1253': 'windows-1253', + 'windows-1253': 'windows-1253', + 'x-cp1253': 'windows-1253', + 'cp1254': 'windows-1254', + 'csisolatin5': 'windows-1254', + 'iso-8859-9': 'windows-1254', + 'iso-ir-148': 'windows-1254', + 'iso8859-9': 'windows-1254', + 'iso88599': 'windows-1254', + 'iso_8859-9': 'windows-1254', + 'iso_8859-9:1989': 'windows-1254', + 'l5': 'windows-1254', + 'latin5': 'windows-1254', + 'windows-1254': 'windows-1254', + 'x-cp1254': 'windows-1254', + 'cp1255': 'windows-1255', + 'windows-1255': 'windows-1255', + 'x-cp1255': 'windows-1255', + 'cp1256': 'windows-1256', + 'windows-1256': 'windows-1256', + 'x-cp1256': 'windows-1256', + 'cp1257': 'windows-1257', + 'windows-1257': 'windows-1257', + 'x-cp1257': 'windows-1257', + 'cp1258': 'windows-1258', + 'windows-1258': 'windows-1258', + 'x-cp1258': 'windows-1258', + 'x-mac-cyrillic': 'x-mac-cyrillic', + 'x-mac-ukrainian': 'x-mac-cyrillic', + 'chinese': 'gbk', + 'csgb2312': 'gbk', + 'csiso58gb231280': 'gbk', + 'gb2312': 'gbk', + 'gb_2312': 'gbk', + 'gb_2312-80': 'gbk', + 'gbk': 'gbk', + 'iso-ir-58': 'gbk', + 'x-gbk': 'gbk', + 'gb18030': 'gb18030', + 'hz-gb-2312': 'hz-gb-2312', + 'big5': 'big5', + 'big5-hkscs': 'big5', + 'cn-big5': 'big5', + 'csbig5': 'big5', + 'x-x-big5': 'big5', + 'cseucpkdfmtjapanese': 'euc-jp', + 'euc-jp': 'euc-jp', + 'x-euc-jp': 'euc-jp', + 'csiso2022jp': 'iso-2022-jp', + 'iso-2022-jp': 'iso-2022-jp', + 'csshiftjis': 'shift_jis', + 'ms_kanji': 'shift_jis', + 'shift-jis': 'shift_jis', + 'shift_jis': 'shift_jis', + 'sjis': 'shift_jis', + 'windows-31j': 'shift_jis', + 'x-sjis': 'shift_jis', + 'cseuckr': 'euc-kr', + 'csksc56011987': 'euc-kr', + 'euc-kr': 'euc-kr', + 'iso-ir-149': 'euc-kr', + 'korean': 'euc-kr', + 'ks_c_5601-1987': 'euc-kr', + 'ks_c_5601-1989': 'euc-kr', + 'ksc5601': 'euc-kr', + 'ksc_5601': 'euc-kr', + 'windows-949': 'euc-kr', + 'csiso2022kr': 'iso-2022-kr', + 'iso-2022-kr': 'iso-2022-kr', + 'utf-16be': 'utf-16be', + 'utf-16': 'utf-16le', + 'utf-16le': 'utf-16le', + 'x-user-defined': 'x-user-defined', +} diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/mklabels.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/mklabels.py new file mode 100644 index 0000000..295dc92 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/mklabels.py @@ -0,0 +1,59 @@ +""" + + webencodings.mklabels + ~~~~~~~~~~~~~~~~~~~~~ + + Regenarate the webencodings.labels module. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +import json +try: + from urllib import urlopen +except ImportError: + from urllib.request import urlopen + + +def assert_lower(string): + assert string == string.lower() + return string + + +def generate(url): + parts = ['''\ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { +'''] + labels = [ + (repr(assert_lower(label)).lstrip('u'), + repr(encoding['name']).lstrip('u')) + for category in json.loads(urlopen(url).read().decode('ascii')) + for encoding in category['encodings'] + for label in encoding['labels']] + max_len = max(len(label) for label, name in labels) + parts.extend( + ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name) + for label, name in labels) + parts.append('}') + return ''.join(parts) + + +if __name__ == '__main__': + print(generate('http://encoding.spec.whatwg.org/encodings.json')) diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/tests.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/tests.py new file mode 100644 index 0000000..e12c10d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/tests.py @@ -0,0 +1,153 @@ +# coding: utf-8 +""" + + webencodings.tests + ~~~~~~~~~~~~~~~~~~ + + A basic test suite for Encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode, + IncrementalDecoder, IncrementalEncoder, UTF8) + + +def assert_raises(exception, function, *args, **kwargs): + try: + function(*args, **kwargs) + except exception: + return + else: # pragma: no cover + raise AssertionError('Did not raise %s.' % exception) + + +def test_labels(): + assert lookup('utf-8').name == 'utf-8' + assert lookup('Utf-8').name == 'utf-8' + assert lookup('UTF-8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8 ').name == 'utf-8' + assert lookup(' \r\nutf8\t').name == 'utf-8' + assert lookup('u8') is None # Python label. + assert lookup('utf-8 ') is None # Non-ASCII white space. + + assert lookup('US-ASCII').name == 'windows-1252' + assert lookup('iso-8859-1').name == 'windows-1252' + assert lookup('latin1').name == 'windows-1252' + assert lookup('LATIN1').name == 'windows-1252' + assert lookup('latin-1') is None + assert lookup('LATİN1') is None # ASCII-only case insensitivity. + + +def test_all_labels(): + for label in LABELS: + assert decode(b'', label) == ('', lookup(label)) + assert encode('', label) == b'' + for repeat in [0, 1, 12]: + output, _ = iter_decode([b''] * repeat, label) + assert list(output) == [] + assert list(iter_encode([''] * repeat, label)) == [] + decoder = IncrementalDecoder(label) + assert decoder.decode(b'') == '' + assert decoder.decode(b'', final=True) == '' + encoder = IncrementalEncoder(label) + assert encoder.encode('') == b'' + assert encoder.encode('', final=True) == b'' + # All encoding names are valid labels too: + for name in set(LABELS.values()): + assert lookup(name).name == name + + +def test_invalid_label(): + assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid') + assert_raises(LookupError, encode, 'é', 'invalid') + assert_raises(LookupError, iter_decode, [], 'invalid') + assert_raises(LookupError, iter_encode, [], 'invalid') + assert_raises(LookupError, IncrementalDecoder, 'invalid') + assert_raises(LookupError, IncrementalEncoder, 'invalid') + + +def test_decode(): + assert decode(b'\x80', 'latin1') == ('€', lookup('latin1')) + assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1')) + assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii')) + assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM + + assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM + assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM + assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be')) + assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le')) + + assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be')) + assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le')) + assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le')) + + assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be')) + assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le')) + assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le')) + + +def test_encode(): + assert encode('é', 'latin1') == b'\xe9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf-16') == b'\xe9\x00' + assert encode('é', 'utf-16le') == b'\xe9\x00' + assert encode('é', 'utf-16be') == b'\x00\xe9' + + +def test_iter_decode(): + def iter_decode_to_string(input, fallback_encoding): + output, _encoding = iter_decode(input, fallback_encoding) + return ''.join(output) + assert iter_decode_to_string([], 'latin1') == '' + assert iter_decode_to_string([b''], 'latin1') == '' + assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'hello'], 'latin1') == 'hello' + assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello' + assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello' + assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD' + assert iter_decode_to_string([ + b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == '' + assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»' + assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo' + + +def test_iter_encode(): + assert b''.join(iter_encode([], 'latin1')) == b'' + assert b''.join(iter_encode([''], 'latin1')) == b'' + assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9' + assert b''.join(iter_encode([ + '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo' + + +def test_x_user_defined(): + encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca' + decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca' + encoded = b'aa' + decoded = 'aa' + assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined')) + assert encode(decoded, 'x-user-defined') == encoded diff --git a/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py new file mode 100644 index 0000000..d16e326 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/webencodings/x_user_defined.py @@ -0,0 +1,325 @@ +# coding: utf-8 +""" + + webencodings.x_user_defined + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + An implementation of the x-user-defined encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +### encodings module API + +codec_info = codecs.CodecInfo( + name='x-user-defined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, +) + + +### Decoding Table + +# Python 3: +# for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700)) +decoding_table = ( + '\x00' + '\x01' + '\x02' + '\x03' + '\x04' + '\x05' + '\x06' + '\x07' + '\x08' + '\t' + '\n' + '\x0b' + '\x0c' + '\r' + '\x0e' + '\x0f' + '\x10' + '\x11' + '\x12' + '\x13' + '\x14' + '\x15' + '\x16' + '\x17' + '\x18' + '\x19' + '\x1a' + '\x1b' + '\x1c' + '\x1d' + '\x1e' + '\x1f' + ' ' + '!' + '"' + '#' + '$' + '%' + '&' + "'" + '(' + ')' + '*' + '+' + ',' + '-' + '.' + '/' + '0' + '1' + '2' + '3' + '4' + '5' + '6' + '7' + '8' + '9' + ':' + ';' + '<' + '=' + '>' + '?' + '@' + 'A' + 'B' + 'C' + 'D' + 'E' + 'F' + 'G' + 'H' + 'I' + 'J' + 'K' + 'L' + 'M' + 'N' + 'O' + 'P' + 'Q' + 'R' + 'S' + 'T' + 'U' + 'V' + 'W' + 'X' + 'Y' + 'Z' + '[' + '\\' + ']' + '^' + '_' + '`' + 'a' + 'b' + 'c' + 'd' + 'e' + 'f' + 'g' + 'h' + 'i' + 'j' + 'k' + 'l' + 'm' + 'n' + 'o' + 'p' + 'q' + 'r' + 's' + 't' + 'u' + 'v' + 'w' + 'x' + 'y' + 'z' + '{' + '|' + '}' + '~' + '\x7f' + '\uf780' + '\uf781' + '\uf782' + '\uf783' + '\uf784' + '\uf785' + '\uf786' + '\uf787' + '\uf788' + '\uf789' + '\uf78a' + '\uf78b' + '\uf78c' + '\uf78d' + '\uf78e' + '\uf78f' + '\uf790' + '\uf791' + '\uf792' + '\uf793' + '\uf794' + '\uf795' + '\uf796' + '\uf797' + '\uf798' + '\uf799' + '\uf79a' + '\uf79b' + '\uf79c' + '\uf79d' + '\uf79e' + '\uf79f' + '\uf7a0' + '\uf7a1' + '\uf7a2' + '\uf7a3' + '\uf7a4' + '\uf7a5' + '\uf7a6' + '\uf7a7' + '\uf7a8' + '\uf7a9' + '\uf7aa' + '\uf7ab' + '\uf7ac' + '\uf7ad' + '\uf7ae' + '\uf7af' + '\uf7b0' + '\uf7b1' + '\uf7b2' + '\uf7b3' + '\uf7b4' + '\uf7b5' + '\uf7b6' + '\uf7b7' + '\uf7b8' + '\uf7b9' + '\uf7ba' + '\uf7bb' + '\uf7bc' + '\uf7bd' + '\uf7be' + '\uf7bf' + '\uf7c0' + '\uf7c1' + '\uf7c2' + '\uf7c3' + '\uf7c4' + '\uf7c5' + '\uf7c6' + '\uf7c7' + '\uf7c8' + '\uf7c9' + '\uf7ca' + '\uf7cb' + '\uf7cc' + '\uf7cd' + '\uf7ce' + '\uf7cf' + '\uf7d0' + '\uf7d1' + '\uf7d2' + '\uf7d3' + '\uf7d4' + '\uf7d5' + '\uf7d6' + '\uf7d7' + '\uf7d8' + '\uf7d9' + '\uf7da' + '\uf7db' + '\uf7dc' + '\uf7dd' + '\uf7de' + '\uf7df' + '\uf7e0' + '\uf7e1' + '\uf7e2' + '\uf7e3' + '\uf7e4' + '\uf7e5' + '\uf7e6' + '\uf7e7' + '\uf7e8' + '\uf7e9' + '\uf7ea' + '\uf7eb' + '\uf7ec' + '\uf7ed' + '\uf7ee' + '\uf7ef' + '\uf7f0' + '\uf7f1' + '\uf7f2' + '\uf7f3' + '\uf7f4' + '\uf7f5' + '\uf7f6' + '\uf7f7' + '\uf7f8' + '\uf7f9' + '\uf7fa' + '\uf7fb' + '\uf7fc' + '\uf7fd' + '\uf7fe' + '\uf7ff' +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/INSTALLER b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/METADATA b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/METADATA new file mode 100644 index 0000000..9b975f0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/METADATA @@ -0,0 +1,138 @@ +Metadata-Version: 2.1 +Name: pylint +Version: 2.2.2 +Summary: python code static checker +Home-page: https://github.com/PyCQA/pylint +Author: Python Code Quality Authority +Author-email: code-quality@python.org +License: GPL +Platform: UNKNOWN +Classifier: Development Status :: 6 - Mature +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU General Public License (GPL) +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Debuggers +Classifier: Topic :: Software Development :: Quality Assurance +Classifier: Topic :: Software Development :: Testing +Requires-Python: >=3.4.* +Requires-Dist: astroid (>=2.0.0) +Requires-Dist: isort (>=4.2.5) +Requires-Dist: mccabe +Requires-Dist: colorama; sys_platform=="win32" + + +README for Pylint - http://pylint.pycqa.org/ +============================================ + +.. image:: https://travis-ci.org/PyCQA/pylint.svg?branch=master + :target: https://travis-ci.org/PyCQA/pylint + +.. image:: https://ci.appveyor.com/api/projects/status/rbvwhakyj1y09atb/branch/master?svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/PCManticore/pylint + +.. image:: https://coveralls.io/repos/github/PyCQA/pylint/badge.svg?branch=master + :target: https://coveralls.io/github/PyCQA/pylint?branch=master + + +.. image:: https://img.shields.io/pypi/v/pylint.svg + :alt: Pypi Package version + :target: https://pypi.python.org/pypi/pylint + +.. image:: https://readthedocs.org/projects/pylint/badge/?version=latest + :target: http://pylint.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/ambv/black + +====== +Pylint +====== + +**It's not just a linter that annoys you!** + +Pylint is a Python static code analysis tool which looks for programming errors, +helps enforcing a coding standard, sniffs for code smells and offers simple refactoring +suggestions. + +It's highly configurable, having special pragmas to control its errors and warnings +from within your code, as well as from an extensive configuration file. +It is also possible to write your own plugins for adding your own checks or for +extending pylint in one way or another. + +It's a free software distributed under the GNU General Public Licence. + +Development is hosted on GitHub: https://github.com/PyCQA/pylint/ + +You can use the code-quality@python.org mailing list to discuss about +Pylint. Subscribe at https://mail.python.org/mailman/listinfo/code-quality/ +or read the archives at https://mail.python.org/pipermail/code-quality/ + +Pull requests are amazing and most welcome. + +Install +------- + +Pylint can be simply installed by running:: + + pip install pylint + +If you are using Python 3.6+, upgrade to get full support for your version:: + + pip install pylint --upgrade + +If you want to install from a source distribution, extract the tarball and run +the following command :: + + python setup.py install + + +Do make sure to do the same for astroid, which is used internally by pylint. + +For debian and rpm packages, use your usual tools according to your Linux distribution. + +More information about installation and available distribution format +can be found here_. + +Documentation +------------- + +The documentation lives at http://pylint.pycqa.org/. + +Pylint is shipped with following additional commands: + +* pyreverse: an UML diagram generator +* symilar: an independent similarities checker +* epylint: Emacs and Flymake compatible Pylint + + +Testing +------- + +We use tox_ for running the test suite. You should be able to install it with:: + + pip install tox pytest + + +To run the test suite for a particular Python version, you can do:: + + tox -e py27 + + +For more detailed information, check the documentation. + +.. _here: http://pylint.pycqa.org/en/latest/user_guide/installation.html +.. _tox: https://tox.readthedocs.io/en/latest/ + + diff --git a/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/RECORD b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/RECORD new file mode 100644 index 0000000..82a97d3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/RECORD @@ -0,0 +1,1582 @@ +pylint/__init__.py,sha256=VBfM8gDZV9q3rWepC7NXThf95WbLIxUZljVHC7_4pGM,999 +pylint/__main__.py,sha256=7sVKdDj6YJsi1eyng7GWrmba1Y0pjIBIy6fObfrt5CM,207 +pylint/__pkginfo__.py,sha256=i8N1MolEohr4pRVhBgY2pK-9Lim30YNFJ2kMDb4X-WU,3526 +pylint/config.py,sha256=MiIpykXiCK3u2tHa-o2B1R65VzGYbjeh3TZKshnugAo,33162 +pylint/epylint.py,sha256=4AhtiXa7OxXGpNShAJ8UY15vf6PVIFvFHEcf-QRUk1U,6861 +pylint/exceptions.py,sha256=iJUo0ry6Fgm5-pzptfgMWCTCsFIemWcGlp0e9f3TweY,922 +pylint/graph.py,sha256=TvMnyQUdZbGUmS0_lLuWFbPHncPImEQIgZKcehq4p5M,6578 +pylint/interfaces.py,sha256=_DndrjiOJTix3PR4tfJAfMZFPZ69IOBsbZMBzs-yX4k,3176 +pylint/lint.py,sha256=v4I_8h3vTzTLySIE-jtmbxgPG5_beR1q1iQkQf7oWRI,65216 +pylint/testutils.py,sha256=BI0M7xE7NxmgTElzgUFJZDVT9gGoWHfyEhEzcPjRPw0,9850 +pylint/utils.py,sha256=hrercZVLu4GT-BQO56_X8an4ArrSDsAQNGyVF77wndk,55165 +pylint/checkers/__init__.py,sha256=MYRmfLZdK-87zvVwENwG_GYZbUmnLA105SBzCkmMX2w,3995 +pylint/checkers/async.py,sha256=a_usjhSXMFg8ZiDwBetDZtRwfRivejgliLheuKZoOHA,3103 +pylint/checkers/base.py,sha256=zolBN7r3x_24lbWuGNuQ1HzcFR_LFCFInwV2lziyTko,84803 +pylint/checkers/classes.py,sha256=VwcSgqBD9xG-TJGQ2EvSKh_9rQiYU7ycJ3leu6Mqmf4,65724 +pylint/checkers/design_analysis.py,sha256=bDHcN743IUheWYJJpG9weT46U8nxgGItCfDUMwQvEIU,17411 +pylint/checkers/exceptions.py,sha256=dz1bFDySwIyZ92B6KDKf_2oXqu3BK__35E9aBN9vez0,20184 +pylint/checkers/format.py,sha256=UTYReqgNXfMusGab9qVKoKEboYSBN1JTicIS4zHDQw4,48651 +pylint/checkers/imports.py,sha256=1lapZQLVazpWiXvPuzlqRT8Hwjq1tpaPtcFb3rfGHCQ,35984 +pylint/checkers/logging.py,sha256=Vl5fwCTBj9M1n9kV45fagOU6KJFM91-4znPVNToOFt8,14130 +pylint/checkers/misc.py,sha256=GAREJO7DeFt7i7IsHV7MHX5ot4Lem1u_VFoodB4wDY0,7117 +pylint/checkers/newstyle.py,sha256=qIImCKY7tD2vOHaKnNdGR4zPpBPo71abZTKarjCNIgo,5163 +pylint/checkers/python3.py,sha256=aSP0cFct4jDvTW3qL9S5E7VYoQIzReCxTc4FeQTF4B4,51769 +pylint/checkers/raw_metrics.py,sha256=F4frhx3TesEItjEMElcz8j5gYJ1SrbLgbDNv7oNyuYk,4057 +pylint/checkers/refactoring.py,sha256=nmoGw6aGq16uenUkpdOhVppbNJmJ7KOLr0qUtgR5nbo,56581 +pylint/checkers/similar.py,sha256=CvPhcMo3GF8E4ySW8UPqSpP9yd6CfiDHMAQ575mzhvs,15042 +pylint/checkers/spelling.py,sha256=CvCZAWwoKCekr4IB9ckRsyP1as27AxDnQ0OGGzGAN9U,13225 +pylint/checkers/stdlib.py,sha256=XbHiNpJRYarkxAIXGMPxbRcDMDY3SL1bgxuEAowe8HU,16541 +pylint/checkers/strings.py,sha256=eMe3ztWTi-Yws2RfOoS4HElnLFv8t5QBSfkOy1g8Q_8,30642 +pylint/checkers/typecheck.py,sha256=vh2yuEn9s-xEZRfDphHIXOX_q7ESAuYaZPcm1AFcc58,61681 +pylint/checkers/utils.py,sha256=wkTYo1AFI7-y9SOBvaTCUJK-O2FEcmriog8iuBdK6A8,40388 +pylint/checkers/variables.py,sha256=NJIHZ2Td1qTYLEFSXq8-S51d78JDJz5ZxiSuPF96IHk,71400 +pylint/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/extensions/_check_docs_utils.py,sha256=Y_5_hTpc9an53UYUr32X3I1FYhfmnN1zFpmScYyFSqw,22668 +pylint/extensions/bad_builtin.py,sha256=xmwDQ4AcXL_z3MhGLkgOPaTaZzvizU8AblKfSDw1r-0,2434 +pylint/extensions/check_docs.py,sha256=PUXI8A1742UTxcoBAQ-dE88e_lFXlUYxfmkIS1z5eq8,784 +pylint/extensions/check_elif.py,sha256=Lgpg7ALxJ_n3QQ6xOLoY_BlupWC3c-Yszkbr9ZSmt5g,2411 +pylint/extensions/comparetozero.py,sha256=5giILRcZSqC68XlBKgD2doCfT0NVbYHd8364JVN1kvI,2391 +pylint/extensions/docparams.py,sha256=GW3iBde4_UZ-fzVFgcCevd5sBtKh_4mCRlMakBpvgG0,19077 +pylint/extensions/docstyle.py,sha256=gQ4KylavmHYF4W16SbXDx_Ih8G2QQRwLpd1QiRtLX8U,2904 +pylint/extensions/emptystring.py,sha256=TnuRvNI2K1oIkp605bJQUgjYUoJ9KfzLSPrxVdSXxfI,2474 +pylint/extensions/mccabe.py,sha256=F4tIYQgx6zzJhzZyu69O9Mxq6IvXXfRgJ21Qok_sxOg,6202 +pylint/extensions/overlapping_exceptions.py,sha256=Rtu-Tw-1DXyipQR6f_D_UGAGvI5-NMAJ3xRhGp9mmeU,3310 +pylint/extensions/redefined_variable_type.py,sha256=VZNdC3F3F1zn3nFiaXYCA9OKCK8U7V4aAt-FqEXIEZE,4207 +pylint/pyreverse/__init__.py,sha256=KFNrEafFXBWBBklF5nyH6tBs-HlNOT1AO2J89KOfMP0,203 +pylint/pyreverse/diadefslib.py,sha256=tfMQwPvrQLJCTgkxQNK4gRKqHCO9YGlV38IzpZp7hNw,8628 +pylint/pyreverse/diagrams.py,sha256=rC8br3YmeloZFwWlfSUJcBBKxFx3VcbaQm5MhlFVn_c,8961 +pylint/pyreverse/inspector.py,sha256=hfCdfHvn_6gz9lLO-ywJtbYyKDbN5ew33c0xOkcxWTQ,12352 +pylint/pyreverse/main.py,sha256=gEgNulvAoVqyX4GIpbVDYe-iprMGMcEzjNEt4Aco0ZI,6650 +pylint/pyreverse/utils.py,sha256=zMU0JA8JPuCWqGu1VHULwAirSo9eGpMkxwxUk2wcd8g,6238 +pylint/pyreverse/vcgutils.py,sha256=-aMHC9LhVsE4kmHrSyC_qowfxpKKLnBHj3Q84vFOwlc,6408 +pylint/pyreverse/writer.py,sha256=F5QRlzv-bvuv3aG5iR9z7ZUUMK23R3tWYOcX17wV-4A,7702 +pylint/reporters/__init__.py,sha256=Pshmok6hVrAe9BTvbnhI_7K0IWqPZ1VB5KATn-KbmWg,3841 +pylint/reporters/json.py,sha256=Qy7PT-qadtWRn-AIeUEscUk7iWvRNyL5pcdR_ABbWlI,1913 +pylint/reporters/text.py,sha256=fbxm5JiaAWDOJqCKaXmlLokxhxJ8oR1Ra6O6D1xeQMk,7946 +pylint/reporters/ureports/__init__.py,sha256=FGm2o7X9KTeVK_71Hme1iflOJC53rP3Nv_G_IBBAOTg,3157 +pylint/reporters/ureports/nodes.py,sha256=RJj-HfDAyGg7TbplWMOODsqM96q_pc0PfCx2v4PZ3no,5196 +pylint/reporters/ureports/text_writer.py,sha256=jTUuIgyV1XYTIsNHyRymXsCx-yWpT6zYVWEJdxMvZgA,3304 +pylint/test/conftest.py,sha256=oJlB__EZBKXqrf7ziXxGH55OvTJoR_923wg1XKRP5JY,1040 +pylint/test/test_func.py,sha256=2hhcXTMHPxp4tyn-wkwxJpNCDzk-9zMXoKVON3rNkhc,4781 +pylint/test/test_functional.py,sha256=UtzXxXMgPwiARUN7lgfNh11hT3lqb_UZly1J-D0I958,12499 +pylint/test/test_import_graph.py,sha256=HKHZnHpTmJLDiAicR_obclUTbSNZMKAaOoGxmiCBXNc,2348 +pylint/test/test_regr.py,sha256=m-DV9o6WPQ5SZLSjtBvXEex0jGAz87mewWLpYXb3O1U,4106 +pylint/test/test_self.py,sha256=NQeWst3FeTR5yqGvVX1FaiTkTZWXvgGVKUvrhjK16-k,20431 +pylint/test/unittest_checker_base.py,sha256=cXC1iunsE1-aBaIq6YjsAtFRcc0LpSDfFrIFheR8F88,17514 +pylint/test/unittest_checker_classes.py,sha256=HHlnFIUiFNLiLJgbv9IUMkywG521MhWV6TQxrG1VaX4,3805 +pylint/test/unittest_checker_exceptions.py,sha256=Jy8zJVoJBpdUGzX4TZTgTkpKbCj9hUUaxJrqXs9v0BE,1795 +pylint/test/unittest_checker_format.py,sha256=O3_5Gk7Bd7KwyrLfr9ARvZVQvduWBV9qH68nVNdpyqQ,18297 +pylint/test/unittest_checker_imports.py,sha256=oswLH7bpJf2hWLZJG2pugmetXcI72RW5KsmUKLmJ1g4,4333 +pylint/test/unittest_checker_logging.py,sha256=59987ssp7YZGygoHiaCGU8_MO4jiHJtIdEL-3zMMzfQ,2612 +pylint/test/unittest_checker_misc.py,sha256=crA3brP7cOI0ZOlkZI7yW7HuIdOV-kHuWXgcoVQfnoc,3147 +pylint/test/unittest_checker_python3.py,sha256=51PKPe4rw4ahgSrkxFoXX2MlV5A6b5TInTbHUqBTM94,39603 +pylint/test/unittest_checker_similar.py,sha256=qL4SjM4N73FeNldI9R9nGBg4qKlfCicnHb1mJGBpZs0,4713 +pylint/test/unittest_checker_spelling.py,sha256=GFIqynItsvd1GdWIuNzG6NHi-ABv-Rga3GbyVA-5iSQ,10866 +pylint/test/unittest_checker_stdlib.py,sha256=er5khbs6gORipD5nKvkuB2-hYo3UsSHRYi7aOKxNkIM,3749 +pylint/test/unittest_checker_strings.py,sha256=zA9eoy3wJ_GjhCAZKHPBDcycyLNNnxod5qfAiVeRYf8,2494 +pylint/test/unittest_checker_typecheck.py,sha256=V5QB7fw4eGjPjkBqgdOUOU8JiWQZi3Qjz81jfWwivis,9705 +pylint/test/unittest_checker_variables.py,sha256=sKLeqARbhq7rGUHibiQSxL1ReC9MBcoG7NPUXoc5tug,8722 +pylint/test/unittest_checkers_utils.py,sha256=7pdKgeuq14cto52BIZnsKIxAgHJGPacTxP4PbOvZcD8,4690 +pylint/test/unittest_config.py,sha256=nqEshlLuTvuLDaIl0xTIaDILIL_tEdRiTEQqyac176k,2016 +pylint/test/unittest_lint.py,sha256=_wvcQPSrOnB6m_SFbzAk0ptxPSFuXzVeOv-YIOyhnw4,27621 +pylint/test/unittest_pyreverse_diadefs.py,sha256=N-ogV0Jz7gcl2U2XmOJ0gHMFv0-6qrYBghzb9v74lT0,6341 +pylint/test/unittest_pyreverse_inspector.py,sha256=i68Ie7PljDBX7KWRoAAXypyd0333uWGbJ0N3gVR5yJ0,3836 +pylint/test/unittest_pyreverse_writer.py,sha256=97gm-Zq4AJkIcsV5_jsfE_ewrFb2uMIdg57JtS6n-uM,3991 +pylint/test/unittest_reporters_json.py,sha256=_hCgC_003mgLLdnuk0VrKzqCDnCdMj2lbf5Y89XgngQ,1698 +pylint/test/unittest_reporting.py,sha256=33U5_e93UVn_kCc07Qe8wT3UE8_7ysc_pgGkWmeWG_E,2509 +pylint/test/unittest_utils.py,sha256=Yb2-vQS41XwSaimgVR2Xe3ZIUk-tdLrWpf4htGv3RKk,13873 +pylint/test/acceptance/test_stdlib.py,sha256=_XXKEoiuDSOPmjv9ZnuTQzjAPubEe0zaHABmTeXP3m4,1317 +pylint/test/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/data/ascript,sha256=V-B0-XbNNKHljqJali61u2ov28upP97CM5vRB9jW62w,194 +pylint/test/data/classes_No_Name.dot,sha256=kQrr6UnifFv819xXsSaY84n056oDhL2H2fVThhfMmrI,680 +pylint/test/data/clientmodule_test.py,sha256=4dneg_cyysIcND6Jq5xwLZpbNl_o5NgMXTw5yMi5KnY,778 +pylint/test/data/packages_No_Name.dot,sha256=IRsH6jUfW6uxZPl6urhpecZrrzs2bhynokxa0DyGMXM,244 +pylint/test/data/suppliermodule_test.py,sha256=lQpvJoz7d6siHbXWylcLekvBFgdJZkcHL-N4ZsA1Bzw,198 +pylint/test/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/extensions/test_bad_builtin.py,sha256=UevFK5-vWjswkT0R6C-AjWLn6qFqNenPEgrFhaY9M2U,1269 +pylint/test/extensions/test_check_docs.py,sha256=OKvgeoJVNxFjQDK1rBQOuUFlQBPku1rqMorrdahYz3o,65618 +pylint/test/extensions/test_check_docs_utils.py,sha256=7ai2XmNQSkxDJSUSIQikMiOzfV4S3cZuOn-KcL11ItQ,2839 +pylint/test/extensions/test_check_mccabe.py,sha256=Ie0TYPBbgQrfJETFO1GpJpMdnKi4S3IKW470DqdzTxI,2014 +pylint/test/extensions/test_check_raise_docs.py,sha256=hRVdaTJ1GMeeCc9rFz9Ob9UkIx_tv547WzKuefKCy44,15610 +pylint/test/extensions/test_check_return_docs.py,sha256=Y-IEqk_J24nNG0TnJ38ek__J0c7zXlr3ehWqiVN_TxY,18201 +pylint/test/extensions/test_check_yields_docs.py,sha256=Qb3I9_Rd7qqWdGkwNt78qkdnGsCTRN6Q5IfEvhIednE,12270 +pylint/test/extensions/test_comparetozero.py,sha256=werUuAngQzcmWID2pJ2p5hqNGem3WM347vojVO-40A4,1927 +pylint/test/extensions/test_docstyle.py,sha256=8aW0Y8Iup9xRB0TqtWD-LpPrnBB-RkKbgGqnfyUIcAA,1773 +pylint/test/extensions/test_elseif_used.py,sha256=FuNbFfD6osWvMKroKdEm1QlKkP7ya5HWVNPUqUSWCuw,1031 +pylint/test/extensions/test_emptystring.py,sha256=vCSOe25uRbZvBUWNumU9LGiZb4IVYjmdGaSy_3e8Oag,1274 +pylint/test/extensions/test_overlapping_exceptions.py,sha256=TOr7u4DEfIlXPMtR_YPZFJ5OkUj5787c4ySDeUzla8Q,2764 +pylint/test/extensions/test_redefined.py,sha256=z2dgXE573ryUEBzf2ItieoiKqjioBfqeLttqr2HsBdc,1613 +pylint/test/extensions/data/bad_builtin.py,sha256=pOua_9PZoQoRA4SiS5js5NGIqkbCvD5CHKZnCpQgp5A,127 +pylint/test/extensions/data/compare_to_zero.py,sha256=yY3drJbme3yYtaCbN6RjcTb24EQrMK-OxqxA_wXl3aI,442 +pylint/test/extensions/data/docstring.py,sha256=UokV_HdPfqCMtDtLmQUlEn3Xo7ali5vw3mfPD_zIifA,811 +pylint/test/extensions/data/elif.py,sha256=jehtuA0d87q0XFVqHU5eUiYvYX_p90a4HarD99Xcj9I,601 +pylint/test/extensions/data/empty_string_comparison.py,sha256=pHfzx_DBVNftVKfKWVKah5eKWXguLY7Lv8E9TWtclwE,282 +pylint/test/extensions/data/mccabe.py,sha256=0h3xJdh_wIqqLqhYjWQtcrSN7XlVss8BnwLOFfiiKrw,3660 +pylint/test/extensions/data/overlapping_exceptions.py,sha256=MyY1gqtwWpv0Ndw8EuA0HnxXWiN7ZOEHAbHhD7JQyu8,844 +pylint/test/extensions/data/overlapping_exceptions_py33.py,sha256=Gh0Nn_He6WMpo38GUtr33tBcPRZVY8BFRl1r92GKUGM,291 +pylint/test/extensions/data/redefined.py,sha256=76InxRcCUk5LTbomtFDC5w_3R9bGLsJ3wSNRRXTrgVQ,1915 +pylint/test/functional/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/abstract_abc_methods.py,sha256=6J7uxWz_8fANqdHeunyxF-OPfECssZIStbzSYADpJkk,475 +pylint/test/functional/abstract_class_instantiated_in_class.py,sha256=C7q8HJmgoN3ltaHTQp6QDgIKYW6VWEhnI_-uyUXFzTw,374 +pylint/test/functional/abstract_class_instantiated_py2.py,sha256=XzALzd8vD5-EhiDSLmwlR6QjlIhEvnKJ79Hmo-tTjCk,1781 +pylint/test/functional/abstract_class_instantiated_py2.rc,sha256=jjoLR3xCdjLyaDGltj15egZfyV0idyvx95Z_ud8WR1s,27 +pylint/test/functional/abstract_class_instantiated_py2.txt,sha256=1OWqOoWY0FTjcg1VyVRSi5-LmmFQp699Dxl5oy2ARmU,409 +pylint/test/functional/abstract_class_instantiated_py3.py,sha256=pTe5r8_FXv3HwlzcVBHfQSye2G1liqGxBvOLe1UzaCc,2844 +pylint/test/functional/abstract_class_instantiated_py3.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/abstract_class_instantiated_py3.txt,sha256=d19Jii0gcWEIBKTwphlF-hhFG7_MeOq2H48_exDGaoI,526 +pylint/test/functional/abstract_class_instantiated_py34.py,sha256=tf86H38x_Iy0Kb__xbnhffEJH0_cJEYCa-chgvIBHMo,379 +pylint/test/functional/abstract_class_instantiated_py34.rc,sha256=Z2YAj5GU5yUV9cm6EGiDE6WoMMP5d8WX-8JzLaudC8Y,27 +pylint/test/functional/abstract_class_instantiated_py34.txt,sha256=BsXosIG9BumSZ-zwLC-g4ZDv3bcpkrwP5cqfB5czp7Y,98 +pylint/test/functional/abstract_method_py2.py,sha256=6PSn3nwLrMNtJvnslSRy3xVDXZQ5o3H81DUxiIxIu9U,2016 +pylint/test/functional/abstract_method_py2.rc,sha256=jjoLR3xCdjLyaDGltj15egZfyV0idyvx95Z_ud8WR1s,27 +pylint/test/functional/abstract_method_py2.txt,sha256=nExVDydjRVCb3EzmBqXFJ05sNhQ6_uRFBiZGD1cF2FI,1692 +pylint/test/functional/abstract_method_py3.py,sha256=p2aYjct3NYUBDEPef34sBs4vGcyHRgOGvHPhbtxvWFQ,2006 +pylint/test/functional/abstract_method_py3.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/abstract_method_py3.txt,sha256=4hV-OyVDJMcoGNgJ813vTMKajkMavTqa-vmHcNYxZqo,1692 +pylint/test/functional/access_member_before_definition.py,sha256=BTNa1vQRO_wywc9NaraR1uzxYfMJHlqvy9GASVB13FY,1059 +pylint/test/functional/access_member_before_definition.txt,sha256=FdPe_Nb9JA-3MTcC2-Hs5yFYLavlyB_13xXx9-aP-NA,205 +pylint/test/functional/access_to__name__.py,sha256=IE5GD5IUynInhHmx8WHYDjop1iJY3LsYyK4uuCI29Lw,626 +pylint/test/functional/access_to__name__.txt,sha256=qannC3noWVGQG8XOyzzPs3lfUfWM2OKti5d1mvrCF4Y,170 +pylint/test/functional/access_to_protected_members.py,sha256=j47gxk-dZ9VPnLHqhSFsy3_GtGC0vWoKgFlWLySfgkI,1596 +pylint/test/functional/access_to_protected_members.txt,sha256=rbTJWhHRAZlFaiYXLkDHWslPvRPUQe5wGkd8kyeRKAA,515 +pylint/test/functional/anomalous_unicode_escape_py2.py,sha256=uP8a-OWIBOqJP5MpjmfxuvqGzQKryWjBVAQepgdtmOQ,699 +pylint/test/functional/anomalous_unicode_escape_py2.rc,sha256=gi7nbtc02unkgoYGeEiZqiiU0-YXF4paT9aFvrYS1uI,28 +pylint/test/functional/anomalous_unicode_escape_py2.txt,sha256=N6R3Q6bdvncQlsJ55EJ9Dc61uKOl9P78_2ZT09I1Low,414 +pylint/test/functional/anomalous_unicode_escape_py3.py,sha256=fPSStaNzCrS0a-dkcZL8elhKEx_KnM6f4zOewu4UmbU,672 +pylint/test/functional/anomalous_unicode_escape_py3.rc,sha256=202YR06iDdSKKr77PzmwvnZQFMSJgHMbe6MIK2FcSvI,28 +pylint/test/functional/anomalous_unicode_escape_py3.txt,sha256=NfjWLdNoXYjZJFUaW6rdjFlDM76mXixm4ieNf7JPRBE,413 +pylint/test/functional/arguments.py,sha256=clkEB6pGjBjF5s2rYklpE8ArCvkhyiBL-tfRa7ofskE,5804 +pylint/test/functional/arguments.txt,sha256=ZeLCUA-ZHeyo7dSmFQSD9squB7De8q-L7Zbrocy0Vp8,3441 +pylint/test/functional/arguments_differ.py,sha256=EhCqv8kjE5f2cX0qeV-XV3QqFuW79BmwIO8phKutvao,3836 +pylint/test/functional/arguments_differ.txt,sha256=cuKRG1W_P6lcKiz6Cnsmc0Lr8_qF0xRO2XasqV7Xa6E,720 +pylint/test/functional/arguments_differ_py3.py,sha256=uypIxl1oMrc_Prmk0xEhObP0CqwN8qcKWf9ain5bsSA,1128 +pylint/test/functional/arguments_differ_py3.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/arguments_differ_py3.txt,sha256=zvNaHuf5KZI8d4e6OeRJ5eoz358dV-0LK7tuye_FzwU,425 +pylint/test/functional/assert_on_tuple.py,sha256=eOb0oxEI0Z5UfTgTqBEl5rmMIHU3L0VqlPeXmSVyxq4,355 +pylint/test/functional/assert_on_tuple.txt,sha256=xaea2FSKWuZ9Ho7wvM7Sa0pUkB4twYVnTmoZYNhUHjY,147 +pylint/test/functional/assigning_non_slot.py,sha256=OpSIJTdczDR2fV_K41-AMXIy3B9E0QVvWXUolUW6krg,3472 +pylint/test/functional/assigning_non_slot.txt,sha256=4wno64h29IzO0WWO4r3sxK8_tgsgKIKN1EabTd3vm_k,539 +pylint/test/functional/assignment_from_no_return.py,sha256=N2jJvIP_SwND0kJXdqv26IyaKBZhA-9bQ9IKdfHxjTw,637 +pylint/test/functional/assignment_from_no_return.txt,sha256=k22AGPn_v_Tzj3u3ptpdy7sLgnBeDrP_TPyBW-Ksi6E,222 +pylint/test/functional/assignment_from_no_return_py3.py,sha256=APCsClSAScwM4gggtVSTIOKryo-ZZIUFEDLH0STbjGc,495 +pylint/test/functional/assignment_from_no_return_py3.rc,sha256=9iH-Tuv_IYxXHEULly62C9cPpKKik1cET3_WTTkjt2U,27 +pylint/test/functional/assignment_from_no_return_py3.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/async_functions.py,sha256=cov1wlmk-s1Pb6fgJ6RJ-QVxq4WRfTvlwm3e5DlR73U,1318 +pylint/test/functional/async_functions.rc,sha256=dP_Zfqp4xaJCM9jhYtOqNIbxRfpn2sV_Sny0wLYzPvM,27 +pylint/test/functional/async_functions.txt,sha256=tBEOG19Q2cUUOcm0lIjJdsUoQL0uJjfJCVR1C6tmhSE,736 +pylint/test/functional/attribute_defined_outside_init.py,sha256=8e--sbU9aMzDpwYMtHYSFHaipXEjvcCoxejDK1Rh6f4,1080 +pylint/test/functional/attribute_defined_outside_init.txt,sha256=fLkRt-6moI6wZDeN3RcXwjUElkQFpJHGhMnfiBkcUt0,161 +pylint/test/functional/bad_continuation.py,sha256=XEDAw-Bq3u2BKxdouNP-80tJO6Dq9kf9uFRoUAC8obY,4472 +pylint/test/functional/bad_continuation.txt,sha256=iLXrBARbU5TGKIQFWkb-enSL1Vg2V_Ip1uW83d-avVw,2424 +pylint/test/functional/bad_continuation_py36.py,sha256=UFKI1u1cBbiiN3Tsilikkr0nHiZ37_sZa-GVXMg3n9E,270 +pylint/test/functional/bad_continuation_py36.rc,sha256=9iH-Tuv_IYxXHEULly62C9cPpKKik1cET3_WTTkjt2U,27 +pylint/test/functional/bad_continuation_tabs.py,sha256=LTj1s0gGTweF1cBTZMg16K5hsHqZ6VisSXUKzo35VJQ,1176 +pylint/test/functional/bad_continuation_tabs.rc,sha256=chKJ0mPdr7kTh2m6I5UzlmnMUv2bSJdYlFvIinO-uu8,49 +pylint/test/functional/bad_continuation_tabs.txt,sha256=WB3DOgHDXzQTc5sptpEo6d2NOQzYihQ37ZjZhxzunOE,268 +pylint/test/functional/bad_except_order.py,sha256=8KrC5G5pXEbCaVTbMvLnZWyCMlhYig_c1b4vXK8-mgg,781 +pylint/test/functional/bad_except_order.txt,sha256=-XrjSscajtaU6s6Ct_0Ha0n6oQg731JurLUbUpkptYA,475 +pylint/test/functional/bad_exception_context.py,sha256=V5XSeD7w71T5TSRLuQdb9EntGa2Roboi0nR3U-yheXA,765 +pylint/test/functional/bad_exception_context.rc,sha256=202YR06iDdSKKr77PzmwvnZQFMSJgHMbe6MIK2FcSvI,28 +pylint/test/functional/bad_exception_context.txt,sha256=9diWbKBjoTLMKjVO7BxjXf7IAeYZ_vXRPSwR5fCI4BY,304 +pylint/test/functional/bad_indentation.py,sha256=GAmTEWRIoybNH_pPuHW7-nOd9aBgByONSSK6-xSk1r4,380 +pylint/test/functional/bad_indentation.txt,sha256=9QM-Fz4afVRj-sQ6LAvX9hIzyUmLe0WDmv7d_31NhGE,127 +pylint/test/functional/bad_inline_option.py,sha256=MaBtnDtvC8KPfcSLkfYsn8Ed2h6RClzC2b8jDHIXhZc,148 +pylint/test/functional/bad_inline_option.rc,sha256=FDt41OCgpUX9neNWFAe0XF3CsVi2gn3pJ6y7tnRdO2k,28 +pylint/test/functional/bad_inline_option.txt,sha256=8FpKkk7cym-oUNlfPyOCm3lxIV-4FLD6TRwjtaGpNnM,68 +pylint/test/functional/bad_open_mode.py,sha256=E0EUHfevxXro6TYZ4lRGy4wq8gBFueUW4sBTqplhz1Y,1172 +pylint/test/functional/bad_open_mode.rc,sha256=U7ukn_RAIkBnyHlMWa3YMPeqL3lBe8OdmO8cuyXPx0M,30 +pylint/test/functional/bad_open_mode.txt,sha256=HQc-IKcInf-iQaX3F07n2dpenrD9qiscUkAVeHDasL4,797 +pylint/test/functional/bad_open_mode_py3.py,sha256=F8fSaWRKRnwSI0r8tfEKyLDr32yG-czYexF0WFR0vzc,563 +pylint/test/functional/bad_open_mode_py3.rc,sha256=v5euPd8y704gPAG9Jjf08O8kqSMZRbZ32olFpt2obDc,57 +pylint/test/functional/bad_open_mode_py3.txt,sha256=I8bf5XmbaouZnXYfd8AoAukaUZNmTbiKl2yYZM-IuHQ,350 +pylint/test/functional/bad_reversed_sequence.py,sha256=ynnBD6cuzmbkqdUMlrDkSMYN3XesNzZ1dA_QWhSnb9I,2160 +pylint/test/functional/bad_reversed_sequence.txt,sha256=IlGDXWWSc-l3jOmfN-qo1BeHT3BTA83CoEImmuI2TTw,632 +pylint/test/functional/bad_staticmethod_argument.py,sha256=3PMRzGU0FvH1mXToM8YdLhF4CuIHtTY3ssUQB14r9js,357 +pylint/test/functional/bad_staticmethod_argument.txt,sha256=dVn4nMETxlYuqy0yw2tBhPE7kGLWYwjE3iA5eSw1F3c,169 +pylint/test/functional/bad_thread_instantiation.py,sha256=yvfk8xLDZaML9ZcMpOhKmp8YI8mk_PmR8qlo6e5nals,263 +pylint/test/functional/bad_thread_instantiation.txt,sha256=Mw5AEOwbUEWA7dqEGfgEn2ifcbykcsV_RLZsMmSt0MA,142 +pylint/test/functional/bad_whitespace.py,sha256=DNLk7XGMDSDmYDE-IMB4IJNElfloygfyJd8NywQf6bc,246 +pylint/test/functional/bad_whitespace.txt,sha256=kbEyEW9JlYhU74F6hZRUYzZuDJSG-y-N4Yk7vBKEIVI,565 +pylint/test/functional/bare_except.py,sha256=fWx5d4lcXNR04jW7Daf-dUXnM--AfTQwujgAVvgBaEM,101 +pylint/test/functional/bare_except.txt,sha256=Bw-mogsFC4MQXlM6swSaUQDWD8p_F6XdwkQQkRLDiH4,45 +pylint/test/functional/blacklisted_name.py,sha256=Fp4Oo98Hi2O7vLE73em5xoZ05OXzyjqCqYf2-Y63g58,78 +pylint/test/functional/blacklisted_name.txt,sha256=KTvdkbyZSGQNEblwYWvApkme-C40ZxTX9iE4dnwSH7o,47 +pylint/test/functional/boolean_datetime.py,sha256=OBquMgdkQBfMFpbxH0O1A-Tb8xQIcMEDqHD1X8ZMsZU,1123 +pylint/test/functional/boolean_datetime.rc,sha256=jIh3Yzcp9RE1nms4mhvBMlflAVAHHWHr2nExXzXvZ4E,27 +pylint/test/functional/boolean_datetime.txt,sha256=gI1KfewCkNEQ8PPzobG2bX9U9jQTRQj_yt7GiLEmoBY,503 +pylint/test/functional/broad_except.py,sha256=QmU-jxwLme-yQXXvac6LnA-04e3xqZNrqPXFhPN7UoU,173 +pylint/test/functional/broad_except.txt,sha256=pAuy5tTwzhJ0N5otdXzsHSJiiruOJBCguDUeRb-kaVA,56 +pylint/test/functional/bugfix_local_scope_metaclass_1177.py,sha256=o-KSnD5Aez-ZuPrIXIxgnDoHfHnTEBKg1I0XdOoJnNk,891 +pylint/test/functional/bugfix_local_scope_metaclass_1177.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/cellvar_escaping_loop.py,sha256=igFaSsAkdS6X6QtJNr9o1ftUWvSFktoV-0R7gscypi0,2472 +pylint/test/functional/cellvar_escaping_loop.txt,sha256=Z_EVuGjR2HNgh_zfYJqR4nb3iYzU91CSSCVwIHEypGw,437 +pylint/test/functional/class_members_py27.py,sha256=SpUPc2rnLPTVof3mc3sAzifvXLhAzpW3OL5JxQpqv7k,1882 +pylint/test/functional/class_members_py27.rc,sha256=qRj-wLosrKU8gZhRSrSn218Et_3XaommluMlOG7Hiv8,42 +pylint/test/functional/class_members_py27.txt,sha256=GOsRYjmurOgPbsXIewtOx0m8DlMQTzRy-M04JqA3nbA,575 +pylint/test/functional/class_members_py30.py,sha256=3rD2TQlO8qFQU1D-tx0rraco4o6HeUkwZjEKDQi-G54,1806 +pylint/test/functional/class_members_py30.rc,sha256=202YR06iDdSKKr77PzmwvnZQFMSJgHMbe6MIK2FcSvI,28 +pylint/test/functional/class_members_py30.txt,sha256=8YwDfYJv8P2oMxDeJ84qEtc7sp-zbcSf-v_fcwJI_d8,580 +pylint/test/functional/class_scope.py,sha256=EUZ66GS_cPb19AtRfeq6watnx6etG1Bn2NoKh5rMZUY,641 +pylint/test/functional/class_scope.txt,sha256=MeVx5fCuIn_uRq230rD_DaFy-nAP_eGLOFhDouZE4hg,267 +pylint/test/functional/comparison_with_callable.py,sha256=Ig6HYASGT7EJ5Yjqwzuam0l94PA4OOz77FTHNNQ7y90,1204 +pylint/test/functional/comparison_with_callable.txt,sha256=Fn2UjV8H12IALWJWqPZqL-KYhLdG8Q18OmPaCJkqx-0,444 +pylint/test/functional/confidence_filter.py,sha256=YTh8NMQCMk_pkZWVpeuQ42-ZgJzOq1ieOxl3d9OAGmM,436 +pylint/test/functional/confidence_filter.rc,sha256=3_WOSeGa6z5HFwZP37YAjHFwtjOEQeGZfrNKRYdZAmM,129 +pylint/test/functional/confidence_filter.txt,sha256=fBSERb2N-h9QqLmfrE-egKm8inEwcLrt29E2Ey0HOvI,65 +pylint/test/functional/confusing_with_statement.py,sha256=p5LErVFFLMzoSxI0kefz7ae2nRjstbwyBLC0jrOxEDo,644 +pylint/test/functional/confusing_with_statement.txt,sha256=qYvFTxUTDeQLVcdh3oB8ol9inhZVL3Szb-dMEfW-hb0,93 +pylint/test/functional/consider_iterating_dictionary.py,sha256=MaQzC0mH6Vlc-RpVXedtX3KMsJO5iUS0gVsG4MvvRGc,1521 +pylint/test/functional/consider_iterating_dictionary.txt,sha256=yarkbOFKDxP3pNL3jNAgzJokNnHXnwMDTXRhqYSv6dA,1560 +pylint/test/functional/consider_join.py,sha256=c7GIPpc4ZEiODS75rQGfVLeb4JOqPBuqjplLLbtPwWg,3118 +pylint/test/functional/consider_join.txt,sha256=GpVFTW8g8wsWYszNCWFM6jegZIVwCb2zsIsWMRINxTg,1110 +pylint/test/functional/consider_merging_isinstance.py,sha256=-ybkp2CdWsLmpm2zpFdBV8F0BnX2JPzAxkRwR_p069Q,1749 +pylint/test/functional/consider_merging_isinstance.txt,sha256=mhNhQHwPXIWTDTeHCsJXZsSNiE8tsYlob1YYY3DQ20A,841 +pylint/test/functional/consider_swap_variables.py,sha256=2v0UweVl3LrcxIrb0KX_rdqm_TpdLA4SRsZk5pPXun0,438 +pylint/test/functional/consider_swap_variables.txt,sha256=FwA6jZc_YOnb_kS7R6pN82AEy1_jMw_fsnk4s3Zj96s,162 +pylint/test/functional/consider_using_dict_comprehension.py,sha256=UP5mwbRLMJCA-Wz3EtJYhanGvvMXuV0XQz_-eQoWwps,196 +pylint/test/functional/consider_using_dict_comprehension.txt,sha256=G0Wf3aMlS5tAfKMntEbLDDDv8IBZ5kQUzL3RyD6uBRs,78 +pylint/test/functional/consider_using_enumerate.py,sha256=FWtzYL7HMCMwqLSiVaCF_AE5AnbTRtmqNuNkc6pzM64,1932 +pylint/test/functional/consider_using_enumerate.txt,sha256=59FJ2mY4QDQdTMX5Sy3H3rUsdlsImXlBdfC060UsVUs,400 +pylint/test/functional/consider_using_get.py,sha256=R0x2KwRkpruTcjvQLPzH9vSrzD8q_nRQUvaqpl1esWk,2340 +pylint/test/functional/consider_using_get.txt,sha256=B50vLHWq135amvagvsthwYJ0ilhp61KwNj0hZBwhlxA,470 +pylint/test/functional/consider_using_in.py,sha256=j3Fcec5ageygOnVwo0Gd-lJPffC9ZJP5HpNjYWl7VPk,2224 +pylint/test/functional/consider_using_in.txt,sha256=o9KoESU5Z5ZTEeRP_EU2TPtaqNo5PpwcZ4pBOFWSPFM,1200 +pylint/test/functional/consider_using_set_comprehension.py,sha256=mujw_ORIM39qOga5m-5yQ1-yL2e6v8LM0pxFSrLp7rI,171 +pylint/test/functional/consider_using_set_comprehension.txt,sha256=t1wO8Jp_xcOyTT7RUuougtbNfwjNimChD5XjMmeTuOw,70 +pylint/test/functional/continue_in_finally.py,sha256=HqAy9dN9CxY-foM5niy6L2sLda3odieEuX-DDNb0PyM,415 +pylint/test/functional/continue_in_finally.txt,sha256=kVQ2dV8OEyW19IriCsbx_UtmqtI-IoffrdfiREG67jQ,72 +pylint/test/functional/control_pragmas.py,sha256=l2ARGFOiVvG5qHNVjKEr8jX17uinBNblbRlcw85-LyA,584 +pylint/test/functional/control_pragmas.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/crash_missing_module_type.py,sha256=gi-oeMpgQrFafYLpCsSXM1wDm-tNEMmphKlRatu3PDM,497 +pylint/test/functional/crash_missing_module_type.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/ctor_arguments.py,sha256=YSIOuxcgzFhSuKpizM-DsvIPFxLiwg-ei4-av9bXDSo,2764 +pylint/test/functional/ctor_arguments.txt,sha256=rdS7Ybm2gxuVusdgqWdsaGKqwcW0b1waHSvLIuN7_Xg,2101 +pylint/test/functional/dangerous_default_value.py,sha256=yZOy1PCXvbqY1UdVdpFuVhnpSwcpeZMkVCXLZ-rk36g,2198 +pylint/test/functional/dangerous_default_value.rc,sha256=gi7nbtc02unkgoYGeEiZqiiU0-YXF4paT9aFvrYS1uI,28 +pylint/test/functional/dangerous_default_value.txt,sha256=e5Scy_K6G4uW1cZNkygRqgHEU2-J0_9bS0w5es9q9X4,1306 +pylint/test/functional/dangerous_default_value_py30.py,sha256=yZOy1PCXvbqY1UdVdpFuVhnpSwcpeZMkVCXLZ-rk36g,2198 +pylint/test/functional/dangerous_default_value_py30.rc,sha256=202YR06iDdSKKr77PzmwvnZQFMSJgHMbe6MIK2FcSvI,28 +pylint/test/functional/dangerous_default_value_py30.txt,sha256=FMm3bq5mrol5M2PsFPu7HRPuHZdjrW24VafRxo2VCJo,1275 +pylint/test/functional/defined_and_used_on_same_line.py,sha256=siQZ_QWBFsT36bcJrMntxZL48uZOXKQJVISQjiHdlZs,676 +pylint/test/functional/deprecated_lambda.py,sha256=-vIQpqBMwCXYYDINNqOhvZOpxdYNPMa85A7Wx2L9ACQ,723 +pylint/test/functional/deprecated_lambda.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/deprecated_lambda.txt,sha256=KXi2CunFb2UFIPLVg_dzKc7wpnKM_KdfX34d1chfQgY,154 +pylint/test/functional/deprecated_method_getmoduleinfo.py,sha256=xaSGJskX6oHGa9F3lO8r7kA2vvYl5KYRme1_9x45_aU,114 +pylint/test/functional/deprecated_method_getmoduleinfo.rc,sha256=1S1XpElk4zD9VXhX4JIL2ns5Eq37_HCLHRArEiFohqw,42 +pylint/test/functional/deprecated_method_getmoduleinfo.txt,sha256=eBLypquDXFYQxJvfC4s7W1KPU3eXNyBSFnDl5h8UDhU,60 +pylint/test/functional/deprecated_methods_py2.py,sha256=4lS4ktXBxkmM3R3786aClEhwxQs709xpX6O_ATWMwK4,325 +pylint/test/functional/deprecated_methods_py2.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/deprecated_methods_py2.txt,sha256=owD6iyhOQ6JeAVcSJQJaBZEJ_2ON976JSfiZWgoyLGo,221 +pylint/test/functional/deprecated_methods_py3.py,sha256=2i8mt7RGmzhJecqLJ1ro7yr4xOcbpfRXExauaQT0C1Q,1562 +pylint/test/functional/deprecated_methods_py3.rc,sha256=-UtgKsZ7MAhyWMpJ4JTEIAbPt-k7kBfGYqFdShs4Rig,28 +pylint/test/functional/deprecated_methods_py3.txt,sha256=lkiOZ1XEED5pIj6gB6-7PE0sd_8FybT4s9kQsU7YJq4,1028 +pylint/test/functional/deprecated_methods_py36.py,sha256=Y-JCwSkXT-SdFzocGMv4OlIXAwSaKZ5prNpRW003Puw,350 +pylint/test/functional/deprecated_methods_py36.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/deprecated_methods_py36.txt,sha256=KvmxVB-GaWuiI8LyFunm9tt_RtKEJF0puTXd9GWVWsU,118 +pylint/test/functional/deprecated_module_py2.py,sha256=3jSc07sESSLXZ3jx4Prsq_0yFZGCjkI_FmzqccLppP4,296 +pylint/test/functional/deprecated_module_py2.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/deprecated_module_py2.txt,sha256=K3wQiGeCsYKz2TspHzJ-5RCboMIDQtEkEP3__w04X5U,232 +pylint/test/functional/deprecated_module_py3.py,sha256=mXh0SF_p3xuEKl3si1TxDyQEgbVK6IYHtxycWZRTuA0,102 +pylint/test/functional/deprecated_module_py3.rc,sha256=NVvBVz7c60hcHefBkw_ZRpuPshgTpSnWcPorxT94E6o,42 +pylint/test/functional/deprecated_module_py3.txt,sha256=lDLQHaOyERFFWt0cxN2Ts0zM95oJqxXKBB2dveE9G0s,60 +pylint/test/functional/deprecated_module_py36.py,sha256=vevrzSmhCYirIKUm48OkdTLsg5cjTWKJULf5J6HzXyU,131 +pylint/test/functional/deprecated_module_py36.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/deprecated_module_py36.txt,sha256=lDLQHaOyERFFWt0cxN2Ts0zM95oJqxXKBB2dveE9G0s,60 +pylint/test/functional/deprecated_module_py4.py,sha256=MaODOevI2JWWFELz4S5IoJIeJuHLtwuBwWKLpivfTnA,123 +pylint/test/functional/deprecated_module_py4.rc,sha256=7oCLXOu0rEEi1Vl-XzDQ4KG67T4MeCp7lSJTQitlFDs,86 +pylint/test/functional/deprecated_module_py4.txt,sha256=NmMCtRlImCx76ruIKkufcOG0UTEhm-UwIlNdWSqEAKI,124 +pylint/test/functional/deprecated_module_uninstalled.py,sha256=j4uwmsnCiITV3Pl58j2zElSV8dDvS2n_Fgi7IGTmoEc,213 +pylint/test/functional/deprecated_module_uninstalled.rc,sha256=MeYnNVgCznssEhH7mihOF1a-fJamQM4KuaydkH88dbE,49 +pylint/test/functional/deprecated_module_uninstalled.txt,sha256=XP9AxlNtlDbIhfrr2c4Ayux9niEvta4iEj94rF6Sgdk,126 +pylint/test/functional/disable_msg_github_issue_1389.py,sha256=JFgQBssnFg0G0UZqjyEfRtLpQEXQPg06_NoDkESDv5Q,357 +pylint/test/functional/disable_msg_github_issue_1389.rc,sha256=9iH-Tuv_IYxXHEULly62C9cPpKKik1cET3_WTTkjt2U,27 +pylint/test/functional/disable_ungrouped_imports.py,sha256=9uH0jKIRw_3WD8QawmhnEIJnkT9wvp-FArH21ovSwNQ,473 +pylint/test/functional/disable_ungrouped_imports.txt,sha256=D7KuJS0WBWFMjFcwhLAWicPIcbGdORt8VVFU0M8rVzY,128 +pylint/test/functional/disable_wrong_import_order.py,sha256=yMAn7gpBcgNydnt-DvZ58joYdC_5xLlfno7TJ2Qu7xA,463 +pylint/test/functional/disable_wrong_import_order.txt,sha256=Ruu5cjeNDIwHDossKhtyWDQegPoF7Tq54q3x1qno9A8,71 +pylint/test/functional/disable_wrong_import_position.py,sha256=WeZHIe5WvlDBhrZiZ6txAi_3GyiS6M-z2QKnUL677EE,219 +pylint/test/functional/docstrings.py,sha256=f7GG1blh4cJDHdeW38sIOvvjJIoZlYmrjUxq_qeXou0,1633 +pylint/test/functional/docstrings.txt,sha256=u_FjlheoZZLhOfSL0BS5yo0rwEEMkNGGguT36XymWYA,475 +pylint/test/functional/duplicate_argument_name.py,sha256=LIfyR7_Ryy28kzHisVE-VvkULiIgdbYoBJ_uWKLgY-A,537 +pylint/test/functional/duplicate_argument_name.txt,sha256=U5hIA58xnE08zO5hIqQ3C0dMfoZntCoIOjFI2CQE5_Q,649 +pylint/test/functional/duplicate_argument_name_py3.py,sha256=enXJKB5jfaeZPcfg_6GlZBZqQrFy5Z4qZv-OWOLcdOk,184 +pylint/test/functional/duplicate_argument_name_py3.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/duplicate_argument_name_py3.txt,sha256=kbdmQHiXQHMB8Bq7no4xMn9iiTR9HzpXTu03DuRtebc,159 +pylint/test/functional/duplicate_bases.py,sha256=UBEMEMsW5tkYMtf3e5eAx7RBe7i48Z-60q4-2hQKJ10,352 +pylint/test/functional/duplicate_bases.txt,sha256=cDpLaScnGOKvNEjS_G8GmgVVehQf9fsCKT0BbuoFkNQ,67 +pylint/test/functional/duplicate_dict_literal_key.py,sha256=q66I0T114OqgEvE6b_Ezmhb2jwTMdGRkhXQiYFDNbXQ,316 +pylint/test/functional/duplicate_dict_literal_key.txt,sha256=_7lGZH8HROkumeIu1JuPjU1E3CvnnQDPYYud8mjfFbU,149 +pylint/test/functional/duplicate_except.py,sha256=rzYfU3OMynKKRf0IVAhKTGhLoEVtnxxtxz7JyCcjIVw,290 +pylint/test/functional/duplicate_except.txt,sha256=cbR_IZOAioVw2mpRr5MGd_6I2JXWd0scrIIBxKIiysI,77 +pylint/test/functional/duplicate_string_formatting_argument.py,sha256=tZTF6SBvRF9EW4XKn1VsI9_pwC0aYX4ldTl5hTkQXlI,323 +pylint/test/functional/duplicate_string_formatting_argument.txt,sha256=aUdR0fS_1WJnY_2Si8VpIYaJASIN5LKC1f9Vwdh4_EE,246 +pylint/test/functional/eval_used.py,sha256=LdeqpymK-NppcUOJmBMDoEjLAD7aeSP7bGsi7M6FFcI,252 +pylint/test/functional/eval_used.txt,sha256=s2Yhwma2-u9WHE8qxFWDDhbVDzdJnLWKB9HnmHYNNEY,107 +pylint/test/functional/exception_is_binary_op.py,sha256=OS9tUPYSt3aNrmlLKslmypOHsXxEh3VOQVnkg08_a8I,441 +pylint/test/functional/exception_is_binary_op.txt,sha256=c0dJUeWICfthkBTk6Nh8xtyNAjiFSWOufynQaxe2lA4,350 +pylint/test/functional/exception_message.py,sha256=wZsSwM8Rn_mTLQFJzzkw7Wkh23TTfgC42PiiMy-gX8I,1172 +pylint/test/functional/exception_message.rc,sha256=1Ui9f0fEwYM26SWw2YUSCQ0vyx4XIUZ6o1AYLEMQUiM,62 +pylint/test/functional/exception_message.txt,sha256=jsE6jf3DG7jbrsaokHAqyrbSjCYDZdgv47IP2UEjYoc,426 +pylint/test/functional/exec_used_py2.py,sha256=nV8bPCr9d9cyba9nTidrhJAOn1h5bO4-Tn5YsR46GJs,209 +pylint/test/functional/exec_used_py2.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/exec_used_py2.txt,sha256=cm4GBbBneq_oa5S9WIBjI4X8VMEnzv5rLwvNgHFtWeY,107 +pylint/test/functional/exec_used_py3.py,sha256=0PcuNba15KFb2kWvDH0xGPHv06SWk8qZZadYlHr6oYo,209 +pylint/test/functional/exec_used_py3.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/exec_used_py3.txt,sha256=iNRW8go_7xgVoaaFMxL2juQuKWt_C-Nir3GOFMyv6bI,106 +pylint/test/functional/fallback_import_disabled.py,sha256=3NlzGsbUGLhF9fJ3s7wS9zXcbnSc4ZIzmow1unUQGWw,331 +pylint/test/functional/fallback_import_disabled.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/fallback_import_enabled.py,sha256=_ZVdt8YL6oPVjrrHx1j0xATPbyG7K82heZ2LFDAc56Q,186 +pylint/test/functional/fallback_import_enabled.rc,sha256=0hxV-z4gH6HFvAyhnu-oIu6v8ss0MRMMrABk9zeGcoA,37 +pylint/test/functional/fallback_import_enabled.txt,sha256=R71iCoywj8VOBEGdoXhwlIFCs995BhDfIE4cPYOxxcQ,125 +pylint/test/functional/fixme.py,sha256=kdpERGPLp7twIlqXZKCjznyONjeVSbnqusyXwZRapYs,681 +pylint/test/functional/fixme.txt,sha256=kcpIj43CbXcBtF73JQXptFOFIr6sorr4gLCgV0HlHzQ,211 +pylint/test/functional/fixme_bad_formatting_1139.py,sha256=Zr1BpyAalk2_bE7W6qPH_2zmN5GwxAqCAHornr4bURw,248 +pylint/test/functional/fixme_bad_formatting_1139.rc,sha256=ebDcHUu3RKSk_UuzPmD7FR0dhnBYRHWsfndhghkbQ0Q,93 +pylint/test/functional/fixme_bad_formatting_1139.txt,sha256=Pbv7-RmLss_sXlj5ZdQ_CCzViN1ezsc7fWDxtrSUkDA,85 +pylint/test/functional/formatted_string_literal_with_if_py36.py,sha256=jwONtdXNaBHcjT-MBCsQVy4ixliGs3BLuMkBy5yy-hg,212 +pylint/test/functional/formatted_string_literal_with_if_py36.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/formatting.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/function_redefined.py,sha256=7Aq7tOblsnXyuPXv7OdQDcCLwIb8VS3wxhETP0708tQ,2316 +pylint/test/functional/function_redefined.txt,sha256=Xzuzfgih5xvdKp7KHpbswVU8MvEU6ROPDAPSjUE5quo,461 +pylint/test/functional/future_import.py,sha256=fhZ-PHkHzWQmF9vk-UrW0NTGbn0lMePe0NM471PoEgo,53 +pylint/test/functional/future_unicode_literals.py,sha256=ZsJuF_b1qI6B5R5ISBPmx6I1S9nRKT8FIunFKuoxvMY,174 +pylint/test/functional/future_unicode_literals.rc,sha256=kC2kiTq2xvygF-O3hgmbyzAH79D24qoHhYpyzElJaMs,14 +pylint/test/functional/future_unicode_literals.txt,sha256=MlspljtV8xMPqP27aLmsn3BxCfzSy5s71H2SZgXY6pc,138 +pylint/test/functional/generated_members.py,sha256=nYmHKuQpl0vsiu7Z4uCO8Y8Dl7cpuhmO9zebSYEyO6c,484 +pylint/test/functional/generated_members.rc,sha256=LJs_Lh6eltgs2-zw5rUP6n18NID_v0Bxji7f-qVywac,195 +pylint/test/functional/genexp_in_class_scope.py,sha256=uAf6ESVdiU6tfz9KXOQSjv5PTi_RuAX8O37bPaMdW7g,213 +pylint/test/functional/genexp_in_class_scope.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/genexpr_variable_scope.py,sha256=RfEOOH2HOW6VBbmymH-qFlFKy1-wzC8kQDoKRt6nbCw,164 +pylint/test/functional/genexpr_variable_scope.txt,sha256=5oSITjsvWTFxHsXYE4_nwe2hAx-q047mmWR2qd6eCmk,45 +pylint/test/functional/globals.py,sha256=KmpsX5q5csnohi54VHCJGSLVuC3GqAXEqoYZIzsKKm8,806 +pylint/test/functional/globals.txt,sha256=au851oJElayM4nwJ-jdUWT_zdLqE63fsAWGCDVbSCtc,487 +pylint/test/functional/implicit_str_concat_in_sequence.py,sha256=0OFYqpZI2qAaPR3mLiZ3FWZ4X_jLwbW6VhZGEMneUKY,1148 +pylint/test/functional/implicit_str_concat_in_sequence.txt,sha256=4uBSNAV7jqKxMKs5BXP4h1PkSMtibMXiFXbvbzqOYcY,317 +pylint/test/functional/implicit_str_concat_in_sequence_latin1.py,sha256=MvZ0ORa9SWqcJhOyMXoNWRerkQ43_UmFHu1ePle3Nbk,116 +pylint/test/functional/implicit_str_concat_in_sequence_latin1.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/implicit_str_concat_in_sequence_utf8.py,sha256=Qs1qTOpfOhVfFGtA_YSM4W23SBPWsYqjjz8ePt8Xhqw,101 +pylint/test/functional/implicit_str_concat_in_sequence_utf8.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/import_error.py,sha256=VcbQr21sRVW6eb7UVNym0d3_xWBVX7aMZz4dTpb_ITg,677 +pylint/test/functional/import_error.rc,sha256=tERYQqD_7zqOhEfueQwYkltNSsZzyLRxtoSWr-5J4K4,33 +pylint/test/functional/import_error.txt,sha256=bA3q-utDG6JsVz1ZRvKX_oV9qDevyl65exffbrM0H5Q,273 +pylint/test/functional/inconsistent_mro.py,sha256=1nu3eqnAN0KUQPgak2FHtAKndcdu3kg7RBPD5a1Hapc,198 +pylint/test/functional/inconsistent_mro.txt,sha256=gW0di-z6oiyDyrBMsyufqS6rMK-ycesUG--AusCAn-Q,94 +pylint/test/functional/inconsistent_returns.py,sha256=-ufhAKV-At51YggCa64SXWIibd-fu24XZRqeh2f9lQ8,6212 +pylint/test/functional/inconsistent_returns.rc,sha256=rR3CTC2Lcftd6e2d_finMf1d_6Mat7RIRpfGKFEyuY0,72 +pylint/test/functional/inconsistent_returns.txt,sha256=rEI7VtEZQYXn3mAXjemyisWtSsYTVFhdR6a5NDYC6ZA,2160 +pylint/test/functional/indexing_exception.py,sha256=WDDvuDiBgiw093MmgD1R2e6pvCQaSOlV8B8Z6ev1AvQ,392 +pylint/test/functional/indexing_exception.rc,sha256=1Ui9f0fEwYM26SWw2YUSCQ0vyx4XIUZ6o1AYLEMQUiM,62 +pylint/test/functional/indexing_exception.txt,sha256=r78P7aqy16kZoyRP6-BAEXxoCdJ1BPvRqX9PY1u0HUI,208 +pylint/test/functional/inherit_non_class.py,sha256=9FfpLZlbMM_4YWvntsV_Q4SkJLcF6aF0sENQql3XmSk,1693 +pylint/test/functional/inherit_non_class.txt,sha256=ZuK551BGCavBzKsho-MFuVNzvSXz3JrnqzOR2BNJgHs,697 +pylint/test/functional/init_is_generator.py,sha256=OE1r38m4H9iwLJHYjhDI87ZMvacmk9kzYqfhhaz5UC8,178 +pylint/test/functional/init_is_generator.txt,sha256=VAbjPuX7NSJe6GXtZgcUn9SUbq02m7a8OSD5sh7Pk9s,70 +pylint/test/functional/init_not_called.py,sha256=q86ALEagyNm17QbkfidWRqVmgbIOMPPHX9a0CVE7ZgY,1428 +pylint/test/functional/init_not_called.txt,sha256=YccPw7SUSDrWoLCqPV_bHC-pDXyDKmOwbtRLLWk7Xdk,242 +pylint/test/functional/init_subclass_classmethod_py36.py,sha256=X3dGyv9PWsiKmv4zRp8pQexd-MKizeUgK_zU5ZbOXZI,341 +pylint/test/functional/init_subclass_classmethod_py36.rc,sha256=9iH-Tuv_IYxXHEULly62C9cPpKKik1cET3_WTTkjt2U,27 +pylint/test/functional/invalid_all_object.py,sha256=-Ap2QRilous2Gk4Fal5n2s2aC7ScC8bBzNIflmJnXgU,160 +pylint/test/functional/invalid_all_object.txt,sha256=710b4DIr_AIoaYU_1gvYHwJBiwy4L8qolQswDvF3mZs,264 +pylint/test/functional/invalid_encoding_py27.py,sha256=rEttWkQlf9g8TlublyT4skbkmwNOMRRWiIF_1WX_Eqg,125 +pylint/test/functional/invalid_encoding_py27.rc,sha256=dMDad99Mwvz-wDojml8uyea2mymIiIhJAdBqAaDVAJs,45 +pylint/test/functional/invalid_encoding_py27.txt,sha256=J9dW91OLo8KyffBoFnKjhVmD7NweWISPYnHEmNYa78o,67 +pylint/test/functional/invalid_envvar_value.py,sha256=QbzZpXon7UbQ3eU-Q69ONpAMDT4QWO4bEMSXZtpWI3I,3308 +pylint/test/functional/invalid_envvar_value.txt,sha256=OeyrfRthcsnEMUDqRDJUcPH_PbytXHzJXuYBtdAK8YQ,2637 +pylint/test/functional/invalid_exceptions_caught.py,sha256=7Ib19znfXRUm9eMwC9A8e5majYwk4Sxb9FqL48P70RI,2542 +pylint/test/functional/invalid_exceptions_caught.txt,sha256=IdWgx9lXaTCUbAqKfkHJ0-RhQ5ksLqqxVfSpfxS4RXQ,1185 +pylint/test/functional/invalid_exceptions_raised.py,sha256=_EfZZhtPbtfORf67kj4OK7m8W4Pa7kKmQUMNXTlkgyg,2401 +pylint/test/functional/invalid_exceptions_raised.txt,sha256=DfT105wqVYY3jM3m_pRnnh3OjlEbtuzJyzng2Coz3VM,1176 +pylint/test/functional/invalid_length_returned.py,sha256=nG5LQ4SN3ctEWXkDJy6rqXmbAzrTG1IdV9CcUT8BBwM,1312 +pylint/test/functional/invalid_length_returned.txt,sha256=6VClNWGpLrzzURwabaZGeV5ld0qCH3b3jOv-b9aXb-E,277 +pylint/test/functional/invalid_metaclass.py,sha256=2U6vk2r0U3rqgNySZn2FovWfb2disZRNKnvje7eJGMM,524 +pylint/test/functional/invalid_metaclass.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/invalid_metaclass_py3.py,sha256=coEe5-RRxizaJLGL9drnFxfAErVUSblhg3YVDZALcXw,371 +pylint/test/functional/invalid_metaclass_py3.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/invalid_metaclass_py3.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/invalid_name.py,sha256=1q8nP90GyZ78mcEZ7-W7eH_hMxmpFZaBaWvmODnRFkU,860 +pylint/test/functional/invalid_name.txt,sha256=FbLEwSc2LujKW3bBAEgCkoqdJf-wD_9qmUFeGAOS9ks,252 +pylint/test/functional/invalid_sequence_index.py,sha256=H_mz0pMPUivZlYkMYZTLyg5oZYxcCDtYDUup00Nn3SU,7190 +pylint/test/functional/invalid_sequence_index.txt,sha256=O46P6QUut8CtNW8rK1fA_hHpPFQV1dquCJVxKVLwPlM,2023 +pylint/test/functional/invalid_slice_index.py,sha256=NggN0AWOVEQhMKTIijKU_s_2Cyr7QNlShcEwPh65rzY,2020 +pylint/test/functional/invalid_slice_index.txt,sha256=FUzvfSbpzlquI5lXwhi6HC44IJlK7ZowIV7rRr5v-4Q,465 +pylint/test/functional/invalid_star_assignment_target.py,sha256=NRNcVaW8TiF2Vel9fmucoYlyIE4nYySAh09Ako2cFO0,105 +pylint/test/functional/invalid_star_assignment_target.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/invalid_star_assignment_target.txt,sha256=ym5de4_8L_2EL_IvLFPwPRgZNYujvzt_11YFlFGVE8w,88 +pylint/test/functional/invalid_unary_operand_type.py,sha256=OWttntnPvkk5t5VXJIc18Fe07sAPZcMxjoR_cBDGI5g,1670 +pylint/test/functional/invalid_unary_operand_type.txt,sha256=Tsar6ArcPbAdWfy1sPxYYnjo9itBPS2wMG2UCNC-E0A,1148 +pylint/test/functional/iterable_context.py,sha256=gNBO7c9boerBA6vmshsiAFSJFHO0w6DWndNun6_jtvA,3667 +pylint/test/functional/iterable_context.txt,sha256=4BlQPGsYl_rKFo0mkROjpOTkA3Z3r2vIL7jvyIUtQoA,765 +pylint/test/functional/iterable_context_py2.py,sha256=en-q_2ha-jYkAyDNiWEvVHLd2oKRjfULUrOxrElc_ns,455 +pylint/test/functional/iterable_context_py2.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/iterable_context_py2.txt,sha256=v-v2dax56-O7r57qGMoZDpvvw9vxqyYFulXq3_j_9Fk,83 +pylint/test/functional/iterable_context_py3.py,sha256=ItsBJ59tbZYyD4i5TeQekZIiNs9_Xo6kSOQ_n7XXhsY,1089 +pylint/test/functional/iterable_context_py3.rc,sha256=RqWzSSeiwSs0paMIURZOLjT8fRhinK_RnXjo5Srp8t0,29 +pylint/test/functional/iterable_context_py3.txt,sha256=v-v2dax56-O7r57qGMoZDpvvw9vxqyYFulXq3_j_9Fk,83 +pylint/test/functional/iterable_context_py36.py,sha256=JL6C-_d7w0-4rertTWKj4aU0OkB7bTKSbTkbinC78v0,733 +pylint/test/functional/iterable_context_py36.rc,sha256=9iH-Tuv_IYxXHEULly62C9cPpKKik1cET3_WTTkjt2U,27 +pylint/test/functional/iterable_context_py36.txt,sha256=Ljl-6f6kYP2jW1pujkIMkyRc87mbl7nIJ-r5nh78Yt8,178 +pylint/test/functional/keyword_arg_before_vararg.py,sha256=k3ZhOrq8JqIOz4Ro25oZ8ygLogVfKE92S9BesZfWMVY,1046 +pylint/test/functional/keyword_arg_before_vararg.txt,sha256=KJEb1x0TPFq93dorcvrwICtywFeTMvURomDNPa2_Oi8,654 +pylint/test/functional/len_checks.py,sha256=bGh3XxjCjfBjE03ahk-9N92-H4pWLqKrDH--J_SH-U4,1618 +pylint/test/functional/len_checks.txt,sha256=o6y_ZHb54XYeP5dd3NGg4KEWJFvlKL6N6Pl8CZTUd_8,1382 +pylint/test/functional/line_endings.py,sha256=rUJ5UGa9z6iZxl34vavq2JBDuKFFgQQNrPVrSyAcTu0,107 +pylint/test/functional/line_endings.rc,sha256=cC7jOmxld3MwvX1qV4-01cLwLxLL68raC439JVv2Rws,40 +pylint/test/functional/line_endings.txt,sha256=bFXVNKR5CLcrhKD53kMVbdJiJsmNosNKMDgYb6adeV4,158 +pylint/test/functional/line_too_long.py,sha256=3VLrl_zsSiqNns1KE7hlf-gS96O2mykEWOqI-AMaUvE,1867 +pylint/test/functional/line_too_long.txt,sha256=B_2pePo3PYG8NEz7uLfxSKQT4dBye-QrF2fScURarp0,250 +pylint/test/functional/line_too_long_end_of_module.py,sha256=gE-_04NBJEdPDsIAsqu99lQN34l0pNZq2j0RM8um2Zo,492 +pylint/test/functional/literal_comparison.py,sha256=13ky1IB-UeXA_bQaTTEdwadUp4VhQkBqAhd8UylHmwc,871 +pylint/test/functional/literal_comparison.txt,sha256=nCnc2T2jBf8ls5DGxoFN0XoyFeOPkFid1tZeO4kpmUs,583 +pylint/test/functional/logging_format_interpolation.py,sha256=5_H8Dmh2p4UsY2QrnWt5_pTWD4sAf1Er-dwP3etEoY4,1528 +pylint/test/functional/logging_format_interpolation.txt,sha256=d_rDzHiNquf6fZv66aO_dr3kEgOXDHS1czKPXKXrkzQ,744 +pylint/test/functional/logging_format_interpolation_py36.py,sha256=Nli04Eo1szCwfeYqxn4mYJBwIXIRR6e_6LfjOgU_iaU,187 +pylint/test/functional/logging_format_interpolation_py36.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/logging_format_interpolation_py36.txt,sha256=4cBkzljDLTYiuFrAnBbZ6NcP7LlVWmGvIkwu_t6rQRc,109 +pylint/test/functional/logging_fstring_interpolation_py36.py,sha256=5T9hBX98Hgar3BhpMhyyPeENhu0APjK_qYys4csZSGU,737 +pylint/test/functional/logging_fstring_interpolation_py36.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/logging_fstring_interpolation_py36.txt,sha256=gT9AgPZDAhifLzSoil-jHBmfI0UD_cNHgUgGwPKdmwg,554 +pylint/test/functional/logging_not_lazy.py,sha256=MkNDIaIPpkxpyGgNPeubJMKDXd5oef_euYAjRByW2II,980 +pylint/test/functional/logging_not_lazy.txt,sha256=4E22rQz0PaA185PIImw8WeQRCyfPPw6ih9WCA9n8wc0,504 +pylint/test/functional/logical_tautology.py,sha256=zpnJayPjZGZCoMf2oAR7pIZZfnFGoFHJbGI26X2kVrA,1280 +pylint/test/functional/logical_tautology.txt,sha256=ssYvLQWMVD2VtLV_YDitWjmvhNfRdTur57WXRxdysy4,777 +pylint/test/functional/long_lines_with_utf8.py,sha256=XaTLpK8THEXb9Fb_05S9_7zwKFqbhkS2M4JzoyLWLW4,304 +pylint/test/functional/long_lines_with_utf8.txt,sha256=izpK1GK7p7nENyiS4gOuKa54B2ellweEbmfHBTyBD5U,41 +pylint/test/functional/long_utf8_lines.py,sha256=tMiZSI43iwlog3Iz4LrbWCaoyih1onnP_wkg7ky1ExM,380 +pylint/test/functional/long_utf8_lines.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/lost_exception.py,sha256=tu-U5mp7KTy-9G9AsnOCxH5X60a8OcCsLUJDx8aXOhA,947 +pylint/test/functional/lost_exception.txt,sha256=_B0NddixeZWdizh_FQsON6coAi6TehPrg4evWcCeIBs,200 +pylint/test/functional/mapping_context.py,sha256=DRrhBCE__4b2eHBVmAOB6IGZLlgJqqOXrOhcNd04jvg,2225 +pylint/test/functional/mapping_context.txt,sha256=JNDdGhpSdlnZ7e0Hd5n66HY_e5XtbCKTJtxqCG54PgQ,157 +pylint/test/functional/mapping_context_py2.py,sha256=Ty9G39CVN2WdXmAuUlgKTFnV28CZlwapO10RU4IY97Q,475 +pylint/test/functional/mapping_context_py2.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/mapping_context_py2.txt,sha256=Y9Hd3g0dfTaiW8YLKEj9UicqsOykP20E7ni_J60fYHo,77 +pylint/test/functional/mapping_context_py3.py,sha256=KFB4XmCCSXfby_BOPPagU5HU9CcCVIwAvHEhxK8TYcM,413 +pylint/test/functional/mapping_context_py3.rc,sha256=RqWzSSeiwSs0paMIURZOLjT8fRhinK_RnXjo5Srp8t0,29 +pylint/test/functional/mapping_context_py3.txt,sha256=Y9Hd3g0dfTaiW8YLKEj9UicqsOykP20E7ni_J60fYHo,77 +pylint/test/functional/member_checks.py,sha256=OrvZP5wfMy0_B56fV_zjmXodLNuhUCa6P2pyMuLAu-s,4871 +pylint/test/functional/member_checks.txt,sha256=ch4o-Y9MnCtFRQ6OOZ5q8gZz_MYeEgxw7gGCgmmXCNo,1503 +pylint/test/functional/member_checks_hints.py,sha256=BrhTf4BwNgigArPT_kY6f9ZDNcczQLqJrIafjP58QfU,717 +pylint/test/functional/member_checks_hints.rc,sha256=BBnSYQArEUHDtRHN75P9RpXcVQ_R3Zm7zspTqZmDo3o,75 +pylint/test/functional/member_checks_hints.txt,sha256=x7uQSI7X-QPmwYPSCy3-ZxvfCoyyX5GUnikpy3Xsyrk,572 +pylint/test/functional/member_checks_ignore_none.py,sha256=v4MWr4JorJOgRZUXAwSaSOiwTqEtLgRNxkxdn8USfoU,130 +pylint/test/functional/member_checks_ignore_none.rc,sha256=8ATiQ3-tkfE7jFb6C7SGZ6xs1Iksyt-mdcVRLfpUg9w,26 +pylint/test/functional/member_checks_ignore_none.txt,sha256=H1hI0ddAp4wK4m4AIURIV5sFgYSldgBW-hv-Nm5P7oc,76 +pylint/test/functional/member_checks_no_hints.py,sha256=BrhTf4BwNgigArPT_kY6f9ZDNcczQLqJrIafjP58QfU,717 +pylint/test/functional/member_checks_no_hints.rc,sha256=j5DX3Ic5rxkr7pJ3aXKAWpZVS3NcILxYAdBQkB419mQ,34 +pylint/test/functional/member_checks_no_hints.txt,sha256=7hcgy2Xo6NyBqTmKmhRkbzsxUlicBrn6cSAMWjb5lF4,443 +pylint/test/functional/member_checks_opaque.py,sha256=hGg9ab7tsLnE_sdjG0hLjlxdt5EBV9cauWUvZ3bDBP8,206 +pylint/test/functional/member_checks_opaque.rc,sha256=3UGjMojklpOiYXwGaR3nzRs95pFVDPeC7Z1oJYejMnY,41 +pylint/test/functional/member_checks_opaque.txt,sha256=BOFvAZfQxBgqU1EYAKzAGUlrOtWmFj8RmHeMhSy6NaM,63 +pylint/test/functional/member_checks_py37.py,sha256=VcZpTkaml8BiT2zdJPJx-ho8rgpMsEVz_SKpv-x9JxM,344 +pylint/test/functional/member_checks_py37.rc,sha256=8Mf5ZLn89xee6ydJTQzp-2rPCW9iMXS3leoD3ByDfIk,27 +pylint/test/functional/member_checks_py37.txt,sha256=P4o61NS3NN9DfM_TNBusoHHEgzeAnO07egBUR4oiBSE,98 +pylint/test/functional/membership_protocol.py,sha256=-KdpKhQlhu2lPZP0UfpKfmBji5M2pCMNUPp0iv-yLzw,2928 +pylint/test/functional/membership_protocol.txt,sha256=LTK3i1AQiG6vajbJsqA7KhaYeK-cFl9UniWFk_QjMCg,559 +pylint/test/functional/membership_protocol_py2.py,sha256=id1AZzHKj7X9zPR0cxIv78Qt-TB5l-_KAXXm1GIaBuI,1029 +pylint/test/functional/membership_protocol_py2.rc,sha256=EvZlp7G0xcTwgpl1OgqiTRWBNbwA1cStbHei3d7YGO8,29 +pylint/test/functional/membership_protocol_py2.txt,sha256=76hShITkOsMX4FIdxefhQQB4Lx7Smx-bLQkobDbUbuo,280 +pylint/test/functional/membership_protocol_py3.py,sha256=EdMXjzHUbJrshnQBWoA63X-E23iQAqrzbvFnpL-Hz9k,944 +pylint/test/functional/membership_protocol_py3.rc,sha256=RqWzSSeiwSs0paMIURZOLjT8fRhinK_RnXjo5Srp8t0,29 +pylint/test/functional/membership_protocol_py3.txt,sha256=76hShITkOsMX4FIdxefhQQB4Lx7Smx-bLQkobDbUbuo,280 +pylint/test/functional/messages_managed_by_id.py,sha256=bAXGDHRYF4V8yf97iB9k1teHZ8UvD5Zc1jMqN-TzntA,236 +pylint/test/functional/messages_managed_by_id.txt,sha256=CQE9Mk2MpbSFOdeaKJzIwA8eT3_ki0gpbKM6rWyHHMs,573 +pylint/test/functional/method_hidden.py,sha256=SosdHhZWIAE2a6c5S7NvOK-mSv6AcuXQitPCrXRxdiw,1160 +pylint/test/functional/method_hidden.txt,sha256=jtyOl0K2LqYYVMIr4kyi4H7FcanhQDVZUubEqvPEbTY,101 +pylint/test/functional/misplaced_bare_raise.py,sha256=Sp36BN3-Z_GTw5EWzxyI-X_6zSzQkNcT7i5eBkdC9JM,1886 +pylint/test/functional/misplaced_bare_raise.txt,sha256=T3M88QOyH6iKZ_ix8kAC3InuZJOMhwCpdzA65rFPHgA,554 +pylint/test/functional/misplaced_comparison_constant.py,sha256=2WinzyMFODRHbM_F3mQBanVbQzKMPSJQ-qNXhdXuCkU,1031 +pylint/test/functional/misplaced_comparison_constant.txt,sha256=47EzZ9e3YO_Ke5vvlUPtiHGVomZgg6zr4fw-jiFgiW4,524 +pylint/test/functional/misplaced_format_function.py,sha256=c8EflzOmST8zlOZwlYeQ_QJvf3Nl6U_frAxksHGTabw,1682 +pylint/test/functional/misplaced_format_function.txt,sha256=PfGq9_rCw9JxllGUi88l8cSJVWHtC022T3giPuOYgCI,289 +pylint/test/functional/misplaced_future.py,sha256=azg9M2DYy6JDeZnqGNrKNoHoaX2FDPZew_7Ga4lpARw,217 +pylint/test/functional/misplaced_future.txt,sha256=LMkbqbBnEErRqfaQMRtYwJenqNdxjdHPmNDJ_CFgKQg,80 +pylint/test/functional/missing_docstring.py,sha256=-QvH_3TSqqFmoXtcPNaL9d9eFTW-Q3MAWjKPvOUAS1U,936 +pylint/test/functional/missing_docstring.txt,sha256=z1Mb6PLtMRwwTjSv5LDzliZyEAjjJNzny-duw6rdfP8,177 +pylint/test/functional/missing_final_newline.py,sha256=NXrgD3ITr0fXJenute-ERFL0lGZyhRfch0cHlgpZ908,122 +pylint/test/functional/missing_final_newline.txt,sha256=zDEBRcb3JxZh-JlvHKK4ouUTgVZdHJVZmWbo_0mWL1A,47 +pylint/test/functional/missing_kwoa_py3.py,sha256=WDWXme5yNQZa-tTh25-hL9rxyKbxWCdktlx8ZhisgGA,671 +pylint/test/functional/missing_kwoa_py3.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/missing_kwoa_py3.txt,sha256=4HpS-cchek1v0Hgw2OJ7nMvJfHJrjGAfrRa9ovmCfs8,253 +pylint/test/functional/missing_self_argument.py,sha256=IhzsDXhI1yKtG6QntowSQ7FCCQWxTekWtZUz6Wy1igU,555 +pylint/test/functional/missing_self_argument.txt,sha256=KUB9dwTGR8wLVKl0sppMxlzXtmDL8v6FVxThRf5gBqI,246 +pylint/test/functional/mixed_indentation.py,sha256=IHVRd-rjiGjHre2L2h-0_dOg0tYUU_jNf9ttCEiMm4k,204 +pylint/test/functional/mixed_indentation.txt,sha256=ihS7JW2T8JYtzcJs4uELcRINijAUNPi-zrL3fjn33TM,135 +pylint/test/functional/monkeypatch_method.py,sha256=z02iKn4O-_YP_9OIBbvyl5O9SUXsFa0jjwvoqZVH-1E,411 +pylint/test/functional/monkeypatch_method.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/multiple_imports.py,sha256=VLRhgvak-J1jCdFy0U4ofzZKzCF5llXdoY_xZoT8Xuc,91 +pylint/test/functional/multiple_imports.txt,sha256=mvkM1OVCbm2Ke3JzcVa-8ea_j71Be5tOGCHBGxlK1-8,62 +pylint/test/functional/namePresetCamelCase.py,sha256=ZRqTfc5_HtLb0RboujV88ttPxqBh-xnRm6xGUdkoXIs,538 +pylint/test/functional/namePresetCamelCase.rc,sha256=04oyXoIfi70P-nTO-h3BQdjShqbnVYO4CXm13le3uTA,347 +pylint/test/functional/namePresetCamelCase.txt,sha256=N6GcY06kyAXMyGBCypZB3BaTA2ct5gShowvi7jYm6wk,422 +pylint/test/functional/name_preset_snake_case.py,sha256=6afufg3ZGyTY1OgHHvDZ-BdI2a9j61nPhgrmg-w4YkU,554 +pylint/test/functional/name_preset_snake_case.rc,sha256=Y_RkQJe3CqvIgNQhOW1pRrQGmdb03r1i7LXDkOcniRw,357 +pylint/test/functional/name_preset_snake_case.txt,sha256=loeAXrV5IzCBCw4uNoEXELehFCEVu9cYNKVF_5q2Pzs,428 +pylint/test/functional/name_styles.py,sha256=Ocsrt7mDLpffNmmmRxRJCRqrm_3xsMBGkC7V-PpxuaQ,3784 +pylint/test/functional/name_styles.rc,sha256=80Rqw8e1IDXY35YXOkLggmImdxWBUX0T4HBi909IP8w,120 +pylint/test/functional/name_styles.txt,sha256=BfnSk8FYc3ue72PM2iqAyynjDl1oVezg-C7cu6_x0sE,1875 +pylint/test/functional/namedtuple_member_inference.py,sha256=xRHbnUsL2AqkEYDKK_m4UfS4ZQMpCmLAhyjE7JwAGO8,559 +pylint/test/functional/namedtuple_member_inference.txt,sha256=rwUTUiqo_wlWqsdzDLNifcv8HSNuqU5DJsmtf8jZbsM,132 +pylint/test/functional/names_in__all__.py,sha256=c2ifBDJf-cZ9EtKsm_ar4qwlBolniWxgdcZCRyDrLjc,1180 +pylint/test/functional/names_in__all__.txt,sha256=t12-kMvim2pJnZq1oyhACkqAAqlj8iVKvaRJ93ulv8M,413 +pylint/test/functional/nested_blocks_issue1088.py,sha256=4VOkobCJ5ImOK1o8oeLT_Ul17qkV5wjhViaR0WnBt8M,619 +pylint/test/functional/nested_blocks_issue1088.txt,sha256=ky81N3w6udHjlJafykpSE6n4iKJJWbLgFQUfYzoO-4o,139 +pylint/test/functional/no_classmethod_decorator.py,sha256=_Dor1VpyCD0y_QcnMOZwaZ5EMCyU-MpY9p4O_E84AuA,942 +pylint/test/functional/no_classmethod_decorator.txt,sha256=TZQCbby2Jd7xusqCyOpQCR7Jsd4lNoFo5ad6XR_Ssi8,282 +pylint/test/functional/no_else_return.py,sha256=vnf9mxhE1dfuRKT6yHVAbGkg_g3AIZ9AMGt7Xk-qxGo,1112 +pylint/test/functional/no_else_return.txt,sha256=HSWQHvy2yQ0Hug7WdwXaJsUeG1n4AKPo-fd5VDT-zgk,284 +pylint/test/functional/no_name_in_module.py,sha256=pIBEQUezcK0A_WmFUm7jrb5HPxe-y-FH8dQ10o2tPns,1519 +pylint/test/functional/no_name_in_module.txt,sha256=mhPrQiay9S8F1hvE-CqsRHBy_nPupXhEO4SOUdrxczU,942 +pylint/test/functional/no_self_use.py,sha256=coE7zGsKtHZiCd5npAnwQ7AHKc9KGHG-G94Tad9yaKo,1735 +pylint/test/functional/no_self_use.txt,sha256=h50KkDLP3oLPAYRF5vsIUVzPL_BsFA7oqCIPrxwKyU8,62 +pylint/test/functional/no_self_use_py3.py,sha256=iap241NxXnWZ-9TKnvznqNQ2-9M60jkrnn_-0VQ4EFs,311 +pylint/test/functional/no_self_use_py3.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/no_self_use_py3.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +pylint/test/functional/no_staticmethod_decorator.py,sha256=ul7Ke5k6IMd5FVl9OOWhaOjR7_lJzRwow9sRlMwoeBg,949 +pylint/test/functional/no_staticmethod_decorator.txt,sha256=Bx30vIux9PUHrgfilM2i_FhoeNwsbCSDCl7Fy2Ja2IU,288 +pylint/test/functional/non_iterator_returned.py,sha256=qNFcaPQkGoKfljDxFNah5SBQu-x6WkLkcfEf2w41e7E,2274 +pylint/test/functional/non_iterator_returned.txt,sha256=JbAye34jA3-Hx_TGm6Dp4UPluzTUGrm959hJEOnoRb4,326 +pylint/test/functional/none_dunder_protocols_py36.py,sha256=nNjWM8qAoYCGp6-E2uWHae5QT4QPwsj-PmFPedkUilM,886 +pylint/test/functional/none_dunder_protocols_py36.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/none_dunder_protocols_py36.txt,sha256=TXCFaOOmk0CTW9DApZ4yfJqb0s9jiaNfkDFYcaomMZ4,572 +pylint/test/functional/nonexistent_operator.py,sha256=ZiRcIaGuAvJNqtsWfbqnfUkAuRDDLAnX2oz8WBybLKc,319 +pylint/test/functional/nonexistent_operator.txt,sha256=p0ZXjDN3x_XjK7Vc2km_Opy1Mk4RjSTKOYoGs5Gg8hY,375 +pylint/test/functional/nonlocal_and_global.py,sha256=DZDCGn7imc6R28UbpNcwCCvzqKhtysORgAoC2DRnm88,350 +pylint/test/functional/nonlocal_and_global.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/nonlocal_and_global.txt,sha256=pFvUXp1vln50bpA_QY7pGpib75MA9gaMwPn0vOtz1Z0,65 +pylint/test/functional/nonlocal_without_binding.py,sha256=MutfZjh-mOgM6zX1iZd1s9r4-iCPCx3X0voRBi-Ho-g,870 +pylint/test/functional/nonlocal_without_binding.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/nonlocal_without_binding.txt,sha256=QfPjlQbmwYjLkxCaKAA5Ob2v4r3iC9hAcwfbXUw-Syg,248 +pylint/test/functional/not_async_context_manager.py,sha256=IvwvYkUIYZ0qE6zUXmuUaaXgAeaehgPwAFC5H2jLMec,1658 +pylint/test/functional/not_async_context_manager.rc,sha256=dP_Zfqp4xaJCM9jhYtOqNIbxRfpn2sV_Sny0wLYzPvM,27 +pylint/test/functional/not_async_context_manager.txt,sha256=VV0pOZOmwgtG_LyeYtz8rHQqwuxn1fagZndSMrcOUyM,619 +pylint/test/functional/not_callable.py,sha256=jxaeGXuA8gNg8qzUCnsb541gqLQw4LnpXdzmGuu5h5I,2524 +pylint/test/functional/not_callable.txt,sha256=2rDNKgWWhJp-Wz9l_Wg4DEsvSTmXxelkCksj-Xr8QVw,322 +pylint/test/functional/not_context_manager.py,sha256=a7y3-lXgrvsmn5kfMIiijzHqhOXxx6VxNxSTkmWX86A,2630 +pylint/test/functional/not_context_manager.txt,sha256=e_rzgY8dnb9qU_oJgBVWGDWL6Kh2ASfA69L-bcgKqz8,455 +pylint/test/functional/not_in_loop.py,sha256=LLfZasH-bPFc7CV14Mnfks60sJ8d_p04cindju1CSb0,877 +pylint/test/functional/not_in_loop.txt,sha256=gJo3sQLbBeyk9TgYDYExYBskVqBubc4_bH9jxZi1L8M,384 +pylint/test/functional/old_division_manually.py,sha256=d4qvY764wv5u6C3pSWbF_f5OHOp5x851LtEL1OPZ2-s,43 +pylint/test/functional/old_division_manually.rc,sha256=xhrY9LBkXcC0EohjfHkMKgFwQHS94JiwYLLT39hJ8tk,79 +pylint/test/functional/postponed_evaluation_activated.py,sha256=tIBLLnB4B50G3X5erVf6iCOnGX8b8AneUdE4n7PIa-I,356 +pylint/test/functional/postponed_evaluation_activated.rc,sha256=W1RCDtlFM3Jcd2PqqvGxmreLaf5CPS87YthqciNpAGI,28 +pylint/test/functional/postponed_evaluation_activated.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/postponed_evaluation_not_activated.py,sha256=OBegm2_aL-dCqyebzUv_TWSEn-Xpwh-y8Kaeyb6U1kg,355 +pylint/test/functional/postponed_evaluation_not_activated.rc,sha256=W1RCDtlFM3Jcd2PqqvGxmreLaf5CPS87YthqciNpAGI,28 +pylint/test/functional/postponed_evaluation_not_activated.txt,sha256=kONm5bVP5u3hj6NDJf1csTRQ0G5VsTQmfYhk2wCGmWw,154 +pylint/test/functional/print_always_warns.py,sha256=_JscxeuyRpeVEDLaOh6tl-M274_pba-J7Glhlf1_qJY,207 +pylint/test/functional/print_always_warns.rc,sha256=wn6NkLPWImrQa3odtdG1fwi66P8SzE2gb3RgEk4pEk0,63 +pylint/test/functional/print_always_warns.txt,sha256=rCkr0W1KBVruOcnbVoD7PyrnXxmdtL_SefiYL9R4yfk,40 +pylint/test/functional/protected_access_access_different_scopes.py,sha256=_xa4m24O4Ie_qXTdRNLoyDWTgEAkFChOaimVu-9WWmU,235 +pylint/test/functional/protected_access_access_different_scopes.rc,sha256=5wJVJR3wPbQJphqFa3SY8a2m0Mro5K4mz0rCpCaI4Iw,28 +pylint/test/functional/protected_access_access_different_scopes.txt,sha256=kw4-bU_g3_XaZsJifJ2alr9m3u5Z588f3icGhx7OVB0,112 +pylint/test/functional/raising_format_tuple.py,sha256=qlUr3rS4VmBdam-jAzCq71sm53gVnpOWlvyitEyOcLQ,1898 +pylint/test/functional/raising_format_tuple.txt,sha256=aEt0BARED3CrKSNN8FcY19frDxT_WugyI8V_aHYah5s,725 +pylint/test/functional/raising_non_exception_py3.py,sha256=RDyLrpN64dLbnmOsSUE1bN6XG9ihRO1jj9Fr5rTc6OQ,416 +pylint/test/functional/raising_non_exception_py3.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/raising_non_exception_py3.txt,sha256=ETtFnJHj1xzb3kNpfyrCquHyLJMXerEsC1eWWos9FjA,92 +pylint/test/functional/raising_self.py,sha256=aQ-BixFGcWZpc_zEeNSTR4X4uagUKdOoLNz_FBqXrgg,213 +pylint/test/functional/raising_self.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/recursion_error_940.py,sha256=vMHiy3kZwugGMlPv10F1mo5OlsCh-xXz7Q3VXWrDY-E,282 +pylint/test/functional/redefine_in_handler.py,sha256=UDjfBsYXBR5cr5CpvPxa1oKO77CCsDnp3rC9TCao8g4,1585 +pylint/test/functional/redefine_in_handler.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/redefine_in_handler.txt,sha256=cwFgise8_FKMEK5Xz9XGPNsrXM_cEnQm9WhwyD21U1w,717 +pylint/test/functional/redefined_argument_from_local.py,sha256=FZ9ifRjXlNt-3vvWBJDVutOq3LYk9etEvTbA-KUI_2c,1627 +pylint/test/functional/redefined_argument_from_local.txt,sha256=92Hc_xTCRqqYc5oCEtZ1QCXjZv3T6gfyyKqh4MrZu00,724 +pylint/test/functional/redefined_builtin.py,sha256=gIZ3Dp_LHjVwueb2ViXzoMJhLO34u4hjv-F8rCLJTc8,260 +pylint/test/functional/redefined_builtin.txt,sha256=Mr_NpfYtLy_Sij4q56AjltZnjVP4HMkdcpNanxRx3LA,104 +pylint/test/functional/redundant_unittest_assert.py,sha256=Uioo5zQHmM5SExOV8Kqw8lnxXehJnke91Qe96aY_5Js,1307 +pylint/test/functional/redundant_unittest_assert.txt,sha256=WrNHlDuDTcmUKgQ2bDkU0DAFJF5y07bB608KwLR37Gg,695 +pylint/test/functional/regression_1326_crash_uninferable.py,sha256=VPUnJqbk0ulwfKw4nct8UllnklqKp0E1uz0vhaiyLzw,202 +pylint/test/functional/regression_no_value_for_parameter.py,sha256=cE8pFO3dAuNXKzDujRGPXFSvG0Y5Di5SKJzLU-lKa6U,291 +pylint/test/functional/regression_no_value_for_parameter.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/reimported.py,sha256=hM3ON6uJZieLYqS6w2L-BAbG3fhIL1_8dikNcxgUlHA,540 +pylint/test/functional/reimported.txt,sha256=6bj7BT9ybGrQVpY1Dm8QKuPCeViObJ1sES59ags1DKU,209 +pylint/test/functional/repeated_keyword.py,sha256=KKMEbdGzyio5J41hH3wZo82atyMbb4EmBvV1AFr9HXQ,311 +pylint/test/functional/repeated_keyword.txt,sha256=atseLvN_m75mZpk21BV2tKM-8itxwo99AjgO1dn5EqU,84 +pylint/test/functional/return_in_init.py,sha256=yQFaiDzX9qzHTle4xov-xICa0gZEEGWGQIyyZtYyVb8,484 +pylint/test/functional/return_in_init.txt,sha256=CN37ipewtRwwY8KL8htH2iu9MTW1Hz32pvzgx19DNB0,61 +pylint/test/functional/return_outside_function.py,sha256=VH4f9G3LF4uYQNhXiNzOMuUOzyK-kpMN_tNIXISatug,100 +pylint/test/functional/return_outside_function.txt,sha256=ACogyqzB966QwsU5AMDiyMhLtY6Fn33ZoxAjX_7zOdE,50 +pylint/test/functional/reused_outer_loop_variable.py,sha256=aVuZumO3kZHMdQWXQvgG4CkiWj_Gz9vz2SbveDyGi9w,865 +pylint/test/functional/reused_outer_loop_variable.txt,sha256=bBtjRBhZ5x3J6X7D6XrBtZSgnPn1aORBDoZQWYVPNPg,286 +pylint/test/functional/reused_outer_loop_variable_py3.py,sha256=zqjL-y0K3ZwY-9TWSu0_Tp1z-kvP_g1HpTwtJTCwaZE,159 +pylint/test/functional/reused_outer_loop_variable_py3.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/reused_outer_loop_variable_py3.txt,sha256=CbYBO4KqInzshTcQwE7ZaEUzEJtWcujPaKzrTLIzewY,70 +pylint/test/functional/self_cls_assignment.py,sha256=u7fUr8EmQyq0gk_yMLkbQYQ4vo8LuOvbvPjc4u3XaFM,1287 +pylint/test/functional/self_cls_assignment.txt,sha256=_at3S8N40ucutEdSWIOhJqiclfE0-5P-vRQU3-CUVos,313 +pylint/test/functional/signature_differs.py,sha256=yreNtEhK7bmg1p-r4aDFE8ekS0I7BuutSWLP8kqBt2A,468 +pylint/test/functional/signature_differs.txt,sha256=03lletfRhrolgCVcESCe0EAlYVZaNgZ0t2eOgbX0yCs,79 +pylint/test/functional/simplifiable_if_expression.py,sha256=TWWf836CJoBNDnmMk_xBCqB48TlSWEMjONgXhz1OCa0,894 +pylint/test/functional/simplifiable_if_expression.txt,sha256=BjPqcO30v9nBh58gl7_nz2Ui91viTrmRONdq5m9v7-8,396 +pylint/test/functional/simplifiable_if_statement.py,sha256=fsTNm9yoyQK4uQxjqIr3kAefsslxk5dRMGw31Uo9Kbw,3657 +pylint/test/functional/simplifiable_if_statement.txt,sha256=JZMqcqwcJzUqDUL-ytBmOh8A1C72JGps5WwQ-yb_x2I,426 +pylint/test/functional/simplify_chained_comparison.py,sha256=juin6RwUnhSNcGMqgHaPzFHHJKSiyaoOA7c27w0BwdQ,1787 +pylint/test/functional/simplify_chained_comparison.txt,sha256=6qlC_0CL9_dVPEG7hFHZKADGKTIchjB8FogB2N3erMQ,1377 +pylint/test/functional/singledispatch_functions.py,sha256=f5R8w-omFzMTXDpInfHjzxIlur8ssmAv9m65TQAiO2c,1470 +pylint/test/functional/singledispatch_functions.rc,sha256=FJkAw5uAAAwzV_aakmE_4u5AuL6G_YhkcywL_qexB_c,63 +pylint/test/functional/singledispatch_functions.txt,sha256=TEEOAoP20jzMAnFlJwup4D_THCn2_cQaLb4-AkHXwF0,303 +pylint/test/functional/singledispatch_functions_py3.py,sha256=f5R8w-omFzMTXDpInfHjzxIlur8ssmAv9m65TQAiO2c,1470 +pylint/test/functional/singledispatch_functions_py3.rc,sha256=RbJ6RCy3Q3hhH9Q8pVPpmhFaIfeXISsKI6bvnNZ1x7o,63 +pylint/test/functional/singledispatch_functions_py3.txt,sha256=TEEOAoP20jzMAnFlJwup4D_THCn2_cQaLb4-AkHXwF0,303 +pylint/test/functional/singleton_comparison.py,sha256=F6QGUZda_ErZzT3k-SjwPprE2YES6B_PyNIkZ96JN48,514 +pylint/test/functional/singleton_comparison.txt,sha256=WHC0arj87m_AJnuXQnZQdtbouV2rC1bOWnuHTW7V4p4,537 +pylint/test/functional/slots_checks.py,sha256=Eh_0Np1FnfTxGDZwdBjHC_sypbBGgKzMvYdLY2shThc,1863 +pylint/test/functional/slots_checks.txt,sha256=zRO-VraCeF9YV8mscuSNbTatu_6kTVF_qQ3yeBo9UvE,629 +pylint/test/functional/socketerror_import.py,sha256=CsNQZttnRJ2ygziEbetetBgir7cZBD0jWGsJfVZKBCk,183 +pylint/test/functional/star_needs_assignment_target.py,sha256=etAnsk0i11vcu42cr6wFzeVxr9kSvwfERn3FzdZSj2U,105 +pylint/test/functional/star_needs_assignment_target.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/star_needs_assignment_target.txt,sha256=JcnepZ9Y0CkzwiXGPE2fRt5Xo5mfLo43fMPCxGYS9G4,86 +pylint/test/functional/star_needs_assignment_target_py35.py,sha256=kEiGK2YpJ9kdgm40BEu4bgG5FzlwWbL-K5c1WtzeWuE,445 +pylint/test/functional/star_needs_assignment_target_py35.rc,sha256=5wJVJR3wPbQJphqFa3SY8a2m0Mro5K4mz0rCpCaI4Iw,28 +pylint/test/functional/star_needs_assignment_target_py35.txt,sha256=Ph4h1mD8ITOEJbvf6jS_qNOLPsQOFVuqWP32MQHLVi0,85 +pylint/test/functional/statement_without_effect.py,sha256=I-LaUgnCrMnUo-k72_32-42MHK07yUbPCsbdV11C7m8,1740 +pylint/test/functional/statement_without_effect.txt,sha256=gtw0WEFkm2QOQBqRuNLQ5qi5s3dLdgdi870iOa7hGus,2240 +pylint/test/functional/statement_without_effect_py36.py,sha256=6NrweC1PoemO4y-xzkLFfG35xs8nctBi3MjxfAUBx_c,420 +pylint/test/functional/statement_without_effect_py36.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/statement_without_effect_py36.txt,sha256=5zOVcttzyd_Tbf72BzMvHa8OmYphFwtdm3Y39hqyy_k,84 +pylint/test/functional/stop_iteration_inside_generator.py,sha256=8KXfRogr5bDpnAu1vkNkZ5jCLh6mvwSsfPxxzl19tHs,3217 +pylint/test/functional/stop_iteration_inside_generator.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/stop_iteration_inside_generator.txt,sha256=nj4EVrY2ZLmE1JETJ1p55bfYUpQ7bgdqKO0RCq_pp5Y,850 +pylint/test/functional/string_formatting.py,sha256=0b7W7_0LGop3EKEjDM4pvAw3WGMK_1MvFld0NMplV7s,6452 +pylint/test/functional/string_formatting.txt,sha256=8L6jndqBiGsZdhB6E9gOcA3Y3XAxZLIgFV3w5JvxrC4,3397 +pylint/test/functional/string_formatting_disable.py,sha256=zO5wyTXXt3t0qp1UDkdPVxYIntbNseMsOYXym1jhCFQ,40 +pylint/test/functional/string_formatting_disable.rc,sha256=Dj_Xvo3iTN9PH-u9-xNnhP8LxWK2_oIZrVFsX3YTL9s,56 +pylint/test/functional/string_formatting_disable.txt,sha256=hSEj-DVCceANt3XS-uR8okJXfk8cO3KKB7TrgoDklIk,42 +pylint/test/functional/string_formatting_failed_inference.py,sha256=4927xH5cdQBQ4Y7tYVh4vfpsp0tyYjsYJHG_eNyXRLU,152 +pylint/test/functional/string_formatting_py27.py,sha256=qgO6VNWnZv_VAaw_3QmPIBrL1-jegKmKS7m-2OyZ7YU,930 +pylint/test/functional/string_formatting_py27.rc,sha256=qRj-wLosrKU8gZhRSrSn218Et_3XaommluMlOG7Hiv8,42 +pylint/test/functional/string_formatting_py27.txt,sha256=8J0p0FjRtkliO9lf57ctjYvv3aVrs0-zeUxQWmubXiQ,1227 +pylint/test/functional/string_formatting_py3.py,sha256=nSp7FxBlThp3bm0QIS0vQnjsefm229oIe7eiCQqNN1c,475 +pylint/test/functional/string_formatting_py3.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/string_formatting_py3.txt,sha256=0VIFxy_siK-VHwJVNTvczvEnWhhZw4fRkElKo-JWDFo,153 +pylint/test/functional/subprocess_popen_preexec_fn.py,sha256=yr_CIo-5Z-2lQIrCcjreMzmjUKhmpB-RIab6dj81cUE,203 +pylint/test/functional/subprocess_popen_preexec_fn.txt,sha256=AZ1EN2Bde7lkm8xJwxLngzWmMTjxHI0sojkzrZsNwns,103 +pylint/test/functional/super_checks.py,sha256=DYuRZKCXJ62T-OxofclXvYSmgGvaYz2-_lGbCYJuuFg,3926 +pylint/test/functional/super_checks.txt,sha256=XEuQ-B6UY0d9s9mkqACdN_0_8iuT8B2_Vo3fxxqRyEM,1649 +pylint/test/functional/superfluous_parens.py,sha256=8-CprSANzn54gN2Z7s1ypRJvXQA1j2-2upgEvYNUf_Q,463 +pylint/test/functional/superfluous_parens.txt,sha256=ST4OVvNQvLntu4-w7kLfhuB4vjHK8mItO0PZyfj0tBs,306 +pylint/test/functional/suspicious_str_strip_call.py,sha256=Tv89qLRHvUxoTrRnH9_-1njRrRuo6-wCjOUfmmAX3gM,216 +pylint/test/functional/suspicious_str_strip_call.rc,sha256=dfft_8DY_J7Jp9Fx01L04fhp6MF-Nji2KNeVqviylQs,28 +pylint/test/functional/suspicious_str_strip_call.txt,sha256=1U3i3bsL-V4Olk8blCtP8PvuZvW-sM4RSJ00QLk8wAQ,190 +pylint/test/functional/suspicious_str_strip_call_py3.py,sha256=Tv89qLRHvUxoTrRnH9_-1njRrRuo6-wCjOUfmmAX3gM,216 +pylint/test/functional/suspicious_str_strip_call_py3.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/suspicious_str_strip_call_py3.txt,sha256=nJtS34qrV2uNybwc4Rhw3q3ZcBhNp62JvQ8gp8jlYrk,184 +pylint/test/functional/syntax_error.py,sha256=nQF4Xi4qcYgDXK7FMTTVXUaqKv50T1g3lob1ljIpVz8,26 +pylint/test/functional/syntax_error.rc,sha256=kC2kiTq2xvygF-O3hgmbyzAH79D24qoHhYpyzElJaMs,14 +pylint/test/functional/syntax_error.txt,sha256=T6JTIJVWZDCT8KP_cgdjdE27-pKzb5DskRxQVND9X4o,50 +pylint/test/functional/syntax_error_jython.py,sha256=nQF4Xi4qcYgDXK7FMTTVXUaqKv50T1g3lob1ljIpVz8,26 +pylint/test/functional/syntax_error_jython.rc,sha256=VC98INc18VlFpZbCBe2Bzw0lUBLphUss-KLhND8RsDk,51 +pylint/test/functional/syntax_error_jython.txt,sha256=lWovOOTx6d8bQOl17HabjNlzDZ4yzr5TMqiL6rUjL3U,62 +pylint/test/functional/sys_stream_regression_1004.py,sha256=Oo3stDX9pS1XLMy5Oaa39X0nKya9tEmtfUpW4BnDAQs,253 +pylint/test/functional/sys_stream_regression_1004.rc,sha256=vTZM9QCK6TLo49sSHxwkflWD3N312KZcCdi_QMoAurw,55 +pylint/test/functional/sys_stream_regression_1004.txt,sha256=F-uI0OH56j0yLVMVegWEBZSb1PSRmVMvcdI9o21mrLc,162 +pylint/test/functional/ternary.py,sha256=AiEOR71sBfuh6Bn2AuwS8WGCOednsbeITDAd3yKJUpo,1343 +pylint/test/functional/ternary.txt,sha256=9jY78G_Ep-wG4-VpN_HK8_pJCHJDu_ae1sOiL758lrw,716 +pylint/test/functional/test_compile.py,sha256=GhSp_Z0CB9KjuGkc5iJ1l3K18_ml3FFaJr6jBZ4zFLM,242 +pylint/test/functional/tokenize_error.py,sha256=cHAQ4LYrW8juG2FrQdGRXFWF4bQhqEFsWQoa3k8G1r0,193 +pylint/test/functional/tokenize_error.rc,sha256=kC2kiTq2xvygF-O3hgmbyzAH79D24qoHhYpyzElJaMs,14 +pylint/test/functional/tokenize_error.txt,sha256=L0dreEbFfEbc3tp2ydCJLAnpstPGDhPYUi5uvowcSds,44 +pylint/test/functional/tokenize_error_jython.py,sha256=HF-gbLoqKkfKPSF3z3K1m5jgC9nbdm4y8NnmHXNZzmI,190 +pylint/test/functional/tokenize_error_jython.rc,sha256=AiHLuaO2WGUOYfc8ME3Y_sNW8ter9K_HFf8v9c9uI88,60 +pylint/test/functional/tokenize_error_jython.txt,sha256=9xJsjEbj5ecVkgMxsVKGzJ2rLv2v_KY3DsMv2vfEME0,70 +pylint/test/functional/too_few_public_methods.py,sha256=zHtnLo7CPWoL_hu33Eq0E9iOH2yYOo2n6DAESsLyDS8,934 +pylint/test/functional/too_few_public_methods.txt,sha256=y23j2fdq-ftt6lY8Ubnd1pAKpLm8NOir_zJ8JYJuSHY,59 +pylint/test/functional/too_few_public_methods_37.py,sha256=VwAN-JmpNYqSRAx4MFmP_uMkO8gVmMJuLVPnNWnGL6I,374 +pylint/test/functional/too_few_public_methods_37.rc,sha256=8Mf5ZLn89xee6ydJTQzp-2rPCW9iMXS3leoD3ByDfIk,27 +pylint/test/functional/too_few_public_methods_37.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/too_many_ancestors.py,sha256=pSF-ZHyNTI5eyrGTFG8ooHH4RAjOldQZghxY3B-jXgw,465 +pylint/test/functional/too_many_ancestors.txt,sha256=V8duMD7Zuv7k15FmmESqnOAV1InMaJBokggbZuphibI,104 +pylint/test/functional/too_many_arguments.py,sha256=MgG63IcU1TOjQIYXO2dMtimQ11dJDMdAoo7WAWdDLaE,392 +pylint/test/functional/too_many_arguments.txt,sha256=m3vj3OJ-88c_SCyi7XSeBDpYAy0TtvaXtlAAB78jNpk,62 +pylint/test/functional/too_many_arguments_issue_1045.py,sha256=c2myDRZdsA4rAhaIPzlzNpgVkOLFl8NPm8ehdOG2hjc,195 +pylint/test/functional/too_many_arguments_issue_1045.rc,sha256=Fcv0l2LYtPo-AEHGNVfKmB-QDZzJb6DcBfxLhmsEfT4,27 +pylint/test/functional/too_many_arguments_issue_1045.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/too_many_boolean_expressions.py,sha256=3FRmSv_f-tDTdPjT6pMFQpfxqzfMO_zgLAaExrWj58g,726 +pylint/test/functional/too_many_boolean_expressions.txt,sha256=VCXjktl_QY9YigOvsaZYR-d5M5sf7tCaplyWa5nco1k,335 +pylint/test/functional/too_many_branches.py,sha256=OhukoagR6xY7dOQrpWaqYrPdd14SISoS9ndfOZys7nI,1099 +pylint/test/functional/too_many_branches.txt,sha256=LA6PkOkEzBsbSHLYaQrQiLzVbI0vvPHFsPseLG3fcbw,52 +pylint/test/functional/too_many_instance_attributes.py,sha256=H91MAL0xfNbBlgonFG_BIDyq8UdUwueMxp2TLka_VG0,646 +pylint/test/functional/too_many_instance_attributes.txt,sha256=S-deFzCUiWhjmbHC8c3wW_x6rtGDS-4_UbVh74NCAN4,72 +pylint/test/functional/too_many_lines.py,sha256=nyGb-XuFUQsQKZ1TEbXi5HYnIC7XthGJeulaU3xdGRU,1110 +pylint/test/functional/too_many_lines.txt,sha256=yGN2XL9uHXRFFAcAD_eJyww7o1lOhlayzW9eevEYZhM,54 +pylint/test/functional/too_many_lines_disabled.py,sha256=2M_KHE_l4J4T2ky7IEARAzAWFOG7qHEqYDXA-ews4Uk,1147 +pylint/test/functional/too_many_locals.py,sha256=QmbnJb-c6Cpzx5N78cYIADvVXDUuoV-cjQ8TjENbbiQ,1670 +pylint/test/functional/too_many_locals.txt,sha256=ifLowqoLPWm-s01cNunJTilGFNGc92xq5gYCf7qORf0,213 +pylint/test/functional/too_many_nested_blocks.py,sha256=DjGQoJjhIcM6FCpLIc9d-fT-njOKqRbxHj0xGCxZSB0,2310 +pylint/test/functional/too_many_nested_blocks.txt,sha256=dsYvCsdhJSebEmkGKtsylGMHs5YY8HACGvWXJHTo8Jg,138 +pylint/test/functional/too_many_public_methods.py,sha256=foH5O6mLECPSAIoZex3rcjPLxUUaeSIeoYzKzxCWVbc,1272 +pylint/test/functional/too_many_public_methods.txt,sha256=s1AuwUzkkjKc54L38kekP1ufztYU-ALKdC91wNsLUBg,63 +pylint/test/functional/too_many_return_statements.py,sha256=xL2upt0u3ms0nAyP63apy1t3VfX6kf1RqRXSAI0SnPk,825 +pylint/test/functional/too_many_return_statements.txt,sha256=scw3uuUYs0zX-FYdBrofgt0irDDCfwRoIG52sTYCEgg,78 +pylint/test/functional/too_many_star_expressions.py,sha256=wPEUnqRYUHkM80c6JLhn5l5ZZrYAmTlKpoAwJsAPhEQ,334 +pylint/test/functional/too_many_star_expressions.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/too_many_star_expressions.txt,sha256=h-U2HPDeh-vbyqhB3hlqgjMNEOUPBp-OCKQgp7tNE_Y,152 +pylint/test/functional/too_many_statements.py,sha256=jqrueobwx0md5denaI4N8x2eRAy3RvjCofF2CBF-jAs,2088 +pylint/test/functional/too_many_statements.txt,sha256=dsJNJy_kUlHI0_MkA4liWOUycUfm-ZniFbzz6VtIsZY,147 +pylint/test/functional/trailing_comma_tuple.py,sha256=o3_pOwLi53_xRPnH_4Gjgu-qpsvqym_fgwlpZiqu6oY,732 +pylint/test/functional/trailing_comma_tuple.rc,sha256=w1gw2l7KCQ70RleAiW6w871KT5QzMkDLE-3-mXj_R2U,27 +pylint/test/functional/trailing_comma_tuple.txt,sha256=ribsjRYGbnbuHcKwLOupNcut3ju0TsehRHFvpk233Ug,381 +pylint/test/functional/trailing_newlines.py,sha256=-TZnJgA-qhjHskF1x2JubcTiMyu5D23_m4Scte7pNaU,80 +pylint/test/functional/trailing_newlines.txt,sha256=E873eAZymJcdhmKvsWZ0s0R7gwqjSonsOK3cBdF0K3k,39 +pylint/test/functional/trailing_whitespaces.py,sha256=lRTfPhyy1LCwe5OD1q46LoNu0m4s3aUZqT4uzozWt9o,432 +pylint/test/functional/trailing_whitespaces.txt,sha256=VrU2dk3c8MekIdSZuI04Eet6yZffef6UIxZloVPZgos,130 +pylint/test/functional/try_except_raise.py,sha256=3LWgAFgixLT6PpLpE5rSMf5smdIS4q9Ft-tSn2FVXxo,2095 +pylint/test/functional/try_except_raise.txt,sha256=g1JTl_o9jQNGsOnGNPCzaIzWqyN5yHB3IGrPsiJdS9E,416 +pylint/test/functional/unbalanced_tuple_unpacking.py,sha256=ABpwtHhZGpJSg0ukh-3-QnPNAyQC_FmkfwSM5Ayjr-8,2846 +pylint/test/functional/unbalanced_tuple_unpacking.txt,sha256=c_fjKw3EALU2hjlen-CLTCh9Ajo97mkQIFdxyQZkNFA,1007 +pylint/test/functional/unbalanced_tuple_unpacking_py30.py,sha256=3uKdn0HE6KhrXFhh_zlsOVN4ZPc4AHisLkr9z9_iNi4,292 +pylint/test/functional/unbalanced_tuple_unpacking_py30.rc,sha256=202YR06iDdSKKr77PzmwvnZQFMSJgHMbe6MIK2FcSvI,28 +pylint/test/functional/undefined_loop_variable.py,sha256=gqdnJTNrLSelHkyPlraG83hhXMXsYrJUMKUpvrAaqik,1345 +pylint/test/functional/undefined_loop_variable.txt,sha256=_iHK3tL0PukOt9pcYaODHZzRO4-KjBrIi8xePbWn8mI,256 +pylint/test/functional/undefined_variable.py,sha256=8mbZaHI8Wn_-rxWuXkYct5dyziE7IkN6eabyjlQv6FI,6036 +pylint/test/functional/undefined_variable.txt,sha256=w2IznXk8WKWTb2rvtmdNhxpztPddEJQSaYBnx8dhh4g,1794 +pylint/test/functional/undefined_variable_py30.py,sha256=6pFpz5Yz9zYfjlainpVcU6PRzpxLD_mtwo7E6RnjMSA,2360 +pylint/test/functional/undefined_variable_py30.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/undefined_variable_py30.txt,sha256=bDedZdLcxNyBQOkxfzFQgS6ASU_vDJMKCAdnCtvt5u4,578 +pylint/test/functional/unexpected_special_method_signature.py,sha256=7wBlNf1MGPm8xMwlaYtoMVM54SN8meIVQg2AHmA9sgw,3225 +pylint/test/functional/unexpected_special_method_signature.txt,sha256=z88AMVG9mK9HEPZEPY9nKrjYw7CSPx9wc9cjZXdP9sw,1924 +pylint/test/functional/ungrouped_imports.py,sha256=rznN9zgHJdyDu0XgrkyG2q-dW7zpFm5Cb-DUhnQXjYQ,583 +pylint/test/functional/ungrouped_imports.txt,sha256=6E_ea4zhXAXQ0mG0WVjFbCPR0l1sb0f-Dtsb_CBejKc,324 +pylint/test/functional/unhashable_dict_key.py,sha256=E-t2hyUOfneQ2Q3shU7ajhJ3VKxqXBj0Wn51STRWfrc,340 +pylint/test/functional/unhashable_dict_key.txt,sha256=6VMjSy8CUCi_z6nbL-R5apAfasaOvwjwITlzaNNl3_o,138 +pylint/test/functional/unidiomatic_typecheck.py,sha256=3LKprMKKbR6_hD-dyMhln4xSm19oEb3BmcXqF2Z7Gds,2501 +pylint/test/functional/unidiomatic_typecheck.txt,sha256=cWm8_PMJg_hasG2V23Q9W8LDuLwyZqLptJ_FywYzsAo,1842 +pylint/test/functional/uninferable_all_object.py,sha256=IPrd1nwVXa7iHt53IBdrJbHEJYxtBhJoa6Rd-0Wg6H0,182 +pylint/test/functional/unnecessary_lambda.py,sha256=9mU57pecmIHYFWRw5c8bacoTNhS4Qi36irtLbVJW-QE,1758 +pylint/test/functional/unnecessary_lambda.txt,sha256=0wXfNAn3ZV6IsfD94eRPre9e3GnfetQQVGkwwIVQwjo,412 +pylint/test/functional/unnecessary_pass.py,sha256=K-414A-oGFAveA1AIjk3ftIta2KQApCtOlFTunO6kTM,1147 +pylint/test/functional/unnecessary_pass.txt,sha256=Brp1LVxUbpKsKvWVfHt5mO_ClNM31yMu2VEkeg82yNA,177 +pylint/test/functional/unneeded_not.py,sha256=MGwAbp_ohpU32RghQnziobgXlTbO4s05nfdN_w1co_w,1686 +pylint/test/functional/unneeded_not.txt,sha256=cHqvA9cO4iDYrLvesfVBp4J8-t5gthlNTsGlXFw5mKU,1204 +pylint/test/functional/unpacked_exceptions.py,sha256=459w4qDgjJFCXoHNrIsF8SLPMAKRDVilUV9jykOLyoo,501 +pylint/test/functional/unpacked_exceptions.rc,sha256=1Ui9f0fEwYM26SWw2YUSCQ0vyx4XIUZ6o1AYLEMQUiM,62 +pylint/test/functional/unpacked_exceptions.txt,sha256=aG1rsBESNpQcIE-Puat1q3FSnwVPOxQlfE1Hr4XA938,389 +pylint/test/functional/unpacking.py,sha256=PbHZvelcTD3FBKVXWHteDvjDNj-hDLeQc8UZk0A18Og,245 +pylint/test/functional/unpacking_generalizations.py,sha256=mWcDdEO9Nl0DHtXiKX5Z4yhXwGOnu2s1pFphhhpieC4,1052 +pylint/test/functional/unpacking_generalizations.rc,sha256=dP_Zfqp4xaJCM9jhYtOqNIbxRfpn2sV_Sny0wLYzPvM,27 +pylint/test/functional/unpacking_generalizations.txt,sha256=f-62StOSqCxKUdXp0F7gEMaz6-BZ7dgyi0f325J_NRc,470 +pylint/test/functional/unpacking_non_sequence.py,sha256=aXoWMZ6V-zfLH54Q_qPt6oJOv0sqysITdXWvnrzmTDM,3867 +pylint/test/functional/unpacking_non_sequence.txt,sha256=x6FKpOWuI8omHqJ4q0za-AmQaqjeU4uqXqRdJa1cZDM,819 +pylint/test/functional/unreachable.py,sha256=ZpuPs_VkoXPITS3yNOStgrht68B4TmajvLY3sKyLTVw,413 +pylint/test/functional/unreachable.txt,sha256=n6dsLv-zbZZnpNWY3Q2nS2a-aEQ-GaDnv1F67ctUdlQ,153 +pylint/test/functional/unrecognized_inline_option.py,sha256=YUkJGozlv-vzXzEVuvcBlinuenOzs5ek2gLKQbAqdXw,83 +pylint/test/functional/unrecognized_inline_option.txt,sha256=ki9I2as1XqAN0k97p9v4nJYhxZJ9GFExE8ehPpjPcTQ,68 +pylint/test/functional/unsubscriptable_value.py,sha256=d3T94NAl5nBiKKwI9PeyP4j1kSlWgofKc8GRFPpV5kU,2647 +pylint/test/functional/unsubscriptable_value.txt,sha256=w0fUb5IPQ_a1AD91XdMxVQGmzB9qYhH-hSa3tw8QzGI,937 +pylint/test/functional/unsupported_assignment_operation.py,sha256=jmjwuaNZJpDvCvLSUtEouSKJXQ0L6_ZOZ1GLU43lp48,2613 +pylint/test/functional/unsupported_assignment_operation.txt,sha256=xc_peSddlYFftfn2G6nR1MBPCX-wSwhmWzM0g94wtnU,1443 +pylint/test/functional/unsupported_binary_operation.py,sha256=VH-D0JFsxnWymR3vrJv5o6oJjDCZn1njNxuNyfNGgWc,1930 +pylint/test/functional/unsupported_binary_operation.rc,sha256=-Qtj7IMkZ2dukjJILUov-9yFx1y6oKfRzoL7MG_WRB0,28 +pylint/test/functional/unsupported_binary_operation.txt,sha256=D_HZ2sFm0GyzmniLuI3iHt8YUfSm-I73WEXCVXrNle4,1858 +pylint/test/functional/unsupported_delete_operation.py,sha256=QhL71BBrgPt0hM5xUrlhqAex5MMRn1WtjDSF2T2Gjyw,2467 +pylint/test/functional/unsupported_delete_operation.txt,sha256=M3AbjVG3QzasYAn9fzvLH2BVOsZmbUWY9pkGog7iZ7w,1341 +pylint/test/functional/unused_argument.py,sha256=X0GRu1l4ZOV5mANa6nk_yVSPDNecCDzwIjQaAcY37a8,1333 +pylint/test/functional/unused_argument.txt,sha256=jqKivoBe7lS63ACeB7Hgi0mvhMB5tRKYqG6EqNvvJT0,174 +pylint/test/functional/unused_argument_py3.py,sha256=f-2fhwfKbmV2LCIzeDlUb6iqZ2V37B9XTe3Gy8cF3gs,111 +pylint/test/functional/unused_argument_py3.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/unused_argument_py3.txt,sha256=KZVtlIcc2QlUIFU8Ceaj7Lq8uQsBoI3EN9I_8_ztCiQ,94 +pylint/test/functional/unused_global_variable1.py,sha256=BoBJ42mzcJOfuXr4fCt1__KOnfXEpse22P-a3XPwTZE,51 +pylint/test/functional/unused_global_variable2.py,sha256=M6LXhBryq3KpyO89YunIZDUd-ZHhq95QcBVz-unCwQk,72 +pylint/test/functional/unused_global_variable2.rc,sha256=hlRljr4GLlxJCa0TcCyE1PTXvZE1eoPDSnpbRDQ852k,45 +pylint/test/functional/unused_global_variable2.txt,sha256=WOs5R6bQiGFe6gI71sIQsw_K5xIsnTA1Uk5YKWuHFk8,46 +pylint/test/functional/unused_global_variable3.py,sha256=Tfj_o1QXWjPCt7Bgfbxrlmn2LZZ4Qw6wgRb3I7ZUfso,99 +pylint/test/functional/unused_global_variable4.py,sha256=MgLDnzlBc4tz_j3zDTb6LxaoRW6EK1mqUSWCIbV1MnA,109 +pylint/test/functional/unused_global_variable4.rc,sha256=hlRljr4GLlxJCa0TcCyE1PTXvZE1eoPDSnpbRDQ852k,45 +pylint/test/functional/unused_global_variable4.txt,sha256=dUK3gfpyvN_5prjVZL5MoWSIJivpIHEitHUuNOjvqlc,92 +pylint/test/functional/unused_import.py,sha256=XGryC72q3IcydsDbHDRvBuwpRAmBCMGrDdnTOF1ASIQ,1058 +pylint/test/functional/unused_import.txt,sha256=RLa2vlRAo9SC9WQ3DwhXOqqZgcC5rjZhk7OoyHSYQdQ,409 +pylint/test/functional/unused_import_assigned_to.py,sha256=9MrMI8JVHZvX_4HWJBNgYWH_YODspUXFmh9vJ0WlFfc,426 +pylint/test/functional/unused_typing_imports.py,sha256=cT4B7FTcnqgaub57AlA2J0lLWa39-mNIn6_UVfq3AkA,889 +pylint/test/functional/unused_typing_imports.rc,sha256=_5mxQ4I63U9ZICdOtftczAEO-ueLOMsA8bDqp7ePKOw,41 +pylint/test/functional/unused_variable.py,sha256=1z0rmQ00FTWpY5qT5JoZqfJA4gj7oCO650mV_HVW0cs,1326 +pylint/test/functional/unused_variable.txt,sha256=3SpP79gsmQfo0GPMMV3gPpMf-J-XuH4m0hlEVnB7a-Y,924 +pylint/test/functional/used_before_assignment_488.py,sha256=h4qxXkGWrPzxKFrypFQap24RT59qrLRopYy-iACOxMo,251 +pylint/test/functional/used_before_assignment_issue1081.py,sha256=N23VeAVP36YwIs5sifDWs8NwZO8z8z2YnI2DRg4_3tE,785 +pylint/test/functional/used_before_assignment_issue1081.txt,sha256=meGmlO4our5s_H5kudp31iZDfy4_DOpNUkHy_9d1u2A,646 +pylint/test/functional/used_before_assignment_issue853.py,sha256=udkPAzNTh-6PCPxDh3ahfxMkTXAIIolDpQNvK0JA4S0,520 +pylint/test/functional/used_before_assignment_nonlocal.py,sha256=bXgwyYauDMdeP45DO7P3UFY80OiE9rYvSK5bn4W5R_o,1464 +pylint/test/functional/used_before_assignment_nonlocal.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/used_before_assignment_nonlocal.txt,sha256=bSYebxOj2GjHwyDWv6B8rET5pPZZefMOVWUXdjzLkVU,496 +pylint/test/functional/used_prior_global_declaration.py,sha256=FoWdOiFDhdmaOFDIWmAh2gLvY-ZlqKp0sdtobTyXJME,484 +pylint/test/functional/used_prior_global_declaration.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/used_prior_global_declaration.txt,sha256=7LEbeHR05qFtWqI1tAttAN6aaUOfANwDLu5ch7skw1c,85 +pylint/test/functional/useless-import-alias.py,sha256=YvqOhmG9I5mFplgC2YK3VYldRU66yAwU7ymyIg2blXQ,960 +pylint/test/functional/useless-import-alias.txt,sha256=zG0g2HlP7kVjBuTm8ay1Lt5F1oXQ2V3B6RWdISfj3Y0,636 +pylint/test/functional/useless_else_on_loop.py,sha256=v1PB3dyIvF2OVwyORQP_uySLVKAyclRzp4OovQ-1_KY,1963 +pylint/test/functional/useless_else_on_loop.txt,sha256=a4eCOeCtgYP2fDUf896hxQy_XAYLLpo69oekqf1iScA,484 +pylint/test/functional/useless_object_inheritance.py,sha256=luBNfgeu-7T0VAYs4DIS3VKMx56FgJi5yaznw5zaIfc,696 +pylint/test/functional/useless_object_inheritance.txt,sha256=bAASp3y7TOxjRAvXwgrrUKZMQebwnsU6wsHWD6_bXo4,431 +pylint/test/functional/useless_return.py,sha256=8vm7qIj5ZYFBYPqtyc7qBI-ypQXIWVcSkZQRF-E4OD0,424 +pylint/test/functional/useless_return.txt,sha256=NsytToRRVczLTe_oZdnBZQL-ta1bKwukegHzqfNCGEo,148 +pylint/test/functional/useless_super_delegation.py,sha256=7aK8Epi6GTXlvsnAhToTFD30KeH3TVTYBTu6u9BXkJ0,10529 +pylint/test/functional/useless_super_delegation.txt,sha256=wLaVHBIigDdt2Z0glT3EP1TbE8Vyh9e7B8Vd4fa2pLM,2055 +pylint/test/functional/useless_super_delegation_py3.py,sha256=FaXr8lYjdaicQPLb_2GNuOu_EGaq_PKnyK_p_-LcmZ8,1283 +pylint/test/functional/useless_super_delegation_py3.rc,sha256=150tvkePYDrY4pNpvhPlBbubWg9zzGQuKHzkBgBDgSY,28 +pylint/test/functional/useless_super_delegation_py3.txt,sha256=ORJ2xFrad17EMei_9PKgSOHR3ybddwPKzukHXM6a_k4,181 +pylint/test/functional/useless_super_delegation_py35.py,sha256=9MAGjVfMLQGge6rqzO_wDIJP4nIhnmRqZupneluKtqM,510 +pylint/test/functional/useless_super_delegation_py35.rc,sha256=5wJVJR3wPbQJphqFa3SY8a2m0Mro5K4mz0rCpCaI4Iw,28 +pylint/test/functional/useless_super_delegation_py35.txt,sha256=iNSZdt32cG4ASBNN-HqQSrucEwf6mluWHptImJZiJps,93 +pylint/test/functional/using_constant_test.py,sha256=vYcK1qJDJmqAt8ppFHrd0is6z7_2k3n-zUusnzxr7UU,2677 +pylint/test/functional/using_constant_test.txt,sha256=MXsYkE0SpqZz3vI_07umsS30GBuOHW56Jf2ygfq2WpI,1786 +pylint/test/functional/wildcard_import.py,sha256=oqCLGv3UbrWkdvMfLMhiF3GqIVspLyYXeZEz40e0LNw,269 +pylint/test/functional/wildcard_import.txt,sha256=6Suy_6rvdnjTiZRMKmNm5UE7IKl59GiklzUcb78TOpY,96 +pylint/test/functional/wildcard_import_allowed.py,sha256=fxbNO2870CrxMmqL4WTC8zxVw7mQ3hWi8300BP4KbZs,194 +pylint/test/functional/wildcard_import_allowed.rc,sha256=EjDp_xNkb4LOFw-4qKtOi2ADIWrKo1-nCHZk98iDJ-k,38 +pylint/test/functional/wildcard_import_allowed.txt,sha256=Xl2EsvBkYMR3l4Xa4RrUfOQMhH7iED6ru3WHhif_hHM,96 +pylint/test/functional/with_used_before_assign.py,sha256=KmGxtJcQp_juBqyoK_KE4FCoYE7aA4WCC6FV1F66t6w,304 +pylint/test/functional/with_used_before_assign.txt,sha256=glE02ZV92Fp-wb5rqbDNQWA3nXNkeOBeJAMugOxA6eg,137 +pylint/test/functional/with_using_generator.py,sha256=DEZpZgdvFlMzcCF48naILF6L-9kw-tJvGkaDyNNc-Jk,387 +pylint/test/functional/with_using_generator.txt,sha256=kU9m7rpdvbBOElCJue6MftBgSbxC3iXOuDR9i1_lr78,102 +pylint/test/functional/wrong_import_order.py,sha256=mrzXiqziOfZ_iVkJPcAj1W0yZRHb0zFZwst8Cp_Sti4,1096 +pylint/test/functional/wrong_import_order.txt,sha256=E87NkcxyGustO8KjudRPwNM3-BZf59eAxse9ugJk24U,634 +pylint/test/functional/wrong_import_order2.py,sha256=YHVkcZ2U1hWC3qfR693NugGJWojEH-uzjs3DB1zd1Hg,326 +pylint/test/functional/wrong_import_position.py,sha256=EuPe_MAUwZthA3g-Pb08IvPk5QdhOZ3s4kHlRpTcgBI,805 +pylint/test/functional/wrong_import_position.txt,sha256=snOLX4pAL42YWxml0u1D34HUqaJM6d4jSaAv5Ho6NUM,363 +pylint/test/functional/wrong_import_position10.py,sha256=f9Kscbp8P-an6N7_8NoqTg_2WO8ApUHVVJxAUUvYz8w,268 +pylint/test/functional/wrong_import_position11.py,sha256=5K54ErI1YAtc_AZzGnXOwOncJfSAsZ-ElvwWWwMrW0Q,136 +pylint/test/functional/wrong_import_position11.txt,sha256=qV7Gr8UtZPHGr35Xr3TAJERzXyiGDOFRBO4IfKljBnk,86 +pylint/test/functional/wrong_import_position12.py,sha256=ImHhtfLLYX-Hb3A8Ed-rl7CliNLZlcB7FspWKE-RDN4,144 +pylint/test/functional/wrong_import_position12.txt,sha256=KBRL0_zQ53uRMqkuOM81JB8oaDCds6w09Ht5-Bd9zo0,86 +pylint/test/functional/wrong_import_position13.py,sha256=ng2XxLqKS8U2bMpa4wS7AM4gZL5K3ZRX9PJMlYojoYg,135 +pylint/test/functional/wrong_import_position13.txt,sha256=URrtOxehsz0QlG-VVywJFQYmYWBky3zvf6nQtmRnoz8,94 +pylint/test/functional/wrong_import_position14.py,sha256=xMlw1sEAJmMjbPXfpT7xqi2Rajq1JSm-OI7t03Q40Yc,154 +pylint/test/functional/wrong_import_position14.txt,sha256=qf7MBVBH812HaaCGdwiibR6B5HpAKHfIG_5m4KEUGpk,85 +pylint/test/functional/wrong_import_position15.py,sha256=DtBqoxhrgbvVRbD8is9VmFmtgml3SFI7pPtMWQOQ2uM,191 +pylint/test/functional/wrong_import_position2.py,sha256=hPcqr-LrQV5h2y84MmzeYlLZIP3V7TUGwE75xjYIBZw,271 +pylint/test/functional/wrong_import_position3.py,sha256=Mn0W8GcD62O-Ngiu2Y0RShm2-iwQMT65Mm_rZC6GLT0,167 +pylint/test/functional/wrong_import_position4.py,sha256=_GKdafr3wFQRXlH_YCoXttyY8AO0rQ6tVsTo77ZeiOA,220 +pylint/test/functional/wrong_import_position5.py,sha256=6IZFtY6tM2c9ztRQlGaERBphcOWgXAY6K48wX2LocpU,169 +pylint/test/functional/wrong_import_position6.py,sha256=kzXJIorZjFd994pwkMQh5DbYLCOm1o_FOYyPRCrGSI4,207 +pylint/test/functional/wrong_import_position7.py,sha256=jusPAw3GWElaeZ_4JckloP6x7YR1ZXOjyz_suWA5Qww,231 +pylint/test/functional/wrong_import_position8.py,sha256=Hk6pRcYEmKoaQIX6EGmU_5veOm9sthA4Yg64-nVde1U,196 +pylint/test/functional/wrong_import_position9.py,sha256=CztZCuTzxmDDtIdrq2gGjTXE63OalY2pPEnz_WQI6UQ,228 +pylint/test/functional/wrong_import_position_exclude_dunder_main.py,sha256=4O2ORUsw9eX7RmusjGWzNxFe_8QvNdwM4IMOlfaPSAc,231 +pylint/test/functional/wrong_import_position_exclude_dunder_main.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/functional/yield_from_iterable_py33.py,sha256=G4-SKpkZjmRAN7vvAx3r4K09IgX69BwUU19zp5TMK-M,151 +pylint/test/functional/yield_from_iterable_py33.rc,sha256=pXXfuVMn34DUN8Sx8RCxHwz7tGJvhC_EiDB9nCV1K1I,27 +pylint/test/functional/yield_from_iterable_py33.txt,sha256=1N_DG1ZonqbPC2IKMvkpqpWpQLNNqchjGFsz1GzVmoo,80 +pylint/test/functional/yield_from_outside_func.py,sha256=rkPouDgTdB3QtgvXabe4OkX7TEvbLg16e_6ZDz_NY8Y,160 +pylint/test/functional/yield_from_outside_func.rc,sha256=-UtgKsZ7MAhyWMpJ4JTEIAbPt-k7kBfGYqFdShs4Rig,28 +pylint/test/functional/yield_from_outside_func.txt,sha256=maG1ODwvlUu5IpSfRmGE559CqOVhbtCcRtWgpzB_cho,49 +pylint/test/functional/yield_inside_async_function.py,sha256=QxG5RyIAGCq4FrYtrI9x5m2U4t44pg3asHVDHaLIhP4,359 +pylint/test/functional/yield_inside_async_function.rc,sha256=SAVP-58s0BF4-8goPuDjRhSgKrdNAkSh2Rm8rsJa8kQ,42 +pylint/test/functional/yield_inside_async_function.txt,sha256=g9xkrjBXP48vDFA861NZQs2DChgsxsAFFS0mEkXkOJk,135 +pylint/test/functional/yield_inside_async_function_py36.py,sha256=g0BoT8V_abwtAvAPUBI_mXeOWe8ce6ZAaWsxTN9qExg,327 +pylint/test/functional/yield_inside_async_function_py36.rc,sha256=yjVnS7KsdPAfx0L2OmHyEwoCnA1gaG3Ii7dmcDBvLy4,28 +pylint/test/functional/yield_inside_async_function_py36.txt,sha256=6kBiye-By2K_k7VaBrH08MY3ilvd85w_uxhRHX60Z0w,68 +pylint/test/functional/yield_outside_func.py,sha256=dH0JygtvTf8Fgrb23JoK_kOFczrn0OyX7S72YNAN4GE,138 +pylint/test/functional/yield_outside_func.txt,sha256=maG1ODwvlUu5IpSfRmGE559CqOVhbtCcRtWgpzB_cho,49 +pylint/test/input/__init__.py,sha256=JWw6epNeSwj44bUSjyXvMvDUISceb1HJMIKrGFm855Y,11 +pylint/test/input/func_3k_removed_stuff_py_30.py,sha256=cSeFsjam4k1_fc7CdtduNB4EuC3CR6duKBsnKhmPpfE,289 +pylint/test/input/func_bad_cont_dictcomp_py27.py,sha256=GciZFGLpJaPxDHk0jOUUiEoDe1TQ1DAG5HKgYm7SVsc,1003 +pylint/test/input/func_bug113231.py,sha256=MmDCZaVom_qo8f5yh7l5W3MFejsRkSS2NIElX6dhSeg,605 +pylint/test/input/func_disable_linebased.py,sha256=O41FmzF_t1zE4obmeNy8e_rRFM8T-RGS1lgd43USeEA,705 +pylint/test/input/func_dotted_ancestor.py,sha256=FFWgNOmSHll5hfn2JHW0IWRL2L_bV1iBRtBxezFvoR0,231 +pylint/test/input/func_e0012.py,sha256=aexrTeW7f0q6SrqLQ8fy50fSJSlbzStmfiSaiNeYdiQ,68 +pylint/test/input/func_e0204.py,sha256=IQKQo3EbiAgMbtuThKrjlceE8aJCp3lL8_gQ41WjbRc,428 +pylint/test/input/func_e12xx.py,sha256=jab6hlU3izL0GrNgPELFUxB0LLiG0vNL0_5eCMV6OeY,660 +pylint/test/input/func_e13xx.py,sha256=UclHuCch1QjeCm5kH7HrKGG50BnIZZj2I6PFqbVbQYM,785 +pylint/test/input/func_excess_escapes.py,sha256=e6OnK73G4eCjegI_mvI7iizOjg6GmxKuf6KuqM1ityk,716 +pylint/test/input/func_first_arg.py,sha256=bX2lMkyNhDUuKpYTrGmZVBPpPh0V1k55rY4vFMCYiWM,751 +pylint/test/input/func_i0011.py,sha256=xi3TIyYRCgRfCE2XX0M2r8UpyJ8NlXwy8g7Kg-AKBa4,80 +pylint/test/input/func_i0012.py,sha256=WQjKwryDXFAWLU34SEl0WIvxXG0nMsJU5SEA3nUS7wE,78 +pylint/test/input/func_i0013.py,sha256=kFeEiR4fElVVyZaPNf1DbYq-UfriOkXXAPP4VKnFfKE,137 +pylint/test/input/func_i0014.py,sha256=dWvkyuNBGA6l39N-xBD0kYoZe02JvFSXSpErDS30_lk,139 +pylint/test/input/func_i0020.py,sha256=Hy2w0DJ13QFSU0tKlS-mquOCXudj0441fEumHBXrp2s,172 +pylint/test/input/func_i0022.py,sha256=2P9DfZnFFV7KhYUKS_0jCnGXDFtlHoc2bQI08jmoOdE,398 +pylint/test/input/func_logging_not_lazy_with_logger.py,sha256=JcS621qB9Ms4Mr_SGW487q577A97dtnl4YdW84aFRXo,303 +pylint/test/input/func_loopvar_in_dict_comp_py27.py,sha256=f8iQkgHJLLWoY5d_uMksxg3Mu9wBmvqdMVwnX6QAQso,166 +pylint/test/input/func_module___dict__.py,sha256=PrqEJVBExXuz6zMU6bKDCRhZOne5dtl3sChJn-dH_gY,173 +pylint/test/input/func_nameerror_on_string_substitution.py,sha256=2Pj9KU3pdeQRqrErR-D_vB8RozjMeKhgwdQ5YS_n_gU,135 +pylint/test/input/func_no_dummy_redefined.py,sha256=R4mCMtO-V96Y5v4CIaU6Iaem2gGbo6NBRVZbYJqJqq0,299 +pylint/test/input/func_noerror___init___return_from_inner_function.py,sha256=f1XMdamknBTI-EhnxK-xXDMybFcRSIv1j2FP0XYaA1I,276 +pylint/test/input/func_noerror_access_attr_before_def_false_positive.py,sha256=5yNQ9a82RIOOE5lCZnDpl3Wt-UCyv1KgLgxRywIk9uQ,2515 +pylint/test/input/func_noerror_base_init_vars.py,sha256=knpuIP4CMCGEen4OZ3ZDR885QQkzageJwr1BkSDuhGg,800 +pylint/test/input/func_noerror_builtin_module_test.py,sha256=nL6fIEU33gCcL8uKl4DyOfaXjv1eK4HP622arg1DHjY,183 +pylint/test/input/func_noerror_class_attributes.py,sha256=RAai7khPR-0iNyAQWVwtkqowxeKUR6u-3PH90KQVkhE,434 +pylint/test/input/func_noerror_classes_meth_could_be_a_function.py,sha256=737iKjdysDWBwIjU7sKZmUzNTo4rs7uRuFaffBMu3XI,691 +pylint/test/input/func_noerror_classes_protected_member_access.py,sha256=MM0ltQMYgXSbsCVCuRd0mjkrKyOr9SQLCEv8hPfByKY,559 +pylint/test/input/func_noerror_decorator_scope.py,sha256=yV0X3TyVonAUzx9lyZW-ovcSRXNPxoJg_Gza2dKlh5Q,570 +pylint/test/input/func_noerror_e1101_9588_base_attr_aug_assign.py,sha256=QdgS5sNqb6mdDLfpduXfRV2PJbWxudq9IRsO0EjNmAA,1019 +pylint/test/input/func_noerror_external_classmethod_crash.py,sha256=C20YeFcVMndWA6g7TJHtVz2dq9dmeRMNLeXuFYi-Q6s,523 +pylint/test/input/func_noerror_inner_classes.py,sha256=l-5gl1yx1VFTA1Vxjf3vI9enRiDtVMVBL-p2iNhO7-E,576 +pylint/test/input/func_noerror_lambda_use_before_assign.py,sha256=oTsL2krAzc0osSMGJWQJizP7V7cUYkXpouNTDNlPVss,183 +pylint/test/input/func_noerror_mcs_attr_access.py,sha256=_ufW2O6QPWwVEQV_KZe5ZyYK7Umx3hDldTLae4n20n0,539 +pylint/test/input/func_noerror_new_style_class_py_30.py,sha256=6oUiHRdPdNAZ777GliGtVwP9KDDvdgXJlqhQZ9Xl0aY,1247 +pylint/test/input/func_noerror_no_warning_docstring.py,sha256=a-9LsdGavwK1-8m85EkJv-Q_vyL5JHSXvctvZT8NZ1M,954 +pylint/test/input/func_noerror_object_as_class_attribute.py,sha256=D7h8ATgJWwcniiXJBH0BJkXX4rbXVnNFoq4FJabXFSo,501 +pylint/test/input/func_noerror_overloaded_operator.py,sha256=nZ5FLw-RdUyTYVgvx8KISXg-PBAJC-FVR40xfTZO8ck,480 +pylint/test/input/func_noerror_property_affectation_py26.py,sha256=oqd8CidpB6Oo0iFVY09Ud2RI2P0O4DUMzS2To-WC8vo,489 +pylint/test/input/func_noerror_yield_assign_py25.py,sha256=7udES9eFAWAz_JdPAGbXTVtFOMdPsDcBUkYZO8HJmLA,387 +pylint/test/input/func_noerror_yield_return_mix.py,sha256=OOEx5M4ScRHnyNInXbS9YEHsVAVWMNrz9ja0vH74Ppk,144 +pylint/test/input/func_nonregr___file___global.py,sha256=PLPHNbZcVqNv-39ru0cqdPCpNTmMCZ1g-Zx_ZgWjstU,145 +pylint/test/input/func_return_yield_mix_py_33.py,sha256=Lw7dV8xNkP0D7m-vJGv2su4nmuqQd45hQD8AdTqfMCA,353 +pylint/test/input/func_typecheck_callfunc_assigment.py,sha256=Kr74H1ObicUmr4_bPVHxNPbLx-zQzzR8dJwI3Shr1pU,1514 +pylint/test/input/func_unused_import_py30.py,sha256=W7_OK9EgRL4aXFFDC-wWHwgLv-YhDdvCnTK8qfQtLwU,470 +pylint/test/input/func_variables_unused_name_from_wilcard_import.py,sha256=EagRgT8SXD3tNm_rpWC51cHKyfbZIpIJikxElHNjA7w,117 +pylint/test/input/func_w0122_py_30.py,sha256=AK2_t0jfrajFbipryUICOfrtaVyNuBR_m_Nj5JB5xkM,177 +pylint/test/input/func_w0233.py,sha256=ACgsNS29oePxbnD0g6S_QcbjOAv4k3J2lWE_Sg7KaqI,1385 +pylint/test/input/func_w0332_py_30.py,sha256=nfkbZ-A7_HALZyQrNgUnYNwixz3yVbM5EtmHQdftaAA,89 +pylint/test/input/func_w0401.py,sha256=S59GLmrFuYbsHEAhUSV3253p1WRN3DQhp1rdQvS31GU,168 +pylint/test/input/func_w0401_disabled.py,sha256=FE-dqhh6ysPn1388mL6LScKkFTFdrbrdafp7QE8hiXc,201 +pylint/test/input/func_w0401_disabled_in_func.py,sha256=zNrvXQ-JdlxdKjoS-JJGXJkKtK8ybRmZ3XQ2hj5v6wo,328 +pylint/test/input/func_w0404.py,sha256=kyQzQxT0T9aYjrhktxmbfMj6wzgssKErFsUiUWUEZ9s,532 +pylint/test/input/func_w0405.py,sha256=HaGwxJzAc0SndiK8GTo6cv5ab65QjYwznAP_VxqVH00,606 +pylint/test/input/func_w0406.py,sha256=GInHREpHPK86vSH-SA5-7Gh_G2fa3JiSgfGkWlu2Nag,214 +pylint/test/input/func_w0611.py,sha256=ssyc0o71ze4ipZclOCs686X5awehom6YMTT6GII4Mhc,473 +pylint/test/input/func_w0612.py,sha256=r_MLa4STCC-nz917qbhXFDlww4AOqrQgswKqsvWKJdc,985 +pylint/test/input/func_w0613.py,sha256=Kb2kIXzjypsgrPIH38IdPd0ksVD0RBGvkSnwSXg4A50,1198 +pylint/test/input/func_w0623_py30.py,sha256=sCkfrCF8y9E1tpo9O8FtcwqHVjj_tJn9v5cTVvx-POc,318 +pylint/test/input/func_w0801.py,sha256=8_m42e4Cm_hgYo0M3r1Wbogb0iZBq_X2SPzjLAtFTJI,203 +pylint/test/input/hide_code_with_imports.py,sha256=06JJ53GuM7kEYCCGBBQlmURxTjPA5e1cmzA36F35e1g,1296 +pylint/test/input/ignore_except_pass_by_default.py,sha256=aOPmPV3tOG2sx0ZDkXbaYzQA50IcIzy9Ei8Srz5ynm4,120 +pylint/test/input/multiline-import,sha256=SDOyKMhdYU_hYd1rmz8DY0WbiJjFZHzga1uPJl692dc,72 +pylint/test/input/noext,sha256=mHcU4tUap6B4OmG8jq5Wcjs24P6XhER1kpkF7v15LZE,85 +pylint/test/input/not__init__.py,sha256=JWw6epNeSwj44bUSjyXvMvDUISceb1HJMIKrGFm855Y,11 +pylint/test/input/similar1,sha256=xsx81u-addWKViULjjfUSDvUrdSd-Ud4cPIsLTf6zMc,181 +pylint/test/input/similar2,sha256=CRYCvO8uA581zBLSZ0sa0KlS0bqRIy2aBezht9vb5As,151 +pylint/test/input/w0401_cycle.py,sha256=UDrGDArHjG6vxLesZ4-UbKt7WjlEcKhvla4qD3MLepY,175 +pylint/test/input/w0801_same.py,sha256=8_m42e4Cm_hgYo0M3r1Wbogb0iZBq_X2SPzjLAtFTJI,203 +pylint/test/input/func_w0401_package/__init__.py,sha256=uAsEr8agjGCEUtGgRaAGDKX7rsAYR5obzykzlZpX3Wk,43 +pylint/test/input/func_w0401_package/all_the_things.py,sha256=LjCyv-Dj0XHSQdmU9Gtd35ZH4TXTfcumcLyDffVlDJI,220 +pylint/test/input/func_w0401_package/thing1.py,sha256=2CPW2sAmzspD63HNbh_R5vgoeX6X2QPP5Wky_8uon34,66 +pylint/test/input/func_w0401_package/thing2.py,sha256=h3tg6MLVrtjCdNz06XtgtQEuQ4eHjFNu52e61qDMgYw,194 +pylint/test/messages/builtin_module.txt,sha256=iWC0ORsLaNKnOYxKFI1vBpz2fuBL4Z4pSu6jpH9CUWI,34 +pylint/test/messages/func_3k_removed_stuff_py_30.txt,sha256=_SGOeqzaAtdn3AW30pg_SQLOMmA24wYVxJbjWUM_S7I,128 +pylint/test/messages/func_bad_cont_dictcomp_py27.txt,sha256=IWqHna3-Mn8DMj-dJD-Zze9els5ek3uVbkdRV-pUiOQ,221 +pylint/test/messages/func_bug113231.txt,sha256=1bvtfICSIQee9k7be-z8eLv3WAbZ_ysAEf-_91ElMiA,140 +pylint/test/messages/func_disable_linebased.txt,sha256=qZIatt2VLU2cU_ONEhCorbSqKWjbajLdaWSeQFhV9cc,62 +pylint/test/messages/func_disable_linebased_py30.txt,sha256=qZIatt2VLU2cU_ONEhCorbSqKWjbajLdaWSeQFhV9cc,62 +pylint/test/messages/func_dotted_ancestor.txt,sha256=TQVZ4pTosXYz7Zkf58P8kUjXD8YhEZNjvHU9JiuqvMI,41 +pylint/test/messages/func_e0012.txt,sha256=vLVvgOwRXOv-RTk0MSrIXapB8S_Ct48fabwjC3lp46k,33 +pylint/test/messages/func_e0204.txt,sha256=3fpsmiQaJm8niMPrS2hkn9FtBQ3DjlWqmJYIjVgSaF8,127 +pylint/test/messages/func_e12xx.txt,sha256=N3iCmZxnqHOAV0wMWb5HWdW-_T9GEssfJEqahxINDkI,386 +pylint/test/messages/func_e13xx.txt,sha256=5N603VWmH4vD_DJ-Tq2_881LJoAvdGpUvT3Tt0cxJoo,757 +pylint/test/messages/func_e13xx_py30.txt,sha256=s_MTNDHl39JYqU24p-4hu97vyZAxi1wU1hX99LOzqsY,689 +pylint/test/messages/func_excess_escapes.txt,sha256=3DOQj_Ez3aY84C9e_MM9MhQi-HgNFoXjqJRxpD5PvHQ,810 +pylint/test/messages/func_first_arg.txt,sha256=ssUFfpXY6AMPSWN3wmUv5j-zkc2rOu1F577zddgWLpU,681 +pylint/test/messages/func_i0011.txt,sha256=cuHpEpg6uPe1YL5K-Zct7fP_NT_scF8jXOw_mNnimlo,154 +pylint/test/messages/func_i0012.txt,sha256=aE-Ff6mIEGQukqqdIynQL0gJsEn6WQfF1tdmbeYu0Co,66 +pylint/test/messages/func_i0013.txt,sha256=N7imHpFskckJvHdmMoEKxJIubLJdJVJ910i0BGiKUgE,28 +pylint/test/messages/func_i0014.txt,sha256=HYlsMki6Vzh9q5gvy96nTRXrBxQ1jbc92yqdZidlFx0,95 +pylint/test/messages/func_i0020.txt,sha256=i52DWaHb-63ED2O7aFSiKDdcfznUbk3Wj-JG2ylX11k,171 +pylint/test/messages/func_i0022.txt,sha256=q7tTkyP3Qgh7AGt4sXAfgOGh2v5OSZjkS55THimK1zw,1156 +pylint/test/messages/func_logging_not_lazy_with_logger.txt,sha256=klrXhgzwXPLtPgGr90vFokc1zElDQ0FoBQuJqpjmPv4,280 +pylint/test/messages/func_loopvar_in_dict_comp_py27.txt,sha256=Frr9svnJeA1eJoP9niRR8L2x_hZB0rjkmncjF5SOp8Q,57 +pylint/test/messages/func_module___dict__.txt,sha256=_9u7ySt19Z-w2Wef7raTRh8xMSEAPdDdZwWop5AqMjE,51 +pylint/test/messages/func_nameerror_on_string_substitution.txt,sha256=IjxnInQ4Yj6COsz0An4fa2xHTG4fqMWlfSv954oMPDk,93 +pylint/test/messages/func_no_dummy_redefined.txt,sha256=egvbSHkOLhnlISCiDmg9aL386kmKFWhZQ6B2ikGNjOk,140 +pylint/test/messages/func_nonregr___file___global.txt,sha256=ZJg1jw5hXbm3KQylzpitoTMCqVIAaNgx-wHhT6Mbp9M,82 +pylint/test/messages/func_raw_escapes.txt,sha256=V9QK3o-XRthcYr8-d_oPXKmXwtPPYk7co8qL__QVxbU,315 +pylint/test/messages/func_return_yield_mix_py_33.txt,sha256=Atgd-_2ko5dzvRH-87jJ-XqHDZHJwNgb771hvmfntic,106 +pylint/test/messages/func_toolonglines_py30.txt,sha256=Wcd3UqxQQS2D56F7z2D7PmQ_LTmjizlV9ewnJa1T37o,124 +pylint/test/messages/func_typecheck_callfunc_assigment.txt,sha256=LcMEw_lnUefm3nh6mnv9ngqs8Up4HGYKiMgHG1_0YUc,229 +pylint/test/messages/func_typecheck_getattr_py30.txt,sha256=J6Kd-q6Kk7Qn0cTMKMF0pEF3rGP59-ev_8RvhssK-dk,648 +pylint/test/messages/func_typecheck_non_callable_call.txt,sha256=MvGfdyooBcLSY1M8KcF0uqBtUKAFDeQ7XS9b409MiX8,247 +pylint/test/messages/func_unicode_literal_py26.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/messages/func_unicode_literal_py274.txt,sha256=WbjFwx65sv9clDzUsuKN6mlIkOZuI1YAfZLH_HNj-Eg,105 +pylint/test/messages/func_unused_import_py30.txt,sha256=sGBQ_e5sl_0_TpRYcVM7rpKCrTGgXUEbu-WLLGIY3as,45 +pylint/test/messages/func_use_for_or_listcomp_var_py29.txt,sha256=laE3eLqnnd6J4YcB4H4IGbpg7pBXG2Q2JnH0t3Utx40,104 +pylint/test/messages/func_use_for_or_listcomp_var_py30.txt,sha256=wA7fGpPNbmGlE28kf4Z6_eU77SM16SPNN6V2TC_LluM,98 +pylint/test/messages/func_variables_unused_name_from_wilcard_import.txt,sha256=4mXcd1cX7kyvrqe_3O-cxq7HRdboixaTVXY6flEp2X0,181 +pylint/test/messages/func_w0122_py_30.txt,sha256=a9hU-TMlF6AGu7WrxpUAOee-xjz1f2JlpkI1wrtCFUo,82 +pylint/test/messages/func_w0233.txt,sha256=4h9GxVtZyf4NXRqQcTtnBw8jdlquHfC64Ad67hqoqno,395 +pylint/test/messages/func_w0312.txt,sha256=WnCR9AJVYVtcGCe5KuCdJMEjcT8q0ebL3Qz_o9BqEw0,106 +pylint/test/messages/func_w0332_py_30.txt,sha256=iGP0Xh2Em38TaQtJtmTiQ31uGUR6zt1sOeeyFfn8m9s,45 +pylint/test/messages/func_w0401.txt,sha256=1KtOEa2qrIATOBj6j5VpNZ1kjNlkmSIq5zMlwbw9JEk,179 +pylint/test/messages/func_w0401_disabled.txt,sha256=0JuG3NHnNFk-305d84A--6IK-7yGqr8St7hd04F8P0E,118 +pylint/test/messages/func_w0401_disabled_in_func.txt,sha256=jJsyiw4r66N6ckx30KdsQXWwcq7DHrYOaHzgF6lnz-U,123 +pylint/test/messages/func_w0401_package.txt,sha256=n99C_TpAsRe6gvwSxpFdujkLJtV6pj1jZDiNdpdqe_w,157 +pylint/test/messages/func_w0404.txt,sha256=usJixqyxydmS-VzeBQ53uEqDel4T8UT7aryS618iZuY,252 +pylint/test/messages/func_w0405.txt,sha256=q-IHhL_hmSNnJdD4d1gA7VQhGjFrVv2fqAOCVRYPcZI,170 +pylint/test/messages/func_w0406.txt,sha256=6qKgGzb4Hlxa3vViBLYCTo-I9h80jBZTOPx2qucnTNo,28 +pylint/test/messages/func_w0611.txt,sha256=neC_IlW8ldp2Vm7qMfj7Bm_BNMa2ll2YD5pHsG-AV8I,24 +pylint/test/messages/func_w0612.txt,sha256=yzAyeOXP_5xav9_rmjF9NRsY3uzcZX4moj3YxXMUDbo,283 +pylint/test/messages/func_w0613.txt,sha256=6fvJSIdGvMcgJHUypVwGwKZEmDZLc4ro8FZljt5otD4,212 +pylint/test/messages/func_w0622.txt,sha256=hFI9P5EgNfAPXtTyDwBOyiFDZy9Mtdm4-4NBDAIt8dA,76 +pylint/test/messages/func_w0623.txt,sha256=DomdIPZ43UvyoHz__1Z6TtARQNjz8w3v3RoxKrawLIU,850 +pylint/test/messages/func_w0623_py30.txt,sha256=6cNiq_bwZLYY0QtxmlTFQ9PiDrxIohinMZNawsamMz4,154 +pylint/test/messages/func_w0623_py_30.txt,sha256=Rm7xJ96UNSkJJe_vEK7bDrHjkDipS1qHX_dlB-Gp8-w,939 +pylint/test/messages/func_w0801.txt,sha256=WnZxpr-QvFCLMAkasyWEIIxvIbpwNv6RfgdFRfXqSwY,208 +pylint/test/messages/func_with_without_as_py25.txt,sha256=hBetJUIrvn8rk3TqBuXURDI3EyX8CHPvjVu71QwpqG0,111 +pylint/test/regrtest_data/.pylintrc,sha256=HN8VPByaZUxW6i1dK3U0gFY_83v6Nx_k2p_mt23jxg4,30 +pylint/test/regrtest_data/application_crash.py,sha256=6zTbSymfZdQMrYukNUWiRBZVBPdC3D9aAMHe_n9U1-c,26 +pylint/test/regrtest_data/classdoc_usage.py,sha256=IXG9zZaLYnuOO66l-X977VncqNOOo2RrACqxuPntT1s,312 +pylint/test/regrtest_data/comments_pylintrc,sha256=2Pdq3kXFF_YYHzx_x964FNOmBkhAQSAG1cFThTakY7o,154 +pylint/test/regrtest_data/decimal_inference.py,sha256=JNwghNDOPTiUx8c4smBiUvWTwzvkHrMRvX7Wm2GFDmw,291 +pylint/test/regrtest_data/descriptor_crash.py,sha256=gjT-xRSDWYc-wv8-RV5wOiha3fGQnthbZzy06IRPoVU,358 +pylint/test/regrtest_data/dummy_plugin.rc,sha256=vuKgloEIeojtyQQbhCI_tU5pT_hiZrx4p_SSK_83vFw,113 +pylint/test/regrtest_data/empty.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pylint/test/regrtest_data/func_block_disable_msg.py,sha256=vkXZOvV5U40JE0gf1Re779xrgSjJkOBIrBmC9pF5UBY,4750 +pylint/test/regrtest_data/import_assign.py,sha256=MQucL4sv1V-Y0k18NTVPs7kTeLsAihUb5WXPz6iRzmw,105 +pylint/test/regrtest_data/import_package_subpackage_module.py,sha256=HgWsYTKAzWUBAbZsy9mR4pCMnk8YSBc5yb3PUIaxnx4,2238 +pylint/test/regrtest_data/import_something.py,sha256=uPhXzWW72WVOVbTdvEpV0HoLdtK-9ZPBfzOHcKqd41k,76 +pylint/test/regrtest_data/meta.py,sha256=QPhCQ67Qf-5HUzpXsTQ3g3Rusl8itbErpiVoA9t-p7Y,102 +pylint/test/regrtest_data/module_global.py,sha256=Pb9B6pOYeTcEslQWqoudoQs2kEeEjmdvOVAWgGJu31Q,137 +pylint/test/regrtest_data/no_stdout_encoding.py,sha256=quNCh1y8MajPHllw2Xx4OMwEln1XxlOdNUqCSb1ci5Q,116 +pylint/test/regrtest_data/numarray_import.py,sha256=_AOjoWWNJCA-f4eTAE-aHL2N-pgUk31_YwJgLaOE_gQ,80 +pylint/test/regrtest_data/numarray_inf.py,sha256=3LURMyTR7jmVSBF5mb9QH4b8F96xw4RIyPfefYVVq2c,120 +pylint/test/regrtest_data/precedence_test.py,sha256=KteLWBibss2at5ZCrjJFUWiM4m-5MxG8c3fg_qE5jeM,383 +pylint/test/regrtest_data/py3k-disabled.rc,sha256=sUQUIZp2_QX5xQbltf3ViuvhzUEfL5rtliOnW7EFeG0,46 +pylint/test/regrtest_data/py3k_error_flag.py,sha256=mKo88RR2cW_fRQqaswfOR-HtNP8AXHrUAifC03sbHks,280 +pylint/test/regrtest_data/py3k_errors_and_warnings.py,sha256=CDaP2G71pYuYsHWEe_VRo6jCZS4G8FBHfQ8cEON3qnE,497 +pylint/test/regrtest_data/special_attr_scope_lookup_crash.py,sha256=-6Edt8xI1HIh-NSNBX-ELVskeO3Rq8bCQHwbHglK1EY,52 +pylint/test/regrtest_data/syntax_error.py,sha256=4iOEbElAnWQLkdkQQKf6Rfy-FgiiSriWbmkOFHnD160,20 +pylint/test/regrtest_data/test_pylintrc_comments.py,sha256=5Z3O8gzs73ikUhgemi41UghFf1aGyxrx_5gNUQMh0eM,29 +pylint/test/regrtest_data/try_finally_disable_msg_crash.py,sha256=8TTNlXFdvmW0aCncFz6T3Nbxf4LIPhqAlAXLZ4Ro5m0,60 +pylint/test/regrtest_data/wildcard.py,sha256=yc2ya8NbzA7utEKO_u4-kluMuqHvcPhs2WG-4X-kOHQ,20 +pylint/test/regrtest_data/wrong_import_position.py,sha256=oXAFZWCbk7IoLq9HnANPQ0RI2CavrhzYNPt1M9NTTiE,231 +pylint/test/regrtest_data/absimp/__init__.py,sha256=jopfkowRBXa3hle8jua7C45zEtu3xwASSHKZhIUB8uY,88 +pylint/test/regrtest_data/absimp/string.py,sha256=QhOmIyZk8m4ZSQ1taN7DwkcJgt9XZRj72brzzJIAJYQ,163 +pylint/test/regrtest_data/bad_package/__init__.py,sha256=MUoNB45Pc9MWvwOCvglr4dzRemZ_RgwzFzVNcfeC6x0,39 +pylint/test/regrtest_data/bad_package/wrong.py,sha256=ySAuCYVX6Usuryalp2R907NZUgZ3MT5mr1JXgNPPWIY,161 +pylint/test/regrtest_data/beyond_top/__init__.py,sha256=6N1yHFJrMzh8Cj9_1NK8DP94vQf7yWUu_LTHFc8Kd1M,108 +pylint/test/regrtest_data/beyond_top/data.py,sha256=qFQYT1qH7Be012lV2CXfiuO7qepXUVhrWcuWyu3Tttw,13 +pylint/test/regrtest_data/dummy/__init__.py,sha256=x623im2PnTIq9EgWQNeuLqg0j9mrlQfp8olL6AswGAg,90 +pylint/test/regrtest_data/dummy/another.py,sha256=6cQMaJSMZnolnZwT7dbvL6OuhVv1mDbtwNNvt7hFjMM,50 +pylint/test/regrtest_data/dummy/dummy.py,sha256=CImG4Nsy1U3y1-ygucTiYLLWNgJ1X7_xackV29zgQOc,47 +pylint/test/regrtest_data/dummy_plugin/dummy_plugin.py,sha256=HCKk85QR-1LozTm2RCq5m10rg0XSO9xRuU_JoCVuXzM,788 +pylint/test/regrtest_data/init_wildcard/__init__.py,sha256=yc2ya8NbzA7utEKO_u4-kluMuqHvcPhs2WG-4X-kOHQ,20 +pylint/test/regrtest_data/package/AudioTime.py,sha256=rEekU-PkiqAx1ogBJMex9SdYyxpwd2d2i1VS5i4Nfu8,76 +pylint/test/regrtest_data/package/__init__.py,sha256=hLvFebqFysfjQ_m1UqJ8udZjEstLznoG6zlsk6UI4Nk,257 +pylint/test/regrtest_data/package/subpackage/__init__.py,sha256=XtKilaAqziUI-ImaSw4V6Aic40domt4v_If7lAZYhSE,25 +pylint/test/regrtest_data/package/subpackage/module.py,sha256=WAtPIk13pW6tYI6rSgNHcCgTu0EXhX6i5CugdHPH8N0,32 +pylint/test/regrtest_data/package_all/__init__.py,sha256=VfVvMl6Zft7VMtA7NuKKVnP46-2HIlCysu_gujjG1CQ,119 +pylint/test/regrtest_data/package_all/notmissing.py,sha256=iWUuMJ1evd_2YjrrAlC_MQccqUOrx_PiXTLEVi5NEIg,33 +pylint-2.2.2.data/scripts/epylint,sha256=ixZ-Def3hAP-hx6ZT9vLnK8GMPk2MrseCXzNpqMvxcU,50 +pylint-2.2.2.data/scripts/pylint,sha256=jWwrvRhbHeEzaMyvUVbVrggaEQqMuAi5-T2LT1CE5IY,52 +pylint-2.2.2.data/scripts/pyreverse,sha256=X-rZWORVwenc_jmraZN_juamsTqOPef1W40b2DL3-Ao,58 +pylint-2.2.2.data/scripts/symilar,sha256=KaS6U6LHbe9oTqPbZbNeKOnFTwp9Fml_DUDo19q6rRI,54 +pylint-2.2.2.dist-info/METADATA,sha256=pXQgMTFMZr2adw5FYhdO9oST1pwwp7Thkz-R10_mEm8,4450 +pylint-2.2.2.dist-info/RECORD,, +pylint-2.2.2.dist-info/WHEEL,sha256=FRuHuBX28RTgsOL603qIpbSc2WeDgbsFBWKj9XFOCpg,92 +pylint-2.2.2.dist-info/entry_points.txt,sha256=WUTwHM2ZcExO-VSvss18AMFsQL-XcWg6O3_MwobWfmw,137 +pylint-2.2.2.dist-info/top_level.txt,sha256=j6Z9i__pIuaiCka6Ul9YIy6yI5aw5QbCtldLvZlMksE,7 +../../Scripts/epylint.exe,sha256=3QQo3rZaO05ben0YBglC1Ehk7N_5us895Y7ytyksrIM,102762 +../../Scripts/pylint.exe,sha256=gyVTbuZ6rH_exYqy63ZlbqyPwvhP_e7GDl4IuJ1NfTM,102760 +../../Scripts/pyreverse.exe,sha256=2qqihWrj1dQaipA0xAocPB6ecxe1vUS9a0lAJGAVQh0,102766 +../../Scripts/symilar.exe,sha256=tI9beU2X4fYywoNqEGkeiQYdwP3aO8VT7qLYPf601CM,102762 +pylint-2.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pylint/checkers/__pycache__/async.cpython-37.pyc,, +pylint/checkers/__pycache__/base.cpython-37.pyc,, +pylint/checkers/__pycache__/classes.cpython-37.pyc,, +pylint/checkers/__pycache__/design_analysis.cpython-37.pyc,, +pylint/checkers/__pycache__/exceptions.cpython-37.pyc,, +pylint/checkers/__pycache__/format.cpython-37.pyc,, +pylint/checkers/__pycache__/imports.cpython-37.pyc,, +pylint/checkers/__pycache__/logging.cpython-37.pyc,, +pylint/checkers/__pycache__/misc.cpython-37.pyc,, +pylint/checkers/__pycache__/newstyle.cpython-37.pyc,, +pylint/checkers/__pycache__/python3.cpython-37.pyc,, +pylint/checkers/__pycache__/raw_metrics.cpython-37.pyc,, +pylint/checkers/__pycache__/refactoring.cpython-37.pyc,, +pylint/checkers/__pycache__/similar.cpython-37.pyc,, +pylint/checkers/__pycache__/spelling.cpython-37.pyc,, +pylint/checkers/__pycache__/stdlib.cpython-37.pyc,, +pylint/checkers/__pycache__/strings.cpython-37.pyc,, +pylint/checkers/__pycache__/typecheck.cpython-37.pyc,, +pylint/checkers/__pycache__/utils.cpython-37.pyc,, +pylint/checkers/__pycache__/variables.cpython-37.pyc,, +pylint/checkers/__pycache__/__init__.cpython-37.pyc,, +pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc,, +pylint/extensions/__pycache__/check_docs.cpython-37.pyc,, +pylint/extensions/__pycache__/check_elif.cpython-37.pyc,, +pylint/extensions/__pycache__/comparetozero.cpython-37.pyc,, +pylint/extensions/__pycache__/docparams.cpython-37.pyc,, +pylint/extensions/__pycache__/docstyle.cpython-37.pyc,, +pylint/extensions/__pycache__/emptystring.cpython-37.pyc,, +pylint/extensions/__pycache__/mccabe.cpython-37.pyc,, +pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc,, +pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc,, +pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc,, +pylint/extensions/__pycache__/__init__.cpython-37.pyc,, +pylint/pyreverse/__pycache__/diadefslib.cpython-37.pyc,, +pylint/pyreverse/__pycache__/diagrams.cpython-37.pyc,, +pylint/pyreverse/__pycache__/inspector.cpython-37.pyc,, +pylint/pyreverse/__pycache__/main.cpython-37.pyc,, +pylint/pyreverse/__pycache__/utils.cpython-37.pyc,, +pylint/pyreverse/__pycache__/vcgutils.cpython-37.pyc,, +pylint/pyreverse/__pycache__/writer.cpython-37.pyc,, +pylint/pyreverse/__pycache__/__init__.cpython-37.pyc,, +pylint/reporters/ureports/__pycache__/nodes.cpython-37.pyc,, +pylint/reporters/ureports/__pycache__/text_writer.cpython-37.pyc,, +pylint/reporters/ureports/__pycache__/__init__.cpython-37.pyc,, +pylint/reporters/__pycache__/json.cpython-37.pyc,, +pylint/reporters/__pycache__/text.cpython-37.pyc,, +pylint/reporters/__pycache__/__init__.cpython-37.pyc,, +pylint/test/acceptance/__pycache__/test_stdlib.cpython-37.pyc,, +pylint/test/data/__pycache__/clientmodule_test.cpython-37.pyc,, +pylint/test/data/__pycache__/suppliermodule_test.cpython-37.pyc,, +pylint/test/data/__pycache__/__init__.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/bad_builtin.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/compare_to_zero.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/docstring.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/elif.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/empty_string_comparison.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/mccabe.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/overlapping_exceptions.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/overlapping_exceptions_py33.cpython-37.pyc,, +pylint/test/extensions/data/__pycache__/redefined.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_bad_builtin.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_check_docs.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_check_docs_utils.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_check_mccabe.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_check_raise_docs.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_check_return_docs.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_check_yields_docs.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_comparetozero.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_docstyle.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_elseif_used.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_emptystring.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_overlapping_exceptions.cpython-37.pyc,, +pylint/test/extensions/__pycache__/test_redefined.cpython-37.pyc,, +pylint/test/extensions/__pycache__/__init__.cpython-37.pyc,, +pylint/test/functional/__pycache__/abstract_abc_methods.cpython-37.pyc,, +pylint/test/functional/__pycache__/abstract_class_instantiated_in_class.cpython-37.pyc,, +pylint/test/functional/__pycache__/abstract_class_instantiated_py2.cpython-37.pyc,, +pylint/test/functional/__pycache__/abstract_class_instantiated_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/abstract_class_instantiated_py34.cpython-37.pyc,, +pylint/test/functional/__pycache__/abstract_method_py2.cpython-37.pyc,, +pylint/test/functional/__pycache__/abstract_method_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/access_member_before_definition.cpython-37.pyc,, +pylint/test/functional/__pycache__/access_to_protected_members.cpython-37.pyc,, +pylint/test/functional/__pycache__/access_to__name__.cpython-37.pyc,, +pylint/test/functional/__pycache__/anomalous_unicode_escape_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/arguments.cpython-37.pyc,, +pylint/test/functional/__pycache__/arguments_differ.cpython-37.pyc,, +pylint/test/functional/__pycache__/arguments_differ_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/assert_on_tuple.cpython-37.pyc,, +pylint/test/functional/__pycache__/assigning_non_slot.cpython-37.pyc,, +pylint/test/functional/__pycache__/assignment_from_no_return.cpython-37.pyc,, +pylint/test/functional/__pycache__/assignment_from_no_return_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/attribute_defined_outside_init.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_continuation.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_continuation_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_continuation_tabs.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_exception_context.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_indentation.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_inline_option.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_open_mode.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_open_mode_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_reversed_sequence.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_staticmethod_argument.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_thread_instantiation.cpython-37.pyc,, +pylint/test/functional/__pycache__/bad_whitespace.cpython-37.pyc,, +pylint/test/functional/__pycache__/bare_except.cpython-37.pyc,, +pylint/test/functional/__pycache__/blacklisted_name.cpython-37.pyc,, +pylint/test/functional/__pycache__/boolean_datetime.cpython-37.pyc,, +pylint/test/functional/__pycache__/broad_except.cpython-37.pyc,, +pylint/test/functional/__pycache__/bugfix_local_scope_metaclass_1177.cpython-37.pyc,, +pylint/test/functional/__pycache__/cellvar_escaping_loop.cpython-37.pyc,, +pylint/test/functional/__pycache__/class_members_py30.cpython-37.pyc,, +pylint/test/functional/__pycache__/class_scope.cpython-37.pyc,, +pylint/test/functional/__pycache__/comparison_with_callable.cpython-37.pyc,, +pylint/test/functional/__pycache__/confidence_filter.cpython-37.pyc,, +pylint/test/functional/__pycache__/confusing_with_statement.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_iterating_dictionary.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_join.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_merging_isinstance.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_swap_variables.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_using_dict_comprehension.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_using_enumerate.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_using_get.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_using_in.cpython-37.pyc,, +pylint/test/functional/__pycache__/consider_using_set_comprehension.cpython-37.pyc,, +pylint/test/functional/__pycache__/control_pragmas.cpython-37.pyc,, +pylint/test/functional/__pycache__/crash_missing_module_type.cpython-37.pyc,, +pylint/test/functional/__pycache__/ctor_arguments.cpython-37.pyc,, +pylint/test/functional/__pycache__/dangerous_default_value.cpython-37.pyc,, +pylint/test/functional/__pycache__/dangerous_default_value_py30.cpython-37.pyc,, +pylint/test/functional/__pycache__/defined_and_used_on_same_line.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_lambda.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_methods_py2.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_methods_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_methods_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_method_getmoduleinfo.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_module_py2.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_module_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_module_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_module_py4.cpython-37.pyc,, +pylint/test/functional/__pycache__/deprecated_module_uninstalled.cpython-37.pyc,, +pylint/test/functional/__pycache__/disable_msg_github_issue_1389.cpython-37.pyc,, +pylint/test/functional/__pycache__/disable_ungrouped_imports.cpython-37.pyc,, +pylint/test/functional/__pycache__/disable_wrong_import_order.cpython-37.pyc,, +pylint/test/functional/__pycache__/disable_wrong_import_position.cpython-37.pyc,, +pylint/test/functional/__pycache__/docstrings.cpython-37.pyc,, +pylint/test/functional/__pycache__/duplicate_bases.cpython-37.pyc,, +pylint/test/functional/__pycache__/duplicate_dict_literal_key.cpython-37.pyc,, +pylint/test/functional/__pycache__/duplicate_except.cpython-37.pyc,, +pylint/test/functional/__pycache__/duplicate_string_formatting_argument.cpython-37.pyc,, +pylint/test/functional/__pycache__/eval_used.cpython-37.pyc,, +pylint/test/functional/__pycache__/exception_is_binary_op.cpython-37.pyc,, +pylint/test/functional/__pycache__/exception_message.cpython-37.pyc,, +pylint/test/functional/__pycache__/exec_used_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/fallback_import_disabled.cpython-37.pyc,, +pylint/test/functional/__pycache__/fallback_import_enabled.cpython-37.pyc,, +pylint/test/functional/__pycache__/fixme.cpython-37.pyc,, +pylint/test/functional/__pycache__/fixme_bad_formatting_1139.cpython-37.pyc,, +pylint/test/functional/__pycache__/formatted_string_literal_with_if_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/function_redefined.cpython-37.pyc,, +pylint/test/functional/__pycache__/future_import.cpython-37.pyc,, +pylint/test/functional/__pycache__/future_unicode_literals.cpython-37.pyc,, +pylint/test/functional/__pycache__/generated_members.cpython-37.pyc,, +pylint/test/functional/__pycache__/genexpr_variable_scope.cpython-37.pyc,, +pylint/test/functional/__pycache__/genexp_in_class_scope.cpython-37.pyc,, +pylint/test/functional/__pycache__/globals.cpython-37.pyc,, +pylint/test/functional/__pycache__/implicit_str_concat_in_sequence.cpython-37.pyc,, +pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_latin1.cpython-37.pyc,, +pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_utf8.cpython-37.pyc,, +pylint/test/functional/__pycache__/import_error.cpython-37.pyc,, +pylint/test/functional/__pycache__/inconsistent_mro.cpython-37.pyc,, +pylint/test/functional/__pycache__/inconsistent_returns.cpython-37.pyc,, +pylint/test/functional/__pycache__/indexing_exception.cpython-37.pyc,, +pylint/test/functional/__pycache__/inherit_non_class.cpython-37.pyc,, +pylint/test/functional/__pycache__/init_is_generator.cpython-37.pyc,, +pylint/test/functional/__pycache__/init_not_called.cpython-37.pyc,, +pylint/test/functional/__pycache__/init_subclass_classmethod_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_all_object.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_encoding_py27.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_envvar_value.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_exceptions_caught.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_exceptions_raised.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_length_returned.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_metaclass.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_metaclass_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_name.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_sequence_index.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_slice_index.cpython-37.pyc,, +pylint/test/functional/__pycache__/invalid_unary_operand_type.cpython-37.pyc,, +pylint/test/functional/__pycache__/iterable_context.cpython-37.pyc,, +pylint/test/functional/__pycache__/iterable_context_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/iterable_context_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/keyword_arg_before_vararg.cpython-37.pyc,, +pylint/test/functional/__pycache__/len_checks.cpython-37.pyc,, +pylint/test/functional/__pycache__/line_endings.cpython-37.pyc,, +pylint/test/functional/__pycache__/line_too_long.cpython-37.pyc,, +pylint/test/functional/__pycache__/line_too_long_end_of_module.cpython-37.pyc,, +pylint/test/functional/__pycache__/literal_comparison.cpython-37.pyc,, +pylint/test/functional/__pycache__/logging_format_interpolation.cpython-37.pyc,, +pylint/test/functional/__pycache__/logging_format_interpolation_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/logging_fstring_interpolation_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/logging_not_lazy.cpython-37.pyc,, +pylint/test/functional/__pycache__/logical_tautology.cpython-37.pyc,, +pylint/test/functional/__pycache__/long_lines_with_utf8.cpython-37.pyc,, +pylint/test/functional/__pycache__/long_utf8_lines.cpython-37.pyc,, +pylint/test/functional/__pycache__/lost_exception.cpython-37.pyc,, +pylint/test/functional/__pycache__/mapping_context.cpython-37.pyc,, +pylint/test/functional/__pycache__/mapping_context_py2.cpython-37.pyc,, +pylint/test/functional/__pycache__/mapping_context_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/membership_protocol.cpython-37.pyc,, +pylint/test/functional/__pycache__/membership_protocol_py2.cpython-37.pyc,, +pylint/test/functional/__pycache__/membership_protocol_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/member_checks.cpython-37.pyc,, +pylint/test/functional/__pycache__/member_checks_hints.cpython-37.pyc,, +pylint/test/functional/__pycache__/member_checks_ignore_none.cpython-37.pyc,, +pylint/test/functional/__pycache__/member_checks_no_hints.cpython-37.pyc,, +pylint/test/functional/__pycache__/member_checks_opaque.cpython-37.pyc,, +pylint/test/functional/__pycache__/member_checks_py37.cpython-37.pyc,, +pylint/test/functional/__pycache__/messages_managed_by_id.cpython-37.pyc,, +pylint/test/functional/__pycache__/method_hidden.cpython-37.pyc,, +pylint/test/functional/__pycache__/misplaced_bare_raise.cpython-37.pyc,, +pylint/test/functional/__pycache__/misplaced_comparison_constant.cpython-37.pyc,, +pylint/test/functional/__pycache__/misplaced_format_function.cpython-37.pyc,, +pylint/test/functional/__pycache__/missing_docstring.cpython-37.pyc,, +pylint/test/functional/__pycache__/missing_final_newline.cpython-37.pyc,, +pylint/test/functional/__pycache__/missing_kwoa_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/missing_self_argument.cpython-37.pyc,, +pylint/test/functional/__pycache__/mixed_indentation.cpython-37.pyc,, +pylint/test/functional/__pycache__/monkeypatch_method.cpython-37.pyc,, +pylint/test/functional/__pycache__/multiple_imports.cpython-37.pyc,, +pylint/test/functional/__pycache__/namedtuple_member_inference.cpython-37.pyc,, +pylint/test/functional/__pycache__/namePresetCamelCase.cpython-37.pyc,, +pylint/test/functional/__pycache__/names_in__all__.cpython-37.pyc,, +pylint/test/functional/__pycache__/name_preset_snake_case.cpython-37.pyc,, +pylint/test/functional/__pycache__/name_styles.cpython-37.pyc,, +pylint/test/functional/__pycache__/nested_blocks_issue1088.cpython-37.pyc,, +pylint/test/functional/__pycache__/nonexistent_operator.cpython-37.pyc,, +pylint/test/functional/__pycache__/none_dunder_protocols_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/non_iterator_returned.cpython-37.pyc,, +pylint/test/functional/__pycache__/not_async_context_manager.cpython-37.pyc,, +pylint/test/functional/__pycache__/not_callable.cpython-37.pyc,, +pylint/test/functional/__pycache__/not_context_manager.cpython-37.pyc,, +pylint/test/functional/__pycache__/no_classmethod_decorator.cpython-37.pyc,, +pylint/test/functional/__pycache__/no_else_return.cpython-37.pyc,, +pylint/test/functional/__pycache__/no_name_in_module.cpython-37.pyc,, +pylint/test/functional/__pycache__/no_self_use.cpython-37.pyc,, +pylint/test/functional/__pycache__/no_self_use_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/no_staticmethod_decorator.cpython-37.pyc,, +pylint/test/functional/__pycache__/postponed_evaluation_activated.cpython-37.pyc,, +pylint/test/functional/__pycache__/postponed_evaluation_not_activated.cpython-37.pyc,, +pylint/test/functional/__pycache__/protected_access_access_different_scopes.cpython-37.pyc,, +pylint/test/functional/__pycache__/raising_format_tuple.cpython-37.pyc,, +pylint/test/functional/__pycache__/raising_non_exception_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/raising_self.cpython-37.pyc,, +pylint/test/functional/__pycache__/recursion_error_940.cpython-37.pyc,, +pylint/test/functional/__pycache__/redefined_argument_from_local.cpython-37.pyc,, +pylint/test/functional/__pycache__/redefined_builtin.cpython-37.pyc,, +pylint/test/functional/__pycache__/redundant_unittest_assert.cpython-37.pyc,, +pylint/test/functional/__pycache__/regression_1326_crash_uninferable.cpython-37.pyc,, +pylint/test/functional/__pycache__/regression_no_value_for_parameter.cpython-37.pyc,, +pylint/test/functional/__pycache__/reimported.cpython-37.pyc,, +pylint/test/functional/__pycache__/repeated_keyword.cpython-37.pyc,, +pylint/test/functional/__pycache__/return_in_init.cpython-37.pyc,, +pylint/test/functional/__pycache__/reused_outer_loop_variable.cpython-37.pyc,, +pylint/test/functional/__pycache__/reused_outer_loop_variable_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/self_cls_assignment.cpython-37.pyc,, +pylint/test/functional/__pycache__/signature_differs.cpython-37.pyc,, +pylint/test/functional/__pycache__/simplifiable_if_expression.cpython-37.pyc,, +pylint/test/functional/__pycache__/simplifiable_if_statement.cpython-37.pyc,, +pylint/test/functional/__pycache__/simplify_chained_comparison.cpython-37.pyc,, +pylint/test/functional/__pycache__/singledispatch_functions.cpython-37.pyc,, +pylint/test/functional/__pycache__/singledispatch_functions_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/singleton_comparison.cpython-37.pyc,, +pylint/test/functional/__pycache__/slots_checks.cpython-37.pyc,, +pylint/test/functional/__pycache__/socketerror_import.cpython-37.pyc,, +pylint/test/functional/__pycache__/statement_without_effect.cpython-37.pyc,, +pylint/test/functional/__pycache__/statement_without_effect_py36.cpython-37.pyc,, +pylint/test/functional/__pycache__/stop_iteration_inside_generator.cpython-37.pyc,, +pylint/test/functional/__pycache__/string_formatting.cpython-37.pyc,, +pylint/test/functional/__pycache__/string_formatting_disable.cpython-37.pyc,, +pylint/test/functional/__pycache__/string_formatting_failed_inference.cpython-37.pyc,, +pylint/test/functional/__pycache__/string_formatting_py27.cpython-37.pyc,, +pylint/test/functional/__pycache__/string_formatting_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/subprocess_popen_preexec_fn.cpython-37.pyc,, +pylint/test/functional/__pycache__/superfluous_parens.cpython-37.pyc,, +pylint/test/functional/__pycache__/super_checks.cpython-37.pyc,, +pylint/test/functional/__pycache__/suspicious_str_strip_call.cpython-37.pyc,, +pylint/test/functional/__pycache__/suspicious_str_strip_call_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/sys_stream_regression_1004.cpython-37.pyc,, +pylint/test/functional/__pycache__/ternary.cpython-37.pyc,, +pylint/test/functional/__pycache__/test_compile.cpython-37.pyc,, +pylint/test/functional/__pycache__/tokenize_error.cpython-37.pyc,, +pylint/test/functional/__pycache__/tokenize_error_jython.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_few_public_methods.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_few_public_methods_37.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_ancestors.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_arguments.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_arguments_issue_1045.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_boolean_expressions.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_branches.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_instance_attributes.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_lines.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_lines_disabled.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_locals.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_nested_blocks.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_public_methods.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_return_statements.cpython-37.pyc,, +pylint/test/functional/__pycache__/too_many_statements.cpython-37.pyc,, +pylint/test/functional/__pycache__/trailing_comma_tuple.cpython-37.pyc,, +pylint/test/functional/__pycache__/trailing_newlines.cpython-37.pyc,, +pylint/test/functional/__pycache__/trailing_whitespaces.cpython-37.pyc,, +pylint/test/functional/__pycache__/unbalanced_tuple_unpacking.cpython-37.pyc,, +pylint/test/functional/__pycache__/unbalanced_tuple_unpacking_py30.cpython-37.pyc,, +pylint/test/functional/__pycache__/undefined_loop_variable.cpython-37.pyc,, +pylint/test/functional/__pycache__/undefined_variable.cpython-37.pyc,, +pylint/test/functional/__pycache__/undefined_variable_py30.cpython-37.pyc,, +pylint/test/functional/__pycache__/unexpected_special_method_signature.cpython-37.pyc,, +pylint/test/functional/__pycache__/ungrouped_imports.cpython-37.pyc,, +pylint/test/functional/__pycache__/unhashable_dict_key.cpython-37.pyc,, +pylint/test/functional/__pycache__/unidiomatic_typecheck.cpython-37.pyc,, +pylint/test/functional/__pycache__/uninferable_all_object.cpython-37.pyc,, +pylint/test/functional/__pycache__/unnecessary_lambda.cpython-37.pyc,, +pylint/test/functional/__pycache__/unnecessary_pass.cpython-37.pyc,, +pylint/test/functional/__pycache__/unneeded_not.cpython-37.pyc,, +pylint/test/functional/__pycache__/unpacking.cpython-37.pyc,, +pylint/test/functional/__pycache__/unpacking_generalizations.cpython-37.pyc,, +pylint/test/functional/__pycache__/unpacking_non_sequence.cpython-37.pyc,, +pylint/test/functional/__pycache__/unreachable.cpython-37.pyc,, +pylint/test/functional/__pycache__/unrecognized_inline_option.cpython-37.pyc,, +pylint/test/functional/__pycache__/unsubscriptable_value.cpython-37.pyc,, +pylint/test/functional/__pycache__/unsupported_assignment_operation.cpython-37.pyc,, +pylint/test/functional/__pycache__/unsupported_binary_operation.cpython-37.pyc,, +pylint/test/functional/__pycache__/unsupported_delete_operation.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_argument.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_argument_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_global_variable1.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_global_variable2.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_global_variable3.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_global_variable4.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_import.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_import_assigned_to.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_typing_imports.cpython-37.pyc,, +pylint/test/functional/__pycache__/unused_variable.cpython-37.pyc,, +pylint/test/functional/__pycache__/used_before_assignment_488.cpython-37.pyc,, +pylint/test/functional/__pycache__/used_before_assignment_issue1081.cpython-37.pyc,, +pylint/test/functional/__pycache__/used_before_assignment_issue853.cpython-37.pyc,, +pylint/test/functional/__pycache__/used_before_assignment_nonlocal.cpython-37.pyc,, +pylint/test/functional/__pycache__/useless-import-alias.cpython-37.pyc,, +pylint/test/functional/__pycache__/useless_else_on_loop.cpython-37.pyc,, +pylint/test/functional/__pycache__/useless_object_inheritance.cpython-37.pyc,, +pylint/test/functional/__pycache__/useless_return.cpython-37.pyc,, +pylint/test/functional/__pycache__/useless_super_delegation.cpython-37.pyc,, +pylint/test/functional/__pycache__/useless_super_delegation_py3.cpython-37.pyc,, +pylint/test/functional/__pycache__/useless_super_delegation_py35.cpython-37.pyc,, +pylint/test/functional/__pycache__/using_constant_test.cpython-37.pyc,, +pylint/test/functional/__pycache__/wildcard_import.cpython-37.pyc,, +pylint/test/functional/__pycache__/wildcard_import_allowed.cpython-37.pyc,, +pylint/test/functional/__pycache__/with_used_before_assign.cpython-37.pyc,, +pylint/test/functional/__pycache__/with_using_generator.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_order.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_order2.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position10.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position11.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position12.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position13.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position14.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position15.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position2.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position3.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position4.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position5.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position6.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position7.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position8.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position9.cpython-37.pyc,, +pylint/test/functional/__pycache__/wrong_import_position_exclude_dunder_main.cpython-37.pyc,, +pylint/test/functional/__pycache__/yield_from_iterable_py33.cpython-37.pyc,, +pylint/test/functional/__pycache__/__init__.cpython-37.pyc,, +pylint/test/input/func_w0401_package/__pycache__/all_the_things.cpython-37.pyc,, +pylint/test/input/func_w0401_package/__pycache__/thing1.cpython-37.pyc,, +pylint/test/input/func_w0401_package/__pycache__/thing2.cpython-37.pyc,, +pylint/test/input/func_w0401_package/__pycache__/__init__.cpython-37.pyc,, +pylint/test/input/__pycache__/func_3k_removed_stuff_py_30.cpython-37.pyc,, +pylint/test/input/__pycache__/func_bad_cont_dictcomp_py27.cpython-37.pyc,, +pylint/test/input/__pycache__/func_bug113231.cpython-37.pyc,, +pylint/test/input/__pycache__/func_disable_linebased.cpython-37.pyc,, +pylint/test/input/__pycache__/func_dotted_ancestor.cpython-37.pyc,, +pylint/test/input/__pycache__/func_e0012.cpython-37.pyc,, +pylint/test/input/__pycache__/func_e0204.cpython-37.pyc,, +pylint/test/input/__pycache__/func_e12xx.cpython-37.pyc,, +pylint/test/input/__pycache__/func_e13xx.cpython-37.pyc,, +pylint/test/input/__pycache__/func_excess_escapes.cpython-37.pyc,, +pylint/test/input/__pycache__/func_first_arg.cpython-37.pyc,, +pylint/test/input/__pycache__/func_i0011.cpython-37.pyc,, +pylint/test/input/__pycache__/func_i0012.cpython-37.pyc,, +pylint/test/input/__pycache__/func_i0013.cpython-37.pyc,, +pylint/test/input/__pycache__/func_i0014.cpython-37.pyc,, +pylint/test/input/__pycache__/func_i0020.cpython-37.pyc,, +pylint/test/input/__pycache__/func_i0022.cpython-37.pyc,, +pylint/test/input/__pycache__/func_logging_not_lazy_with_logger.cpython-37.pyc,, +pylint/test/input/__pycache__/func_loopvar_in_dict_comp_py27.cpython-37.pyc,, +pylint/test/input/__pycache__/func_module___dict__.cpython-37.pyc,, +pylint/test/input/__pycache__/func_nameerror_on_string_substitution.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_access_attr_before_def_false_positive.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_base_init_vars.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_builtin_module_test.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_classes_meth_could_be_a_function.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_classes_protected_member_access.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_class_attributes.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_decorator_scope.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_e1101_9588_base_attr_aug_assign.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_external_classmethod_crash.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_inner_classes.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_lambda_use_before_assign.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_mcs_attr_access.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_new_style_class_py_30.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_no_warning_docstring.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_object_as_class_attribute.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_overloaded_operator.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_property_affectation_py26.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_yield_assign_py25.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror_yield_return_mix.cpython-37.pyc,, +pylint/test/input/__pycache__/func_noerror___init___return_from_inner_function.cpython-37.pyc,, +pylint/test/input/__pycache__/func_nonregr___file___global.cpython-37.pyc,, +pylint/test/input/__pycache__/func_no_dummy_redefined.cpython-37.pyc,, +pylint/test/input/__pycache__/func_return_yield_mix_py_33.cpython-37.pyc,, +pylint/test/input/__pycache__/func_typecheck_callfunc_assigment.cpython-37.pyc,, +pylint/test/input/__pycache__/func_unused_import_py30.cpython-37.pyc,, +pylint/test/input/__pycache__/func_variables_unused_name_from_wilcard_import.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0233.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0401.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0401_disabled.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0401_disabled_in_func.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0404.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0405.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0406.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0611.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0612.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0613.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0623_py30.cpython-37.pyc,, +pylint/test/input/__pycache__/func_w0801.cpython-37.pyc,, +pylint/test/input/__pycache__/hide_code_with_imports.cpython-37.pyc,, +pylint/test/input/__pycache__/ignore_except_pass_by_default.cpython-37.pyc,, +pylint/test/input/__pycache__/not__init__.cpython-37.pyc,, +pylint/test/input/__pycache__/w0401_cycle.cpython-37.pyc,, +pylint/test/input/__pycache__/w0801_same.cpython-37.pyc,, +pylint/test/input/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/absimp/__pycache__/string.cpython-37.pyc,, +pylint/test/regrtest_data/absimp/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/bad_package/__pycache__/wrong.cpython-37.pyc,, +pylint/test/regrtest_data/beyond_top/__pycache__/data.cpython-37.pyc,, +pylint/test/regrtest_data/beyond_top/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/dummy/__pycache__/another.cpython-37.pyc,, +pylint/test/regrtest_data/dummy/__pycache__/dummy.cpython-37.pyc,, +pylint/test/regrtest_data/dummy/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/dummy_plugin/__pycache__/dummy_plugin.cpython-37.pyc,, +pylint/test/regrtest_data/init_wildcard/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/package/subpackage/__pycache__/module.cpython-37.pyc,, +pylint/test/regrtest_data/package/subpackage/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/package/__pycache__/AudioTime.cpython-37.pyc,, +pylint/test/regrtest_data/package/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/package_all/__pycache__/notmissing.cpython-37.pyc,, +pylint/test/regrtest_data/package_all/__pycache__/__init__.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/application_crash.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/classdoc_usage.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/decimal_inference.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/empty.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/func_block_disable_msg.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/import_assign.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/import_package_subpackage_module.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/import_something.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/meta.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/module_global.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/no_stdout_encoding.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/numarray_import.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/numarray_inf.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/precedence_test.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/special_attr_scope_lookup_crash.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/test_pylintrc_comments.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/try_finally_disable_msg_crash.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/wildcard.cpython-37.pyc,, +pylint/test/regrtest_data/__pycache__/wrong_import_position.cpython-37.pyc,, +pylint/test/__pycache__/conftest.cpython-37.pyc,, +pylint/test/__pycache__/test_func.cpython-37.pyc,, +pylint/test/__pycache__/test_functional.cpython-37.pyc,, +pylint/test/__pycache__/test_import_graph.cpython-37.pyc,, +pylint/test/__pycache__/test_regr.cpython-37.pyc,, +pylint/test/__pycache__/test_self.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checkers_utils.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_base.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_classes.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_exceptions.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_format.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_imports.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_logging.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_misc.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_python3.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_similar.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_spelling.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_stdlib.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_strings.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_typecheck.cpython-37.pyc,, +pylint/test/__pycache__/unittest_checker_variables.cpython-37.pyc,, +pylint/test/__pycache__/unittest_config.cpython-37.pyc,, +pylint/test/__pycache__/unittest_lint.cpython-37.pyc,, +pylint/test/__pycache__/unittest_pyreverse_diadefs.cpython-37.pyc,, +pylint/test/__pycache__/unittest_pyreverse_inspector.cpython-37.pyc,, +pylint/test/__pycache__/unittest_pyreverse_writer.cpython-37.pyc,, +pylint/test/__pycache__/unittest_reporters_json.cpython-37.pyc,, +pylint/test/__pycache__/unittest_reporting.cpython-37.pyc,, +pylint/test/__pycache__/unittest_utils.cpython-37.pyc,, +pylint/__pycache__/config.cpython-37.pyc,, +pylint/__pycache__/epylint.cpython-37.pyc,, +pylint/__pycache__/exceptions.cpython-37.pyc,, +pylint/__pycache__/graph.cpython-37.pyc,, +pylint/__pycache__/interfaces.cpython-37.pyc,, +pylint/__pycache__/lint.cpython-37.pyc,, +pylint/__pycache__/testutils.cpython-37.pyc,, +pylint/__pycache__/utils.cpython-37.pyc,, +pylint/__pycache__/__init__.cpython-37.pyc,, +pylint/__pycache__/__main__.cpython-37.pyc,, +pylint/__pycache__/__pkginfo__.cpython-37.pyc,, diff --git a/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/WHEEL b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/WHEEL new file mode 100644 index 0000000..d1acba1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.31.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/entry_points.txt b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/entry_points.txt new file mode 100644 index 0000000..063b5e4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/entry_points.txt @@ -0,0 +1,6 @@ +[console_scripts] +epylint = pylint:run_epylint +pylint = pylint:run_pylint +pyreverse = pylint:run_pyreverse +symilar = pylint:run_symilar + diff --git a/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/top_level.txt new file mode 100644 index 0000000..7fb0ea1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint-2.2.2.dist-info/top_level.txt @@ -0,0 +1 @@ +pylint diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/__init__.py new file mode 100644 index 0000000..a5d43d1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/__init__.py @@ -0,0 +1,43 @@ +# Copyright (c) 2008, 2012 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014, 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import sys + +from .__pkginfo__ import version as __version__ + + +def run_pylint(): + """run pylint""" + from pylint.lint import Run + + try: + Run(sys.argv[1:]) + except KeyboardInterrupt: + sys.exit(1) + + +def run_epylint(): + """run pylint""" + from pylint.epylint import Run + + Run() + + +def run_pyreverse(): + """run pyreverse""" + from pylint.pyreverse.main import Run + + Run(sys.argv[1:]) + + +def run_symilar(): + """run symilar""" + from pylint.checkers.similar import Run + + Run(sys.argv[1:]) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__main__.py b/basic python programmes/venv/Lib/site-packages/pylint/__main__.py new file mode 100644 index 0000000..7eca119 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/__main__.py @@ -0,0 +1,8 @@ + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +#!/usr/bin/env python +import pylint + +pylint.run_pylint() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pkginfo__.py b/basic python programmes/venv/Lib/site-packages/pylint/__pkginfo__.py new file mode 100644 index 0000000..4bbc8da --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/__pkginfo__.py @@ -0,0 +1,93 @@ +# Copyright (c) 2006-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2010 Julien Jehannet <julien.jehannet@logilab.fr> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Ricardo Gemignani <ricardo.gemignani@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2016 Florian Bruhin <git@the-compiler.org> +# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2017-2018 Hugo <hugovk@users.noreply.github.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +# pylint: disable=W0622,C0103 +"""pylint packaging information""" + +from __future__ import absolute_import + +from os.path import join + +modname = distname = "pylint" + +numversion = (2, 2, 2) +dev_version = None +string_version = ".".join(str(num) for num in numversion) + +if dev_version: + version = string_version + "-" + dev_version +else: + version = string_version + +install_requires = ["astroid>=2.0.0", "isort >= 4.2.5", "mccabe"] + +dependency_links = [] # type: ignore + +extras_require = {} +extras_require[':sys_platform=="win32"'] = ["colorama"] + +license = "GPL" +description = "python code static checker" +web = "https://github.com/PyCQA/pylint" +mailinglist = "mailto:code-quality@python.org" +author = "Python Code Quality Authority" +author_email = "code-quality@python.org" + +classifiers = [ + "Development Status :: 6 - Mature", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Debuggers", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", +] + + +long_desc = """\ + Pylint is a Python source code analyzer which looks for programming + errors, helps enforcing a coding standard and sniffs for some code + smells (as defined in Martin Fowler's Refactoring book) + . + Pylint can be seen as another PyChecker since nearly all tests you + can do with PyChecker can also be done with Pylint. However, Pylint + offers some more features, like checking length of lines of code, + checking if variable names are well-formed according to your coding + standard, or checking if declared interfaces are truly implemented, + and much more. + . + Additionally, it is possible to write plugins to add your own checks. + . + Pylint is shipped with "pyreverse" (UML diagram generator) + and "symilar" (an independent similarities checker).""" + +scripts = [ + join("bin", filename) for filename in ("pylint", "symilar", "epylint", "pyreverse") +] + +include_dirs = [join("pylint", "test")] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..5ee45cd Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__main__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000..20e60cf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__main__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__pkginfo__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__pkginfo__.cpython-37.pyc new file mode 100644 index 0000000..9130d7d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/__pkginfo__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/config.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/config.cpython-37.pyc new file mode 100644 index 0000000..c9316e5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/config.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/epylint.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/epylint.cpython-37.pyc new file mode 100644 index 0000000..032922c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/epylint.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000..1d92c7c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/graph.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/graph.cpython-37.pyc new file mode 100644 index 0000000..02d88f8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/graph.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/interfaces.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/interfaces.cpython-37.pyc new file mode 100644 index 0000000..ddd0f75 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/interfaces.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/lint.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/lint.cpython-37.pyc new file mode 100644 index 0000000..897db38 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/lint.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/testutils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/testutils.cpython-37.pyc new file mode 100644 index 0000000..1b4136a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/testutils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000..c2a544b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/__pycache__/utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__init__.py new file mode 100644 index 0000000..fcb1f5b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__init__.py @@ -0,0 +1,134 @@ +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2013 buck@yelp.com <buck@yelp.com> +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2017-2018 Bryce Guinta <bryce.paul.guinta@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""utilities methods and classes for checkers + +Base id of standard checkers (used in msg and report ids): +01: base +02: classes +03: format +04: import +05: misc +06: variables +07: exceptions +08: similar +09: design_analysis +10: newstyle +11: typecheck +12: logging +13: string_format +14: string_constant +15: stdlib +16: python3 +17: refactoring +18-50: not yet used: reserved for future internal checkers. +51-99: perhaps used: reserved for external checkers + +The raw_metrics checker has no number associated since it doesn't emit any +messages nor reports. XXX not true, emit a 07 report ! + +""" + +import sys +import tokenize +import warnings +from typing import Any + +from pylint.config import OptionsProviderMixIn +from pylint.reporters import diff_string +from pylint.utils import register_plugins +from pylint.interfaces import UNDEFINED + + +def table_lines_from_stats(stats, old_stats, columns): + """get values listed in <columns> from <stats> and <old_stats>, + and return a formated list of values, designed to be given to a + ureport.Table object + """ + lines = [] + for m_type in columns: + new = stats[m_type] + format = str # pylint: disable=redefined-builtin + if isinstance(new, float): + format = lambda num: "%.3f" % num + old = old_stats.get(m_type) + if old is not None: + diff_str = diff_string(old, new) + old = format(old) + else: + old, diff_str = "NC", "NC" + lines += (m_type.replace("_", " "), format(new), old, diff_str) + return lines + + +class BaseChecker(OptionsProviderMixIn): + """base class for checkers""" + + # checker name (you may reuse an existing one) + name = None # type: str + # options level (0 will be displaying in --help, 1 in --long-help) + level = 1 + # ordered list of options to control the ckecker behaviour + options = () # type: Any + # messages issued by this checker + msgs = {} # type: Any + # reports issued by this checker + reports = () # type: Any + # mark this checker as enabled or not. + enabled = True + + def __init__(self, linter=None): + """checker instances should have the linter as argument + + linter is an object implementing ILinter + """ + if self.name is not None: + self.name = self.name.lower() + OptionsProviderMixIn.__init__(self) + self.linter = linter + + def add_message( + self, + msg_id, + line=None, + node=None, + args=None, + confidence=UNDEFINED, + col_offset=None, + ): + """add a message of a given type""" + self.linter.add_message(msg_id, line, node, args, confidence, col_offset) + + # dummy methods implementing the IChecker interface + + def open(self): + """called before visiting project (i.e set of modules)""" + + def close(self): + """called after visiting project (i.e set of modules)""" + + +class BaseTokenChecker(BaseChecker): + """Base class for checkers that want to have access to the token stream.""" + + def process_tokens(self, tokens): + """Should be overridden by subclasses.""" + raise NotImplementedError() + + +def initialize(linter): + """initialize linter with checkers in this package """ + register_plugins(linter, __path__[0]) + + +__all__ = ("BaseChecker", "initialize") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..2a72655 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/async.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/async.cpython-37.pyc new file mode 100644 index 0000000..fe8d4ab Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/async.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/base.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000..dbc945d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/base.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/classes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/classes.cpython-37.pyc new file mode 100644 index 0000000..cca6bef Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/classes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-37.pyc new file mode 100644 index 0000000..b9edf67 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/design_analysis.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000..ccef412 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/format.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/format.cpython-37.pyc new file mode 100644 index 0000000..e44bf37 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/format.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/imports.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/imports.cpython-37.pyc new file mode 100644 index 0000000..dca983c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/imports.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/logging.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/logging.cpython-37.pyc new file mode 100644 index 0000000..acda62f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/logging.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/misc.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/misc.cpython-37.pyc new file mode 100644 index 0000000..41f6872 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/misc.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/newstyle.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/newstyle.cpython-37.pyc new file mode 100644 index 0000000..e2146c7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/newstyle.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/python3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/python3.cpython-37.pyc new file mode 100644 index 0000000..5ad3fb8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/python3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/raw_metrics.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/raw_metrics.cpython-37.pyc new file mode 100644 index 0000000..0f96337 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/raw_metrics.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/refactoring.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/refactoring.cpython-37.pyc new file mode 100644 index 0000000..cdd858a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/refactoring.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/similar.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/similar.cpython-37.pyc new file mode 100644 index 0000000..f09908f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/similar.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/spelling.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/spelling.cpython-37.pyc new file mode 100644 index 0000000..810d1a2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/spelling.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/stdlib.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/stdlib.cpython-37.pyc new file mode 100644 index 0000000..a325b10 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/stdlib.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/strings.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/strings.cpython-37.pyc new file mode 100644 index 0000000..4c6814d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/strings.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/typecheck.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/typecheck.cpython-37.pyc new file mode 100644 index 0000000..14fdb0e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/typecheck.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000..8ada338 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/variables.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/variables.cpython-37.pyc new file mode 100644 index 0000000..49820b3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/checkers/__pycache__/variables.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/async.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/async.py new file mode 100644 index 0000000..881b29d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/async.py @@ -0,0 +1,84 @@ +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2017 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Checker for anything related to the async protocol (PEP 492).""" + +import sys + +import astroid +from astroid import exceptions + +from pylint import checkers +from pylint.checkers import utils as checker_utils +from pylint import interfaces +from pylint import utils + + +class AsyncChecker(checkers.BaseChecker): + __implements__ = interfaces.IAstroidChecker + name = "async" + msgs = { + "E1700": ( + "Yield inside async function", + "yield-inside-async-function", + "Used when an `yield` or `yield from` statement is " + "found inside an async function.", + {"minversion": (3, 5)}, + ), + "E1701": ( + "Async context manager '%s' doesn't implement __aenter__ and __aexit__.", + "not-async-context-manager", + "Used when an async context manager is used with an object " + "that does not implement the async context management protocol.", + {"minversion": (3, 5)}, + ), + } + + def open(self): + self._ignore_mixin_members = utils.get_global_option( + self, "ignore-mixin-members" + ) + + @checker_utils.check_messages("yield-inside-async-function") + def visit_asyncfunctiondef(self, node): + for child in node.nodes_of_class(astroid.Yield): + if child.scope() is node and ( + sys.version_info[:2] == (3, 5) or isinstance(child, astroid.YieldFrom) + ): + self.add_message("yield-inside-async-function", node=child) + + @checker_utils.check_messages("not-async-context-manager") + def visit_asyncwith(self, node): + for ctx_mgr, _ in node.items: + infered = checker_utils.safe_infer(ctx_mgr) + if infered is None or infered is astroid.Uninferable: + continue + + if isinstance(infered, astroid.Instance): + try: + infered.getattr("__aenter__") + infered.getattr("__aexit__") + except exceptions.NotFoundError: + if isinstance(infered, astroid.Instance): + # If we do not know the bases of this class, + # just skip it. + if not checker_utils.has_known_bases(infered): + continue + # Just ignore mixin classes. + if self._ignore_mixin_members: + if infered.name[-5:].lower() == "mixin": + continue + else: + continue + + self.add_message( + "not-async-context-manager", node=node, args=(infered.name,) + ) + + +def register(linter): + """required method to auto register this checker""" + linter.register_checker(AsyncChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/base.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/base.py new file mode 100644 index 0000000..beb7c13 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/base.py @@ -0,0 +1,2213 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2016 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2010 Daniel Harding <dharding@gmail.com> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2013-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Nick Bastin <nick.bastin@gmail.com> +# Copyright (c) 2015 Michael Kefeder <oss@multiwave.ch> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Stephane Wirtel <stephane@wirtel.be> +# Copyright (c) 2015 Cosmin Poieana <cmin@ropython.org> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Radu Ciorba <radu@devrandom.ro> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016, 2018 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Elias Dorneles <eliasdorneles@gmail.com> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016 Yannack <yannack@users.noreply.github.com> +# Copyright (c) 2016 Alex Jurkiewicz <alex@jurkiewi.cz> +# Copyright (c) 2017 Jacques Kvam <jwkvam@gmail.com> +# Copyright (c) 2017 ttenhoeve-aa <ttenhoeve@appannie.com> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> +# Copyright (c) 2018 Steven M. Vascellaro <svascellaro@gmail.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Chris Lamb <chris@chris-lamb.co.uk> +# Copyright (c) 2018 glmdgrielson <32415403+glmdgrielson@users.noreply.github.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""basic checker for Python code""" + +import builtins +import collections +import itertools +import sys +import re +from typing import Pattern + +import astroid +import astroid.bases +import astroid.scoped_nodes + +from pylint import checkers +from pylint import exceptions +from pylint import interfaces +from pylint.checkers import utils +from pylint import reporters +from pylint.checkers.utils import get_node_last_lineno +from pylint.reporters.ureports import nodes as reporter_nodes +import pylint.utils as lint_utils + + +class NamingStyle: + # It may seem counterintuitive that single naming style + # has multiple "accepted" forms of regular expressions, + # but we need to special-case stuff like dunder names + # in method names. + CLASS_NAME_RGX = None # type: Pattern[str] + MOD_NAME_RGX = None # type: Pattern[str] + CONST_NAME_RGX = None # type: Pattern[str] + COMP_VAR_RGX = None # type: Pattern[str] + DEFAULT_NAME_RGX = None # type: Pattern[str] + CLASS_ATTRIBUTE_RGX = None # type: Pattern[str] + + @classmethod + def get_regex(cls, name_type): + return { + "module": cls.MOD_NAME_RGX, + "const": cls.CONST_NAME_RGX, + "class": cls.CLASS_NAME_RGX, + "function": cls.DEFAULT_NAME_RGX, + "method": cls.DEFAULT_NAME_RGX, + "attr": cls.DEFAULT_NAME_RGX, + "argument": cls.DEFAULT_NAME_RGX, + "variable": cls.DEFAULT_NAME_RGX, + "class_attribute": cls.CLASS_ATTRIBUTE_RGX, + "inlinevar": cls.COMP_VAR_RGX, + }[name_type] + + +class SnakeCaseStyle(NamingStyle): + """Regex rules for snake_case naming style.""" + + CLASS_NAME_RGX = re.compile("[a-z_][a-z0-9_]+$") + MOD_NAME_RGX = re.compile("([a-z_][a-z0-9_]*)$") + CONST_NAME_RGX = re.compile("(([a-z_][a-z0-9_]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[a-z_][a-z0-9_]*$") + DEFAULT_NAME_RGX = re.compile( + "(([a-z_][a-z0-9_]{2,})|(_[a-z0-9_]*)|(__[a-z][a-z0-9_]+__))$" + ) + CLASS_ATTRIBUTE_RGX = re.compile(r"(([a-z_][a-z0-9_]{2,}|(__.*__)))$") + + +class CamelCaseStyle(NamingStyle): + """Regex rules for camelCase naming style.""" + + CLASS_NAME_RGX = re.compile("[a-z_][a-zA-Z0-9]+$") + MOD_NAME_RGX = re.compile("([a-z_][a-zA-Z0-9]*)$") + CONST_NAME_RGX = re.compile("(([a-z_][A-Za-z0-9]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[a-z_][A-Za-z0-9]*$") + DEFAULT_NAME_RGX = re.compile("(([a-z_][a-zA-Z0-9]{2,})|(__[a-z][a-zA-Z0-9_]+__))$") + CLASS_ATTRIBUTE_RGX = re.compile(r"([a-z_][A-Za-z0-9]{2,}|(__.*__))$") + + +class PascalCaseStyle(NamingStyle): + """Regex rules for PascalCase naming style.""" + + CLASS_NAME_RGX = re.compile("[A-Z_][a-zA-Z0-9]+$") + MOD_NAME_RGX = re.compile("[A-Z_][a-zA-Z0-9]+$") + CONST_NAME_RGX = re.compile("(([A-Z_][A-Za-z0-9]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[A-Z_][a-zA-Z0-9]+$") + DEFAULT_NAME_RGX = re.compile("[A-Z_][a-zA-Z0-9]{2,}$|(__[a-z][a-zA-Z0-9_]+__)$") + CLASS_ATTRIBUTE_RGX = re.compile("[A-Z_][a-zA-Z0-9]{2,}$") + + +class UpperCaseStyle(NamingStyle): + """Regex rules for UPPER_CASE naming style.""" + + CLASS_NAME_RGX = re.compile("[A-Z_][A-Z0-9_]+$") + MOD_NAME_RGX = re.compile("[A-Z_][A-Z0-9_]+$") + CONST_NAME_RGX = re.compile("(([A-Z_][A-Z0-9_]*)|(__.*__))$") + COMP_VAR_RGX = re.compile("[A-Z_][A-Z0-9_]+$") + DEFAULT_NAME_RGX = re.compile("([A-Z_][A-Z0-9_]{2,})|(__[a-z][a-zA-Z0-9_]+__)$") + CLASS_ATTRIBUTE_RGX = re.compile("[A-Z_][A-Z0-9_]{2,}$") + + +class AnyStyle(NamingStyle): + @classmethod + def get_regex(cls, name_type): + return re.compile(".*") + + +NAMING_STYLES = { + "snake_case": SnakeCaseStyle, + "camelCase": CamelCaseStyle, + "PascalCase": PascalCaseStyle, + "UPPER_CASE": UpperCaseStyle, + "any": AnyStyle, +} + +# do not require a doc string on private/system methods +NO_REQUIRED_DOC_RGX = re.compile("^_") +REVERSED_PROTOCOL_METHOD = "__reversed__" +SEQUENCE_PROTOCOL_METHODS = ("__getitem__", "__len__") +REVERSED_METHODS = (SEQUENCE_PROTOCOL_METHODS, (REVERSED_PROTOCOL_METHOD,)) +TYPECHECK_COMPARISON_OPERATORS = frozenset(("is", "is not", "==", "!=", "in", "not in")) +LITERAL_NODE_TYPES = (astroid.Const, astroid.Dict, astroid.List, astroid.Set) +UNITTEST_CASE = "unittest.case" +BUILTINS = builtins.__name__ +TYPE_QNAME = "%s.type" % BUILTINS +PY33 = sys.version_info >= (3, 3) +PY3K = sys.version_info >= (3, 0) +PY35 = sys.version_info >= (3, 5) +ABC_METACLASSES = {"_py_abc.ABCMeta", "abc.ABCMeta"} # Python 3.7+, + +# Name categories that are always consistent with all naming conventions. +EXEMPT_NAME_CATEGORIES = {"exempt", "ignore"} + +# A mapping from builtin-qname -> symbol, to be used when generating messages +# about dangerous default values as arguments +DEFAULT_ARGUMENT_SYMBOLS = dict( + zip( + [".".join([BUILTINS, x]) for x in ("set", "dict", "list")], + ["set()", "{}", "[]"], + ) +) +REVERSED_COMPS = {"<": ">", "<=": ">=", ">": "<", ">=": "<="} +COMPARISON_OPERATORS = frozenset(("==", "!=", "<", ">", "<=", ">=")) +# List of methods which can be redefined +REDEFINABLE_METHODS = frozenset(("__module__",)) + + +def _redefines_import(node): + """ Detect that the given node (AssignName) is inside an + exception handler and redefines an import from the tryexcept body. + Returns True if the node redefines an import, False otherwise. + """ + current = node + while current and not isinstance(current.parent, astroid.ExceptHandler): + current = current.parent + if not current or not utils.error_of_type(current.parent, ImportError): + return False + try_block = current.parent.parent + for import_node in try_block.nodes_of_class((astroid.ImportFrom, astroid.Import)): + for name, alias in import_node.names: + if alias: + if alias == node.name: + return True + elif name == node.name: + return True + return False + + +def in_loop(node): + """return True if the node is inside a kind of for loop""" + parent = node.parent + while parent is not None: + if isinstance( + parent, + ( + astroid.For, + astroid.ListComp, + astroid.SetComp, + astroid.DictComp, + astroid.GeneratorExp, + ), + ): + return True + parent = parent.parent + return False + + +def in_nested_list(nested_list, obj): + """return true if the object is an element of <nested_list> or of a nested + list + """ + for elmt in nested_list: + if isinstance(elmt, (list, tuple)): + if in_nested_list(elmt, obj): + return True + elif elmt == obj: + return True + return False + + +def _get_break_loop_node(break_node): + """ + Returns the loop node that holds the break node in arguments. + + Args: + break_node (astroid.Break): the break node of interest. + + Returns: + astroid.For or astroid.While: the loop node holding the break node. + """ + loop_nodes = (astroid.For, astroid.While) + parent = break_node.parent + while not isinstance(parent, loop_nodes) or break_node in getattr( + parent, "orelse", [] + ): + parent = parent.parent + if parent is None: + break + return parent + + +def _loop_exits_early(loop): + """ + Returns true if a loop may ends up in a break statement. + + Args: + loop (astroid.For, astroid.While): the loop node inspected. + + Returns: + bool: True if the loop may ends up in a break statement, False otherwise. + """ + loop_nodes = (astroid.For, astroid.While) + definition_nodes = (astroid.FunctionDef, astroid.ClassDef) + inner_loop_nodes = [ + _node + for _node in loop.nodes_of_class(loop_nodes, skip_klass=definition_nodes) + if _node != loop + ] + return any( + _node + for _node in loop.nodes_of_class(astroid.Break, skip_klass=definition_nodes) + if _get_break_loop_node(_node) not in inner_loop_nodes + ) + + +def _is_multi_naming_match(match, node_type, confidence): + return ( + match is not None + and match.lastgroup is not None + and match.lastgroup not in EXEMPT_NAME_CATEGORIES + and (node_type != "method" or confidence != interfaces.INFERENCE_FAILURE) + ) + + +BUILTIN_PROPERTY = "builtins.property" + + +def _get_properties(config): + """Returns a tuple of property classes and names. + + Property classes are fully qualified, such as 'abc.abstractproperty' and + property names are the actual names, such as 'abstract_property'. + """ + property_classes = {BUILTIN_PROPERTY} + property_names = set() # Not returning 'property', it has its own check. + if config is not None: + property_classes.update(config.property_classes) + property_names.update( + (prop.rsplit(".", 1)[-1] for prop in config.property_classes) + ) + return property_classes, property_names + + +def _determine_function_name_type(node, config=None): + """Determine the name type whose regex the a function's name should match. + + :param node: A function node. + :type node: astroid.node_classes.NodeNG + :param config: Configuration from which to pull additional property classes. + :type config: :class:`optparse.Values` + + :returns: One of ('function', 'method', 'attr') + :rtype: str + """ + property_classes, property_names = _get_properties(config) + if not node.is_method(): + return "function" + if node.decorators: + decorators = node.decorators.nodes + else: + decorators = [] + for decorator in decorators: + # If the function is a property (decorated with @property + # or @abc.abstractproperty), the name type is 'attr'. + if isinstance(decorator, astroid.Name) or ( + isinstance(decorator, astroid.Attribute) + and decorator.attrname in property_names + ): + infered = utils.safe_infer(decorator) + if infered and infered.qname() in property_classes: + return "attr" + # If the function is decorated using the prop_method.{setter,getter} + # form, treat it like an attribute as well. + elif isinstance(decorator, astroid.Attribute) and decorator.attrname in ( + "setter", + "deleter", + ): + return "attr" + return "method" + + +def _has_abstract_methods(node): + """ + Determine if the given `node` has abstract methods. + + The methods should be made abstract by decorating them + with `abc` decorators. + """ + return len(utils.unimplemented_abstract_methods(node)) > 0 + + +def report_by_type_stats(sect, stats, old_stats): + """make a report of + + * percentage of different types documented + * percentage of different types with a bad name + """ + # percentage of different types documented and/or with a bad name + nice_stats = {} + for node_type in ("module", "class", "method", "function"): + try: + total = stats[node_type] + except KeyError: + raise exceptions.EmptyReportError() + nice_stats[node_type] = {} + if total != 0: + try: + documented = total - stats["undocumented_" + node_type] + percent = (documented * 100.) / total + nice_stats[node_type]["percent_documented"] = "%.2f" % percent + except KeyError: + nice_stats[node_type]["percent_documented"] = "NC" + try: + percent = (stats["badname_" + node_type] * 100.) / total + nice_stats[node_type]["percent_badname"] = "%.2f" % percent + except KeyError: + nice_stats[node_type]["percent_badname"] = "NC" + lines = ("type", "number", "old number", "difference", "%documented", "%badname") + for node_type in ("module", "class", "method", "function"): + new = stats[node_type] + old = old_stats.get(node_type, None) + if old is not None: + diff_str = reporters.diff_string(old, new) + else: + old, diff_str = "NC", "NC" + lines += ( + node_type, + str(new), + str(old), + diff_str, + nice_stats[node_type].get("percent_documented", "0"), + nice_stats[node_type].get("percent_badname", "0"), + ) + sect.append(reporter_nodes.Table(children=lines, cols=6, rheaders=1)) + + +def redefined_by_decorator(node): + """return True if the object is a method redefined via decorator. + + For example: + @property + def x(self): return self._x + @x.setter + def x(self, value): self._x = value + """ + if node.decorators: + for decorator in node.decorators.nodes: + if ( + isinstance(decorator, astroid.Attribute) + and getattr(decorator.expr, "name", None) == node.name + ): + return True + return False + + +class _BasicChecker(checkers.BaseChecker): + __implements__ = interfaces.IAstroidChecker + name = "basic" + + +class BasicErrorChecker(_BasicChecker): + msgs = { + "E0100": ( + "__init__ method is a generator", + "init-is-generator", + "Used when the special class method __init__ is turned into a " + "generator by a yield in its body.", + ), + "E0101": ( + "Explicit return in __init__", + "return-in-init", + "Used when the special class method __init__ has an explicit " + "return value.", + ), + "E0102": ( + "%s already defined line %s", + "function-redefined", + "Used when a function / class / method is redefined.", + ), + "E0103": ( + "%r not properly in loop", + "not-in-loop", + "Used when break or continue keywords are used outside a loop.", + ), + "E0104": ( + "Return outside function", + "return-outside-function", + 'Used when a "return" statement is found outside a function or method.', + ), + "E0105": ( + "Yield outside function", + "yield-outside-function", + 'Used when a "yield" statement is found outside a function or method.', + ), + "E0106": ( + "Return with argument inside generator", + "return-arg-in-generator", + 'Used when a "return" statement with an argument is found ' + "outside in a generator function or method (e.g. with some " + '"yield" statements).', + {"maxversion": (3, 3)}, + ), + "E0107": ( + "Use of the non-existent %s operator", + "nonexistent-operator", + "Used when you attempt to use the C-style pre-increment or " + "pre-decrement operator -- and ++, which doesn't exist in Python.", + ), + "E0108": ( + "Duplicate argument name %s in function definition", + "duplicate-argument-name", + "Duplicate argument names in function definitions are syntax errors.", + ), + "E0110": ( + "Abstract class %r with abstract methods instantiated", + "abstract-class-instantiated", + "Used when an abstract class with `abc.ABCMeta` as metaclass " + "has abstract methods and is instantiated.", + ), + "W0120": ( + "Else clause on loop without a break statement", + "useless-else-on-loop", + "Loops should only have an else clause if they can exit early " + "with a break statement, otherwise the statements under else " + "should be on the same scope as the loop itself.", + ), + "E0112": ( + "More than one starred expression in assignment", + "too-many-star-expressions", + "Emitted when there are more than one starred " + "expressions (`*x`) in an assignment. This is a SyntaxError.", + ), + "E0113": ( + "Starred assignment target must be in a list or tuple", + "invalid-star-assignment-target", + "Emitted when a star expression is used as a starred assignment target.", + ), + "E0114": ( + "Can use starred expression only in assignment target", + "star-needs-assignment-target", + "Emitted when a star expression is not used in an assignment target.", + ), + "E0115": ( + "Name %r is nonlocal and global", + "nonlocal-and-global", + "Emitted when a name is both nonlocal and global.", + ), + "E0116": ( + "'continue' not supported inside 'finally' clause", + "continue-in-finally", + "Emitted when the `continue` keyword is found " + "inside a finally clause, which is a SyntaxError.", + ), + "E0117": ( + "nonlocal name %s found without binding", + "nonlocal-without-binding", + "Emitted when a nonlocal variable does not have an attached " + "name somewhere in the parent scopes", + ), + "E0118": ( + "Name %r is used prior to global declaration", + "used-prior-global-declaration", + "Emitted when a name is used prior a global declaration, " + "which results in an error since Python 3.6.", + {"minversion": (3, 6)}, + ), + } + + @utils.check_messages("function-redefined") + def visit_classdef(self, node): + self._check_redefinition("class", node) + + def _too_many_starred_for_tuple(self, assign_tuple): + starred_count = 0 + for elem in assign_tuple.itered(): + if isinstance(elem, astroid.Tuple): + return self._too_many_starred_for_tuple(elem) + if isinstance(elem, astroid.Starred): + starred_count += 1 + return starred_count > 1 + + @utils.check_messages("too-many-star-expressions", "invalid-star-assignment-target") + def visit_assign(self, node): + # Check *a, *b = ... + assign_target = node.targets[0] + # Check *a = b + if isinstance(node.targets[0], astroid.Starred): + self.add_message("invalid-star-assignment-target", node=node) + + if not isinstance(assign_target, astroid.Tuple): + return + if self._too_many_starred_for_tuple(assign_target): + self.add_message("too-many-star-expressions", node=node) + + @utils.check_messages("star-needs-assignment-target") + def visit_starred(self, node): + """Check that a Starred expression is used in an assignment target.""" + if isinstance(node.parent, astroid.Call): + # f(*args) is converted to Call(args=[Starred]), so ignore + # them for this check. + return + if PY35 and isinstance( + node.parent, (astroid.List, astroid.Tuple, astroid.Set, astroid.Dict) + ): + # PEP 448 unpacking. + return + + stmt = node.statement() + if not isinstance(stmt, astroid.Assign): + return + + if stmt.value is node or stmt.value.parent_of(node): + self.add_message("star-needs-assignment-target", node=node) + + @utils.check_messages( + "init-is-generator", + "return-in-init", + "function-redefined", + "return-arg-in-generator", + "duplicate-argument-name", + "nonlocal-and-global", + "used-prior-global-declaration", + ) + def visit_functiondef(self, node): + self._check_nonlocal_and_global(node) + self._check_name_used_prior_global(node) + if not redefined_by_decorator( + node + ) and not utils.is_registered_in_singledispatch_function(node): + self._check_redefinition(node.is_method() and "method" or "function", node) + # checks for max returns, branch, return in __init__ + returns = node.nodes_of_class( + astroid.Return, skip_klass=(astroid.FunctionDef, astroid.ClassDef) + ) + if node.is_method() and node.name == "__init__": + if node.is_generator(): + self.add_message("init-is-generator", node=node) + else: + values = [r.value for r in returns] + # Are we returning anything but None from constructors + if any(v for v in values if not utils.is_none(v)): + self.add_message("return-in-init", node=node) + elif node.is_generator(): + # make sure we don't mix non-None returns and yields + if not PY33: + for retnode in returns: + if ( + isinstance(retnode.value, astroid.Const) + and retnode.value.value is not None + ): + self.add_message( + "return-arg-in-generator", + node=node, + line=retnode.fromlineno, + ) + # Check for duplicate names by clustering args with same name for detailed report + arg_clusters = collections.defaultdict(list) + arguments = filter(None, [node.args.args, node.args.kwonlyargs]) + + for arg in itertools.chain.from_iterable(arguments): + arg_clusters[arg.name].append(arg) + + # provide detailed report about each repeated argument + for argument_duplicates in arg_clusters.values(): + if len(argument_duplicates) != 1: + for argument in argument_duplicates: + self.add_message( + "duplicate-argument-name", + line=argument.lineno, + node=argument, + args=(argument.name,), + ) + + visit_asyncfunctiondef = visit_functiondef + + def _check_name_used_prior_global(self, node): + + scope_globals = { + name: child + for child in node.nodes_of_class(astroid.Global) + for name in child.names + if child.scope() is node + } + + if not scope_globals: + return + + for node_name in node.nodes_of_class(astroid.Name): + if node_name.scope() is not node: + continue + + name = node_name.name + corresponding_global = scope_globals.get(name) + if not corresponding_global: + continue + + global_lineno = corresponding_global.fromlineno + if global_lineno and global_lineno > node_name.fromlineno: + self.add_message( + "used-prior-global-declaration", node=node_name, args=(name,) + ) + + def _check_nonlocal_and_global(self, node): + """Check that a name is both nonlocal and global.""" + + def same_scope(current): + return current.scope() is node + + from_iter = itertools.chain.from_iterable + nonlocals = set( + from_iter( + child.names + for child in node.nodes_of_class(astroid.Nonlocal) + if same_scope(child) + ) + ) + + if not nonlocals: + return + + global_vars = set( + from_iter( + child.names + for child in node.nodes_of_class(astroid.Global) + if same_scope(child) + ) + ) + for name in nonlocals.intersection(global_vars): + self.add_message("nonlocal-and-global", args=(name,), node=node) + + @utils.check_messages("return-outside-function") + def visit_return(self, node): + if not isinstance(node.frame(), astroid.FunctionDef): + self.add_message("return-outside-function", node=node) + + @utils.check_messages("yield-outside-function") + def visit_yield(self, node): + self._check_yield_outside_func(node) + + @utils.check_messages("yield-outside-function") + def visit_yieldfrom(self, node): + self._check_yield_outside_func(node) + + @utils.check_messages("not-in-loop", "continue-in-finally") + def visit_continue(self, node): + self._check_in_loop(node, "continue") + + @utils.check_messages("not-in-loop") + def visit_break(self, node): + self._check_in_loop(node, "break") + + @utils.check_messages("useless-else-on-loop") + def visit_for(self, node): + self._check_else_on_loop(node) + + @utils.check_messages("useless-else-on-loop") + def visit_while(self, node): + self._check_else_on_loop(node) + + @utils.check_messages("nonexistent-operator") + def visit_unaryop(self, node): + """check use of the non-existent ++ and -- operator operator""" + if ( + (node.op in "+-") + and isinstance(node.operand, astroid.UnaryOp) + and (node.operand.op == node.op) + ): + self.add_message("nonexistent-operator", node=node, args=node.op * 2) + + def _check_nonlocal_without_binding(self, node, name): + current_scope = node.scope() + while True: + if current_scope.parent is None: + break + + if not isinstance(current_scope, (astroid.ClassDef, astroid.FunctionDef)): + self.add_message("nonlocal-without-binding", args=(name,), node=node) + return + + if name not in current_scope.locals: + current_scope = current_scope.parent.scope() + continue + + # Okay, found it. + return + + if not isinstance(current_scope, astroid.FunctionDef): + self.add_message("nonlocal-without-binding", args=(name,), node=node) + + @utils.check_messages("nonlocal-without-binding") + def visit_nonlocal(self, node): + for name in node.names: + self._check_nonlocal_without_binding(node, name) + + @utils.check_messages("abstract-class-instantiated") + def visit_call(self, node): + """ Check instantiating abstract class with + abc.ABCMeta as metaclass. + """ + try: + for inferred in node.func.infer(): + self._check_inferred_class_is_abstract(inferred, node) + except astroid.InferenceError: + return + + def _check_inferred_class_is_abstract(self, infered, node): + if not isinstance(infered, astroid.ClassDef): + return + + klass = utils.node_frame_class(node) + if klass is infered: + # Don't emit the warning if the class is instantiated + # in its own body or if the call is not an instance + # creation. If the class is instantiated into its own + # body, we're expecting that it knows what it is doing. + return + + # __init__ was called + abstract_methods = _has_abstract_methods(infered) + + if not abstract_methods: + return + + metaclass = infered.metaclass() + + if metaclass is None: + # Python 3.4 has `abc.ABC`, which won't be detected + # by ClassNode.metaclass() + for ancestor in infered.ancestors(): + if ancestor.qname() == "abc.ABC": + self.add_message( + "abstract-class-instantiated", args=(infered.name,), node=node + ) + break + + return + + if metaclass.qname() in ABC_METACLASSES: + self.add_message( + "abstract-class-instantiated", args=(infered.name,), node=node + ) + + def _check_yield_outside_func(self, node): + if not isinstance(node.frame(), (astroid.FunctionDef, astroid.Lambda)): + self.add_message("yield-outside-function", node=node) + + def _check_else_on_loop(self, node): + """Check that any loop with an else clause has a break statement.""" + if node.orelse and not _loop_exits_early(node): + self.add_message( + "useless-else-on-loop", + node=node, + # This is not optimal, but the line previous + # to the first statement in the else clause + # will usually be the one that contains the else:. + line=node.orelse[0].lineno - 1, + ) + + def _check_in_loop(self, node, node_name): + """check that a node is inside a for or while loop""" + _node = node.parent + while _node: + if isinstance(_node, (astroid.For, astroid.While)): + if node not in _node.orelse: + return + + if isinstance(_node, (astroid.ClassDef, astroid.FunctionDef)): + break + if ( + isinstance(_node, astroid.TryFinally) + and node in _node.finalbody + and isinstance(node, astroid.Continue) + ): + self.add_message("continue-in-finally", node=node) + + _node = _node.parent + + self.add_message("not-in-loop", node=node, args=node_name) + + def _check_redefinition(self, redeftype, node): + """check for redefinition of a function / method / class name""" + parent_frame = node.parent.frame() + defined_self = parent_frame[node.name] + if defined_self is not node and not astroid.are_exclusive(node, defined_self): + + # Additional checks for methods which are not considered + # redefined, since they are already part of the base API. + if ( + isinstance(parent_frame, astroid.ClassDef) + and node.name in REDEFINABLE_METHODS + ): + return + + dummy_variables_rgx = lint_utils.get_global_option( + self, "dummy-variables-rgx", default=None + ) + if dummy_variables_rgx and dummy_variables_rgx.match(node.name): + return + self.add_message( + "function-redefined", + node=node, + args=(redeftype, defined_self.fromlineno), + ) + + +class BasicChecker(_BasicChecker): + """checks for : + * doc strings + * number of arguments, local variables, branches, returns and statements in + functions, methods + * required module attributes + * dangerous default values as arguments + * redefinition of function / method / class + * uses of the global statement + """ + + __implements__ = interfaces.IAstroidChecker + + name = "basic" + msgs = { + "W0101": ( + "Unreachable code", + "unreachable", + 'Used when there is some code behind a "return" or "raise" ' + "statement, which will never be accessed.", + ), + "W0102": ( + "Dangerous default value %s as argument", + "dangerous-default-value", + "Used when a mutable value as list or dictionary is detected in " + "a default value for an argument.", + ), + "W0104": ( + "Statement seems to have no effect", + "pointless-statement", + "Used when a statement doesn't have (or at least seems to) any effect.", + ), + "W0105": ( + "String statement has no effect", + "pointless-string-statement", + "Used when a string is used as a statement (which of course " + "has no effect). This is a particular case of W0104 with its " + "own message so you can easily disable it if you're using " + "those strings as documentation, instead of comments.", + ), + "W0106": ( + 'Expression "%s" is assigned to nothing', + "expression-not-assigned", + "Used when an expression that is not a function call is assigned " + "to nothing. Probably something else was intended.", + ), + "W0108": ( + "Lambda may not be necessary", + "unnecessary-lambda", + "Used when the body of a lambda expression is a function call " + "on the same argument list as the lambda itself; such lambda " + "expressions are in all but a few cases replaceable with the " + "function being called in the body of the lambda.", + ), + "W0109": ( + "Duplicate key %r in dictionary", + "duplicate-key", + "Used when a dictionary expression binds the same key multiple times.", + ), + "W0122": ( + "Use of exec", + "exec-used", + 'Used when you use the "exec" statement (function for Python ' + "3), to discourage its usage. That doesn't " + "mean you cannot use it !", + ), + "W0123": ( + "Use of eval", + "eval-used", + 'Used when you use the "eval" function, to discourage its ' + "usage. Consider using `ast.literal_eval` for safely evaluating " + "strings containing Python expressions " + "from untrusted sources. ", + ), + "W0150": ( + "%s statement in finally block may swallow exception", + "lost-exception", + "Used when a break or a return statement is found inside the " + "finally clause of a try...finally block: the exceptions raised " + "in the try clause will be silently swallowed instead of being " + "re-raised.", + ), + "W0199": ( + "Assert called on a 2-uple. Did you mean 'assert x,y'?", + "assert-on-tuple", + "A call of assert on a tuple will always evaluate to true if " + "the tuple is not empty, and will always evaluate to false if " + "it is.", + ), + "W0124": ( + 'Following "as" with another context manager looks like a tuple.', + "confusing-with-statement", + "Emitted when a `with` statement component returns multiple values " + "and uses name binding with `as` only for a part of those values, " + "as in with ctx() as a, b. This can be misleading, since it's not " + "clear if the context manager returns a tuple or if the node without " + "a name binding is another context manager.", + ), + "W0125": ( + "Using a conditional statement with a constant value", + "using-constant-test", + "Emitted when a conditional statement (If or ternary if) " + "uses a constant value for its test. This might not be what " + "the user intended to do.", + ), + "E0111": ( + "The first reversed() argument is not a sequence", + "bad-reversed-sequence", + "Used when the first argument to reversed() builtin " + "isn't a sequence (does not implement __reversed__, " + "nor __getitem__ and __len__", + ), + "E0119": ( + "format function is not called on str", + "misplaced-format-function", + "Emitted when format function is not called on str object. " + 'e.g doing print("value: {}").format(123) instead of ' + 'print("value: {}".format(123)). This might not be what the user ' + "intended to do.", + ), + } + + reports = (("RP0101", "Statistics by type", report_by_type_stats),) + + def __init__(self, linter): + _BasicChecker.__init__(self, linter) + self.stats = None + self._tryfinallys = None + + def open(self): + """initialize visit variables and statistics + """ + self._tryfinallys = [] + self.stats = self.linter.add_stats(module=0, function=0, method=0, class_=0) + + @utils.check_messages("using-constant-test") + def visit_if(self, node): + self._check_using_constant_test(node, node.test) + + @utils.check_messages("using-constant-test") + def visit_ifexp(self, node): + self._check_using_constant_test(node, node.test) + + @utils.check_messages("using-constant-test") + def visit_comprehension(self, node): + if node.ifs: + for if_test in node.ifs: + self._check_using_constant_test(node, if_test) + + def _check_using_constant_test(self, node, test): + const_nodes = ( + astroid.Module, + astroid.scoped_nodes.GeneratorExp, + astroid.Lambda, + astroid.FunctionDef, + astroid.ClassDef, + astroid.bases.Generator, + astroid.UnboundMethod, + astroid.BoundMethod, + astroid.Module, + ) + structs = (astroid.Dict, astroid.Tuple, astroid.Set) + + # These nodes are excepted, since they are not constant + # values, requiring a computation to happen. The only type + # of node in this list which doesn't have this property is + # Attribute, which is excepted because the conditional statement + # can be used to verify that the attribute was set inside a class, + # which is definitely a valid use case. + except_nodes = ( + astroid.Attribute, + astroid.Call, + astroid.BinOp, + astroid.BoolOp, + astroid.UnaryOp, + astroid.Subscript, + ) + inferred = None + emit = isinstance(test, (astroid.Const,) + structs + const_nodes) + if not isinstance(test, except_nodes): + inferred = utils.safe_infer(test) + + if emit or isinstance(inferred, const_nodes): + self.add_message("using-constant-test", node=node) + + def visit_module(self, _): + """check module name, docstring and required arguments + """ + self.stats["module"] += 1 + + def visit_classdef(self, node): # pylint: disable=unused-argument + """check module name, docstring and redefinition + increment branch counter + """ + self.stats["class"] += 1 + + @utils.check_messages( + "pointless-statement", "pointless-string-statement", "expression-not-assigned" + ) + def visit_expr(self, node): + """check for various kind of statements without effect""" + expr = node.value + if isinstance(expr, astroid.Const) and isinstance(expr.value, str): + # treat string statement in a separated message + # Handle PEP-257 attribute docstrings. + # An attribute docstring is defined as being a string right after + # an assignment at the module level, class level or __init__ level. + scope = expr.scope() + if isinstance( + scope, (astroid.ClassDef, astroid.Module, astroid.FunctionDef) + ): + if isinstance(scope, astroid.FunctionDef) and scope.name != "__init__": + pass + else: + sibling = expr.previous_sibling() + if ( + sibling is not None + and sibling.scope() is scope + and isinstance(sibling, (astroid.Assign, astroid.AnnAssign)) + ): + return + self.add_message("pointless-string-statement", node=node) + return + # ignore if this is : + # * a direct function call + # * the unique child of a try/except body + # * a yield (which are wrapped by a discard node in _ast XXX) + # warn W0106 if we have any underlying function call (we can't predict + # side effects), else pointless-statement + if isinstance(expr, (astroid.Yield, astroid.Await, astroid.Call)) or ( + isinstance(node.parent, astroid.TryExcept) and node.parent.body == [node] + ): + return + if any(expr.nodes_of_class(astroid.Call)): + self.add_message( + "expression-not-assigned", node=node, args=expr.as_string() + ) + else: + self.add_message("pointless-statement", node=node) + + @staticmethod + def _filter_vararg(node, call_args): + # Return the arguments for the given call which are + # not passed as vararg. + for arg in call_args: + if isinstance(arg, astroid.Starred): + if ( + isinstance(arg.value, astroid.Name) + and arg.value.name != node.args.vararg + ): + yield arg + else: + yield arg + + @staticmethod + def _has_variadic_argument(args, variadic_name): + if not args: + return True + for arg in args: + if isinstance(arg.value, astroid.Name): + if arg.value.name != variadic_name: + return True + else: + return True + return False + + @utils.check_messages("unnecessary-lambda") + def visit_lambda(self, node): + """check whether or not the lambda is suspicious + """ + # if the body of the lambda is a call expression with the same + # argument list as the lambda itself, then the lambda is + # possibly unnecessary and at least suspicious. + if node.args.defaults: + # If the arguments of the lambda include defaults, then a + # judgment cannot be made because there is no way to check + # that the defaults defined by the lambda are the same as + # the defaults defined by the function called in the body + # of the lambda. + return + call = node.body + if not isinstance(call, astroid.Call): + # The body of the lambda must be a function call expression + # for the lambda to be unnecessary. + return + if isinstance(node.body.func, astroid.Attribute) and isinstance( + node.body.func.expr, astroid.Call + ): + # Chained call, the intermediate call might + # return something else (but we don't check that, yet). + return + + ordinary_args = list(node.args.args) + new_call_args = list(self._filter_vararg(node, call.args)) + if node.args.kwarg: + if self._has_variadic_argument(call.kwargs, node.args.kwarg): + return + elif call.kwargs or call.keywords: + return + + if node.args.vararg: + if self._has_variadic_argument(call.starargs, node.args.vararg): + return + elif call.starargs: + return + + # The "ordinary" arguments must be in a correspondence such that: + # ordinary_args[i].name == call.args[i].name. + if len(ordinary_args) != len(new_call_args): + return + for arg, passed_arg in zip(ordinary_args, new_call_args): + if not isinstance(passed_arg, astroid.Name): + return + if arg.name != passed_arg.name: + return + + self.add_message("unnecessary-lambda", line=node.fromlineno, node=node) + + @utils.check_messages("dangerous-default-value") + def visit_functiondef(self, node): + """check function name, docstring, arguments, redefinition, + variable names, max locals + """ + self.stats[node.is_method() and "method" or "function"] += 1 + self._check_dangerous_default(node) + + visit_asyncfunctiondef = visit_functiondef + + def _check_dangerous_default(self, node): + # check for dangerous default values as arguments + is_iterable = lambda n: isinstance(n, (astroid.List, astroid.Set, astroid.Dict)) + for default in node.args.defaults: + try: + value = next(default.infer()) + except astroid.InferenceError: + continue + + if ( + isinstance(value, astroid.Instance) + and value.qname() in DEFAULT_ARGUMENT_SYMBOLS + ): + + if value is default: + msg = DEFAULT_ARGUMENT_SYMBOLS[value.qname()] + elif isinstance(value, astroid.Instance) or is_iterable(value): + # We are here in the following situation(s): + # * a dict/set/list/tuple call which wasn't inferred + # to a syntax node ({}, () etc.). This can happen + # when the arguments are invalid or unknown to + # the inference. + # * a variable from somewhere else, which turns out to be a list + # or a dict. + if is_iterable(default): + msg = value.pytype() + elif isinstance(default, astroid.Call): + msg = "%s() (%s)" % (value.name, value.qname()) + else: + msg = "%s (%s)" % (default.as_string(), value.qname()) + else: + # this argument is a name + msg = "%s (%s)" % ( + default.as_string(), + DEFAULT_ARGUMENT_SYMBOLS[value.qname()], + ) + self.add_message("dangerous-default-value", node=node, args=(msg,)) + + @utils.check_messages("unreachable", "lost-exception") + def visit_return(self, node): + """1 - check is the node has a right sibling (if so, that's some + unreachable code) + 2 - check is the node is inside the finally clause of a try...finally + block + """ + self._check_unreachable(node) + # Is it inside final body of a try...finally bloc ? + self._check_not_in_finally(node, "return", (astroid.FunctionDef,)) + + @utils.check_messages("unreachable") + def visit_continue(self, node): + """check is the node has a right sibling (if so, that's some unreachable + code) + """ + self._check_unreachable(node) + + @utils.check_messages("unreachable", "lost-exception") + def visit_break(self, node): + """1 - check is the node has a right sibling (if so, that's some + unreachable code) + 2 - check is the node is inside the finally clause of a try...finally + block + """ + # 1 - Is it right sibling ? + self._check_unreachable(node) + # 2 - Is it inside final body of a try...finally bloc ? + self._check_not_in_finally(node, "break", (astroid.For, astroid.While)) + + @utils.check_messages("unreachable") + def visit_raise(self, node): + """check if the node has a right sibling (if so, that's some unreachable + code) + """ + self._check_unreachable(node) + + @utils.check_messages("exec-used") + def visit_exec(self, node): + """just print a warning on exec statements""" + self.add_message("exec-used", node=node) + + def _check_misplaced_format_function(self, call_node): + if not isinstance(call_node.func, astroid.Attribute): + return + if call_node.func.attrname != "format": + return + + expr = utils.safe_infer(call_node.func.expr) + if expr is astroid.Uninferable: + return + if not expr: + # we are doubtful on inferred type of node, so here just check if format + # was called on print() + call_expr = call_node.func.expr + if not isinstance(call_expr, astroid.Call): + return + if ( + isinstance(call_expr.func, astroid.Name) + and call_expr.func.name == "print" + ): + self.add_message("misplaced-format-function", node=call_node) + + @utils.check_messages( + "eval-used", "exec-used", "bad-reversed-sequence", "misplaced-format-function" + ) + def visit_call(self, node): + """visit a Call node -> check if this is not a blacklisted builtin + call and check for * or ** use + """ + self._check_misplaced_format_function(node) + if isinstance(node.func, astroid.Name): + name = node.func.name + # ignore the name if it's not a builtin (i.e. not defined in the + # locals nor globals scope) + if not (name in node.frame() or name in node.root()): + if name == "exec": + self.add_message("exec-used", node=node) + elif name == "reversed": + self._check_reversed(node) + elif name == "eval": + self.add_message("eval-used", node=node) + + @utils.check_messages("assert-on-tuple") + def visit_assert(self, node): + """check the use of an assert statement on a tuple.""" + if ( + node.fail is None + and isinstance(node.test, astroid.Tuple) + and len(node.test.elts) == 2 + ): + self.add_message("assert-on-tuple", node=node) + + @utils.check_messages("duplicate-key") + def visit_dict(self, node): + """check duplicate key in dictionary""" + keys = set() + for k, _ in node.items: + if isinstance(k, astroid.Const): + key = k.value + if key in keys: + self.add_message("duplicate-key", node=node, args=key) + keys.add(key) + + def visit_tryfinally(self, node): + """update try...finally flag""" + self._tryfinallys.append(node) + + def leave_tryfinally(self, node): # pylint: disable=unused-argument + """update try...finally flag""" + self._tryfinallys.pop() + + def _check_unreachable(self, node): + """check unreachable code""" + unreach_stmt = node.next_sibling() + if unreach_stmt is not None: + self.add_message("unreachable", node=unreach_stmt) + + def _check_not_in_finally(self, node, node_name, breaker_classes=()): + """check that a node is not inside a finally clause of a + try...finally statement. + If we found before a try...finally bloc a parent which its type is + in breaker_classes, we skip the whole check.""" + # if self._tryfinallys is empty, we're not an in try...finally block + if not self._tryfinallys: + return + # the node could be a grand-grand...-children of the try...finally + _parent = node.parent + _node = node + while _parent and not isinstance(_parent, breaker_classes): + if hasattr(_parent, "finalbody") and _node in _parent.finalbody: + self.add_message("lost-exception", node=node, args=node_name) + return + _node = _parent + _parent = _node.parent + + def _check_reversed(self, node): + """ check that the argument to `reversed` is a sequence """ + try: + argument = utils.safe_infer(utils.get_argument_from_call(node, position=0)) + except utils.NoSuchArgumentError: + pass + else: + if argument is astroid.Uninferable: + return + if argument is None: + # Nothing was infered. + # Try to see if we have iter(). + if isinstance(node.args[0], astroid.Call): + try: + func = next(node.args[0].func.infer()) + except astroid.InferenceError: + return + if getattr( + func, "name", None + ) == "iter" and utils.is_builtin_object(func): + self.add_message("bad-reversed-sequence", node=node) + return + + if isinstance(argument, astroid.Instance): + if argument._proxied.name == "dict" and utils.is_builtin_object( + argument._proxied + ): + self.add_message("bad-reversed-sequence", node=node) + return + if any( + ancestor.name == "dict" and utils.is_builtin_object(ancestor) + for ancestor in argument._proxied.ancestors() + ): + # Mappings aren't accepted by reversed(), unless + # they provide explicitly a __reversed__ method. + try: + argument.locals[REVERSED_PROTOCOL_METHOD] + except KeyError: + self.add_message("bad-reversed-sequence", node=node) + return + + for methods in REVERSED_METHODS: + for meth in methods: + try: + argument.getattr(meth) + except astroid.NotFoundError: + break + else: + break + else: + self.add_message("bad-reversed-sequence", node=node) + elif not isinstance(argument, (astroid.List, astroid.Tuple)): + # everything else is not a proper sequence for reversed() + self.add_message("bad-reversed-sequence", node=node) + + @utils.check_messages("confusing-with-statement") + def visit_with(self, node): + if not PY3K: + # in Python 2 a "with" statement with multiple managers coresponds + # to multiple nested AST "With" nodes + pairs = [] + parent_node = node.parent + if isinstance(parent_node, astroid.With): + # we only care about the direct parent, since this method + # gets called for each with node anyway + pairs.extend(parent_node.items) + pairs.extend(node.items) + else: + # in PY3K a "with" statement with multiple managers coresponds + # to one AST "With" node with multiple items + pairs = node.items + if pairs: + for prev_pair, pair in zip(pairs, pairs[1:]): + if isinstance(prev_pair[1], astroid.AssignName) and ( + pair[1] is None and not isinstance(pair[0], astroid.Call) + ): + # don't emit a message if the second is a function call + # there's no way that can be mistaken for a name assignment + if PY3K or node.lineno == node.parent.lineno: + # if the line number doesn't match + # we assume it's a nested "with" + self.add_message("confusing-with-statement", node=node) + + +KNOWN_NAME_TYPES = { + "module", + "const", + "class", + "function", + "method", + "attr", + "argument", + "variable", + "class_attribute", + "inlinevar", +} + + +HUMAN_READABLE_TYPES = { + "module": "module", + "const": "constant", + "class": "class", + "function": "function", + "method": "method", + "attr": "attribute", + "argument": "argument", + "variable": "variable", + "class_attribute": "class attribute", + "inlinevar": "inline iteration", +} + +DEFAULT_NAMING_STYLES = { + "module": "snake_case", + "const": "UPPER_CASE", + "class": "PascalCase", + "function": "snake_case", + "method": "snake_case", + "attr": "snake_case", + "argument": "snake_case", + "variable": "snake_case", + "class_attribute": "any", + "inlinevar": "any", +} + + +def _create_naming_options(): + name_options = [] + for name_type in sorted(KNOWN_NAME_TYPES): + human_readable_name = HUMAN_READABLE_TYPES[name_type] + default_style = DEFAULT_NAMING_STYLES[name_type] + name_type = name_type.replace("_", "-") + name_options.append( + ( + "%s-naming-style" % (name_type,), + { + "default": default_style, + "type": "choice", + "choices": list(NAMING_STYLES.keys()), + "metavar": "<style>", + "help": "Naming style matching correct %s names." + % (human_readable_name,), + }, + ) + ) + name_options.append( + ( + "%s-rgx" % (name_type,), + { + "default": None, + "type": "regexp", + "metavar": "<regexp>", + "help": "Regular expression matching correct %s names. Overrides %s-naming-style." + % (human_readable_name, name_type), + }, + ) + ) + return tuple(name_options) + + +class NameChecker(_BasicChecker): + + msgs = { + "C0102": ( + 'Black listed name "%s"', + "blacklisted-name", + "Used when the name is listed in the black list (unauthorized names).", + ), + "C0103": ( + '%s name "%s" doesn\'t conform to %s', + "invalid-name", + "Used when the name doesn't conform to naming rules " + "associated to its type (constant, variable, class...).", + ), + "W0111": ( + "Name %s will become a keyword in Python %s", + "assign-to-new-keyword", + "Used when assignment will become invalid in future " + "Python release due to introducing new keyword.", + ), + } + + options = ( + ( + "good-names", + { + "default": ("i", "j", "k", "ex", "Run", "_"), + "type": "csv", + "metavar": "<names>", + "help": "Good variable names which should always be accepted," + " separated by a comma.", + }, + ), + ( + "bad-names", + { + "default": ("foo", "bar", "baz", "toto", "tutu", "tata"), + "type": "csv", + "metavar": "<names>", + "help": "Bad variable names which should always be refused, " + "separated by a comma.", + }, + ), + ( + "name-group", + { + "default": (), + "type": "csv", + "metavar": "<name1:name2>", + "help": ( + "Colon-delimited sets of names that determine each" + " other's naming style when the name regexes" + " allow several styles." + ), + }, + ), + ( + "include-naming-hint", + { + "default": False, + "type": "yn", + "metavar": "<y_or_n>", + "help": "Include a hint for the correct naming format with invalid-name.", + }, + ), + ( + "property-classes", + { + "default": ("abc.abstractproperty",), + "type": "csv", + "metavar": "<decorator names>", + "help": "List of decorators that produce properties, such as " + "abc.abstractproperty. Add to this list to register " + "other decorators that produce valid properties. " + "These decorators are taken in consideration only for invalid-name.", + }, + ), + ) + _create_naming_options() + + KEYWORD_ONSET = {(3, 7): {"async", "await"}} + + def __init__(self, linter): + _BasicChecker.__init__(self, linter) + self._name_category = {} + self._name_group = {} + self._bad_names = {} + self._name_regexps = {} + self._name_hints = {} + + def open(self): + self.stats = self.linter.add_stats( + badname_module=0, + badname_class=0, + badname_function=0, + badname_method=0, + badname_attr=0, + badname_const=0, + badname_variable=0, + badname_inlinevar=0, + badname_argument=0, + badname_class_attribute=0, + ) + for group in self.config.name_group: + for name_type in group.split(":"): + self._name_group[name_type] = "group_%s" % (group,) + + regexps, hints = self._create_naming_rules() + self._name_regexps = regexps + self._name_hints = hints + + def _create_naming_rules(self): + regexps = {} + hints = {} + + for name_type in KNOWN_NAME_TYPES: + naming_style_option_name = "%s_naming_style" % (name_type,) + naming_style_name = getattr(self.config, naming_style_option_name) + + regexps[name_type] = NAMING_STYLES[naming_style_name].get_regex(name_type) + + custom_regex_setting_name = "%s_rgx" % (name_type,) + custom_regex = getattr(self.config, custom_regex_setting_name, None) + if custom_regex is not None: + regexps[name_type] = custom_regex + + if custom_regex is not None: + hints[name_type] = "%r pattern" % custom_regex.pattern + else: + hints[name_type] = "%s naming style" % naming_style_name + + return regexps, hints + + @utils.check_messages("blacklisted-name", "invalid-name") + def visit_module(self, node): + self._check_name("module", node.name.split(".")[-1], node) + self._bad_names = {} + + def leave_module(self, node): # pylint: disable=unused-argument + for all_groups in self._bad_names.values(): + if len(all_groups) < 2: + continue + groups = collections.defaultdict(list) + min_warnings = sys.maxsize + for group in all_groups.values(): + groups[len(group)].append(group) + min_warnings = min(len(group), min_warnings) + if len(groups[min_warnings]) > 1: + by_line = sorted( + groups[min_warnings], + key=lambda group: min(warning[0].lineno for warning in group), + ) + warnings = itertools.chain(*by_line[1:]) + else: + warnings = groups[min_warnings][0] + for args in warnings: + self._raise_name_warning(*args) + + @utils.check_messages("blacklisted-name", "invalid-name", "assign-to-new-keyword") + def visit_classdef(self, node): + self._check_assign_to_new_keyword_violation(node.name, node) + self._check_name("class", node.name, node) + for attr, anodes in node.instance_attrs.items(): + if not any(node.instance_attr_ancestors(attr)): + self._check_name("attr", attr, anodes[0]) + + @utils.check_messages("blacklisted-name", "invalid-name", "assign-to-new-keyword") + def visit_functiondef(self, node): + # Do not emit any warnings if the method is just an implementation + # of a base class method. + self._check_assign_to_new_keyword_violation(node.name, node) + confidence = interfaces.HIGH + if node.is_method(): + if utils.overrides_a_method(node.parent.frame(), node.name): + return + confidence = ( + interfaces.INFERENCE + if utils.has_known_bases(node.parent.frame()) + else interfaces.INFERENCE_FAILURE + ) + + self._check_name( + _determine_function_name_type(node, config=self.config), + node.name, + node, + confidence, + ) + # Check argument names + args = node.args.args + if args is not None: + self._recursive_check_names(args, node) + + visit_asyncfunctiondef = visit_functiondef + + @utils.check_messages("blacklisted-name", "invalid-name") + def visit_global(self, node): + for name in node.names: + self._check_name("const", name, node) + + @utils.check_messages("blacklisted-name", "invalid-name", "assign-to-new-keyword") + def visit_assignname(self, node): + """check module level assigned names""" + self._check_assign_to_new_keyword_violation(node.name, node) + frame = node.frame() + assign_type = node.assign_type() + if isinstance(assign_type, astroid.Comprehension): + self._check_name("inlinevar", node.name, node) + elif isinstance(frame, astroid.Module): + if isinstance(assign_type, astroid.Assign) and not in_loop(assign_type): + if isinstance(utils.safe_infer(assign_type.value), astroid.ClassDef): + self._check_name("class", node.name, node) + else: + if not _redefines_import(node): + # Don't emit if the name redefines an import + # in an ImportError except handler. + self._check_name("const", node.name, node) + elif isinstance(assign_type, astroid.ExceptHandler): + self._check_name("variable", node.name, node) + elif isinstance(frame, astroid.FunctionDef): + # global introduced variable aren't in the function locals + if node.name in frame and node.name not in frame.argnames(): + if not _redefines_import(node): + self._check_name("variable", node.name, node) + elif isinstance(frame, astroid.ClassDef): + if not list(frame.local_attr_ancestors(node.name)): + self._check_name("class_attribute", node.name, node) + + def _recursive_check_names(self, args, node): + """check names in a possibly recursive list <arg>""" + for arg in args: + if isinstance(arg, astroid.AssignName): + self._check_name("argument", arg.name, node) + else: + self._recursive_check_names(arg.elts, node) + + def _find_name_group(self, node_type): + return self._name_group.get(node_type, node_type) + + def _raise_name_warning(self, node, node_type, name, confidence): + type_label = HUMAN_READABLE_TYPES[node_type] + hint = self._name_hints[node_type] + if self.config.include_naming_hint: + hint += " (%r pattern)" % self._name_regexps[node_type].pattern + args = (type_label.capitalize(), name, hint) + + self.add_message("invalid-name", node=node, args=args, confidence=confidence) + self.stats["badname_" + node_type] += 1 + + def _check_name(self, node_type, name, node, confidence=interfaces.HIGH): + """check for a name using the type's regexp""" + + def _should_exempt_from_invalid_name(node): + if node_type == "variable": + inferred = utils.safe_infer(node) + if isinstance(inferred, astroid.ClassDef): + return True + return False + + if utils.is_inside_except(node): + clobbering, _ = utils.clobber_in_except(node) + if clobbering: + return + if name in self.config.good_names: + return + if name in self.config.bad_names: + self.stats["badname_" + node_type] += 1 + self.add_message("blacklisted-name", node=node, args=name) + return + regexp = self._name_regexps[node_type] + match = regexp.match(name) + + if _is_multi_naming_match(match, node_type, confidence): + name_group = self._find_name_group(node_type) + bad_name_group = self._bad_names.setdefault(name_group, {}) + warnings = bad_name_group.setdefault(match.lastgroup, []) + warnings.append((node, node_type, name, confidence)) + + if match is None and not _should_exempt_from_invalid_name(node): + self._raise_name_warning(node, node_type, name, confidence) + + def _check_assign_to_new_keyword_violation(self, name, node): + keyword_first_version = self._name_became_keyword_in_version( + name, self.KEYWORD_ONSET + ) + if keyword_first_version is not None: + self.add_message( + "assign-to-new-keyword", + node=node, + args=(name, keyword_first_version), + confidence=interfaces.HIGH, + ) + + @staticmethod + def _name_became_keyword_in_version(name, rules): + for version, keywords in rules.items(): + if name in keywords and sys.version_info < version: + return ".".join(map(str, version)) + return None + + +class DocStringChecker(_BasicChecker): + msgs = { + "C0111": ( + "Missing %s docstring", # W0131 + "missing-docstring", + "Used when a module, function, class or method has no docstring." + "Some special methods like __init__ doesn't necessary require a " + "docstring.", + ), + "C0112": ( + "Empty %s docstring", # W0132 + "empty-docstring", + "Used when a module, function, class or method has an empty " + "docstring (it would be too easy ;).", + ), + } + options = ( + ( + "no-docstring-rgx", + { + "default": NO_REQUIRED_DOC_RGX, + "type": "regexp", + "metavar": "<regexp>", + "help": "Regular expression which should only match " + "function or class names that do not require a " + "docstring.", + }, + ), + ( + "docstring-min-length", + { + "default": -1, + "type": "int", + "metavar": "<int>", + "help": ( + "Minimum line length for functions/classes that" + " require docstrings, shorter ones are exempt." + ), + }, + ), + ) + + def open(self): + self.stats = self.linter.add_stats( + undocumented_module=0, + undocumented_function=0, + undocumented_method=0, + undocumented_class=0, + ) + + @utils.check_messages("missing-docstring", "empty-docstring") + def visit_module(self, node): + self._check_docstring("module", node) + + @utils.check_messages("missing-docstring", "empty-docstring") + def visit_classdef(self, node): + if self.config.no_docstring_rgx.match(node.name) is None: + self._check_docstring("class", node) + + @staticmethod + def _is_setter_or_deleter(node): + names = {"setter", "deleter"} + for decorator in node.decorators.nodes: + if isinstance(decorator, astroid.Attribute) and decorator.attrname in names: + return True + return False + + @utils.check_messages("missing-docstring", "empty-docstring") + def visit_functiondef(self, node): + if self.config.no_docstring_rgx.match(node.name) is None: + ftype = "method" if node.is_method() else "function" + if node.decorators and self._is_setter_or_deleter(node): + return + + if isinstance(node.parent.frame(), astroid.ClassDef): + overridden = False + confidence = ( + interfaces.INFERENCE + if utils.has_known_bases(node.parent.frame()) + else interfaces.INFERENCE_FAILURE + ) + # check if node is from a method overridden by its ancestor + for ancestor in node.parent.frame().ancestors(): + if node.name in ancestor and isinstance( + ancestor[node.name], astroid.FunctionDef + ): + overridden = True + break + self._check_docstring( + ftype, node, report_missing=not overridden, confidence=confidence + ) + elif isinstance(node.parent.frame(), astroid.Module): + self._check_docstring(ftype, node) + else: + return + + visit_asyncfunctiondef = visit_functiondef + + def _check_docstring( + self, node_type, node, report_missing=True, confidence=interfaces.HIGH + ): + """check the node has a non empty docstring""" + docstring = node.doc + if docstring is None: + if not report_missing: + return + lines = get_node_last_lineno(node) - node.lineno + + if node_type == "module" and not lines: + # If the module has no body, there's no reason + # to require a docstring. + return + max_lines = self.config.docstring_min_length + + if node_type != "module" and max_lines > -1 and lines < max_lines: + return + self.stats["undocumented_" + node_type] += 1 + if ( + node.body + and isinstance(node.body[0], astroid.Expr) + and isinstance(node.body[0].value, astroid.Call) + ): + # Most likely a string with a format call. Let's see. + func = utils.safe_infer(node.body[0].value.func) + if isinstance(func, astroid.BoundMethod) and isinstance( + func.bound, astroid.Instance + ): + # Strings in Python 3, others in Python 2. + if PY3K and func.bound.name == "str": + return + if func.bound.name in ("str", "unicode", "bytes"): + return + self.add_message( + "missing-docstring", node=node, args=(node_type,), confidence=confidence + ) + elif not docstring.strip(): + self.stats["undocumented_" + node_type] += 1 + self.add_message( + "empty-docstring", node=node, args=(node_type,), confidence=confidence + ) + + +class PassChecker(_BasicChecker): + """check if the pass statement is really necessary""" + + msgs = { + "W0107": ( + "Unnecessary pass statement", + "unnecessary-pass", + 'Used when a "pass" statement that can be avoided is encountered.', + ) + } + + @utils.check_messages("unnecessary-pass") + def visit_pass(self, node): + if len(node.parent.child_sequence(node)) > 1 or ( + isinstance(node.parent, (astroid.ClassDef, astroid.FunctionDef)) + and (node.parent.doc is not None) + ): + self.add_message("unnecessary-pass", node=node) + + +def _is_one_arg_pos_call(call): + """Is this a call with exactly 1 argument, + where that argument is positional? + """ + return isinstance(call, astroid.Call) and len(call.args) == 1 and not call.keywords + + +class ComparisonChecker(_BasicChecker): + """Checks for comparisons + + - singleton comparison: 'expr == True', 'expr == False' and 'expr == None' + - yoda condition: 'const "comp" right' where comp can be '==', '!=', '<', + '<=', '>' or '>=', and right can be a variable, an attribute, a method or + a function + """ + + msgs = { + "C0121": ( + "Comparison to %s should be %s", + "singleton-comparison", + "Used when an expression is compared to singleton " + "values like True, False or None.", + ), + "C0122": ( + "Comparison should be %s", + "misplaced-comparison-constant", + "Used when the constant is placed on the left side " + "of a comparison. It is usually clearer in intent to " + "place it in the right hand side of the comparison.", + ), + "C0123": ( + "Using type() instead of isinstance() for a typecheck.", + "unidiomatic-typecheck", + "The idiomatic way to perform an explicit typecheck in " + "Python is to use isinstance(x, Y) rather than " + "type(x) == Y, type(x) is Y. Though there are unusual " + "situations where these give different results.", + {"old_names": [("W0154", "unidiomatic-typecheck")]}, + ), + "R0123": ( + "Comparison to literal", + "literal-comparison", + "Used when comparing an object to a literal, which is usually " + "what you do not want to do, since you can compare to a different " + "literal than what was expected altogether.", + ), + "R0124": ( + "Redundant comparison - %s", + "comparison-with-itself", + "Used when something is compared against itself.", + ), + "W0143": ( + "Comparing against a callable, did you omit the parenthesis?", + "comparison-with-callable", + "This message is emitted when pylint detects that a comparison with a " + "callable was made, which might suggest that some parenthesis were omitted, " + "resulting in potential unwanted behaviour.", + ), + } + + def _check_singleton_comparison(self, singleton, root_node, negative_check=False): + if singleton.value is True: + if not negative_check: + suggestion = "just 'expr'" + else: + suggestion = "just 'not expr'" + self.add_message( + "singleton-comparison", node=root_node, args=(True, suggestion) + ) + elif singleton.value is False: + if not negative_check: + suggestion = "'not expr'" + else: + suggestion = "'expr'" + self.add_message( + "singleton-comparison", node=root_node, args=(False, suggestion) + ) + elif singleton.value is None: + if not negative_check: + suggestion = "'expr is None'" + else: + suggestion = "'expr is not None'" + self.add_message( + "singleton-comparison", node=root_node, args=(None, suggestion) + ) + + def _check_literal_comparison(self, literal, node): + """Check if we compare to a literal, which is usually what we do not want to do.""" + nodes = (astroid.List, astroid.Tuple, astroid.Dict, astroid.Set) + is_other_literal = isinstance(literal, nodes) + is_const = False + if isinstance(literal, astroid.Const): + if isinstance(literal.value, bool) or literal.value is None: + # Not interested in this values. + return + is_const = isinstance(literal.value, (bytes, str, int, float)) + + if is_const or is_other_literal: + self.add_message("literal-comparison", node=node) + + def _check_misplaced_constant(self, node, left, right, operator): + if isinstance(right, astroid.Const): + return + operator = REVERSED_COMPS.get(operator, operator) + suggestion = "%s %s %r" % (right.as_string(), operator, left.value) + self.add_message("misplaced-comparison-constant", node=node, args=(suggestion,)) + + def _check_logical_tautology(self, node): + """Check if identifier is compared against itself. + :param node: Compare node + :type node: astroid.node_classes.Compare + :Example: + val = 786 + if val == val: # [comparison-with-itself] + pass + """ + left_operand = node.left + right_operand = node.ops[0][1] + operator = node.ops[0][0] + if isinstance(left_operand, astroid.Const) and isinstance( + right_operand, astroid.Const + ): + left_operand = left_operand.value + right_operand = right_operand.value + elif isinstance(left_operand, astroid.Name) and isinstance( + right_operand, astroid.Name + ): + left_operand = left_operand.name + right_operand = right_operand.name + + if left_operand == right_operand: + suggestion = "%s %s %s" % (left_operand, operator, right_operand) + self.add_message("comparison-with-itself", node=node, args=(suggestion,)) + + def _check_callable_comparison(self, node): + operator = node.ops[0][0] + if operator not in COMPARISON_OPERATORS: + return + + bare_callables = (astroid.FunctionDef, astroid.BoundMethod) + left_operand, right_operand = node.left, node.ops[0][1] + # this message should be emitted only when there is comparison of bare callable + # with non bare callable. + if ( + sum( + 1 + for operand in (left_operand, right_operand) + if isinstance(utils.safe_infer(operand), bare_callables) + ) + == 1 + ): + self.add_message("comparison-with-callable", node=node) + + @utils.check_messages( + "singleton-comparison", + "misplaced-comparison-constant", + "unidiomatic-typecheck", + "literal-comparison", + "comparison-with-itself", + "comparison-with-callable", + ) + def visit_compare(self, node): + self._check_callable_comparison(node) + self._check_logical_tautology(node) + self._check_unidiomatic_typecheck(node) + # NOTE: this checker only works with binary comparisons like 'x == 42' + # but not 'x == y == 42' + if len(node.ops) != 1: + return + + left = node.left + operator, right = node.ops[0] + if operator in COMPARISON_OPERATORS and isinstance(left, astroid.Const): + self._check_misplaced_constant(node, left, right, operator) + + if operator == "==": + if isinstance(left, astroid.Const): + self._check_singleton_comparison(left, node) + elif isinstance(right, astroid.Const): + self._check_singleton_comparison(right, node) + if operator == "!=": + if isinstance(right, astroid.Const): + self._check_singleton_comparison(right, node, negative_check=True) + if operator in ("is", "is not"): + self._check_literal_comparison(right, node) + + def _check_unidiomatic_typecheck(self, node): + operator, right = node.ops[0] + if operator in TYPECHECK_COMPARISON_OPERATORS: + left = node.left + if _is_one_arg_pos_call(left): + self._check_type_x_is_y(node, left, operator, right) + + def _check_type_x_is_y(self, node, left, operator, right): + """Check for expressions like type(x) == Y.""" + left_func = utils.safe_infer(left.func) + if not ( + isinstance(left_func, astroid.ClassDef) and left_func.qname() == TYPE_QNAME + ): + return + + if operator in ("is", "is not") and _is_one_arg_pos_call(right): + right_func = utils.safe_infer(right.func) + if ( + isinstance(right_func, astroid.ClassDef) + and right_func.qname() == TYPE_QNAME + ): + # type(x) == type(a) + right_arg = utils.safe_infer(right.args[0]) + if not isinstance(right_arg, LITERAL_NODE_TYPES): + # not e.g. type(x) == type([]) + return + self.add_message("unidiomatic-typecheck", node=node) + + +def register(linter): + """required method to auto register this checker""" + linter.register_checker(BasicErrorChecker(linter)) + linter.register_checker(BasicChecker(linter)) + linter.register_checker(NameChecker(linter)) + linter.register_checker(DocStringChecker(linter)) + linter.register_checker(PassChecker(linter)) + linter.register_checker(ComparisonChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/classes.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/classes.py new file mode 100644 index 0000000..b0a8590 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/classes.py @@ -0,0 +1,1750 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2016 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2010 Maarten ter Huurne <maarten@treewalker.org> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2013-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2014 David Pursehouse <david.pursehouse@gmail.com> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2016 Anthony Foglia <afoglia@users.noreply.github.com> +# Copyright (c) 2016 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Ben Green <benhgreen@icloud.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""classes checker for Python code +""" +from __future__ import generators + +import collections +from itertools import chain, zip_longest +import sys + +import astroid +from astroid.bases import Generator, BUILTINS +from astroid.exceptions import InconsistentMroError, DuplicateBasesError +from astroid import decorators +from astroid import objects +from astroid.scoped_nodes import function_to_method +from pylint.interfaces import IAstroidChecker +from pylint.checkers import BaseChecker +from pylint.checkers.utils import ( + PYMETHODS, + SPECIAL_METHODS_PARAMS, + overrides_a_method, + check_messages, + is_attr_private, + is_attr_protected, + node_frame_class, + is_builtin_object, + decorated_with_property, + unimplemented_abstract_methods, + decorated_with, + class_is_abstract, + safe_infer, + has_known_bases, + is_iterable, + is_comprehension, +) +from pylint.utils import get_global_option + + +if sys.version_info >= (3, 0): + NEXT_METHOD = "__next__" +else: + NEXT_METHOD = "next" +INVALID_BASE_CLASSES = {"bool", "range", "slice", "memoryview"} + + +# Dealing with useless override detection, with regard +# to parameters vs arguments + +_CallSignature = collections.namedtuple( + "_CallSignature", "args kws starred_args starred_kws" +) +_ParameterSignature = collections.namedtuple( + "_ParameterSignature", "args kwonlyargs varargs kwargs" +) + + +def _signature_from_call(call): + kws = {} + args = [] + starred_kws = [] + starred_args = [] + for keyword in call.keywords or []: + arg, value = keyword.arg, keyword.value + if arg is None and isinstance(value, astroid.Name): + # Starred node and we are interested only in names, + # otherwise some transformation might occur for the parameter. + starred_kws.append(value.name) + elif isinstance(value, astroid.Name): + kws[arg] = value.name + else: + kws[arg] = None + + for arg in call.args: + if isinstance(arg, astroid.Starred) and isinstance(arg.value, astroid.Name): + # Positional variadic and a name, otherwise some transformation + # might have occurred. + starred_args.append(arg.value.name) + elif isinstance(arg, astroid.Name): + args.append(arg.name) + else: + args.append(None) + + return _CallSignature(args, kws, starred_args, starred_kws) + + +def _signature_from_arguments(arguments): + kwarg = arguments.kwarg + vararg = arguments.vararg + args = [arg.name for arg in arguments.args if arg.name != "self"] + kwonlyargs = [arg.name for arg in arguments.kwonlyargs] + return _ParameterSignature(args, kwonlyargs, vararg, kwarg) + + +def _definition_equivalent_to_call(definition, call): + """Check if a definition signature is equivalent to a call.""" + if definition.kwargs: + same_kw_variadics = definition.kwargs in call.starred_kws + else: + same_kw_variadics = not call.starred_kws + if definition.varargs: + same_args_variadics = definition.varargs in call.starred_args + else: + same_args_variadics = not call.starred_args + same_kwonlyargs = all(kw in call.kws for kw in definition.kwonlyargs) + same_args = definition.args == call.args + + no_additional_kwarg_arguments = True + if call.kws: + for keyword in call.kws: + is_arg = keyword in call.args + is_kwonly = keyword in definition.kwonlyargs + if not is_arg and not is_kwonly: + # Maybe this argument goes into **kwargs, + # or it is an extraneous argument. + # In any case, the signature is different than + # the call site, which stops our search. + no_additional_kwarg_arguments = False + break + + return all( + ( + same_args, + same_kwonlyargs, + same_args_variadics, + same_kw_variadics, + no_additional_kwarg_arguments, + ) + ) + + +# Deal with parameters overridding in two methods. + + +def _positional_parameters(method): + positional = method.args.args + if method.type in ("classmethod", "method"): + positional = positional[1:] + return positional + + +def _get_node_type(node, potential_types): + """ + Return the type of the node if it exists in potential_types. + + Args: + node (astroid.node): node to get the type of. + potential_types (tuple): potential types of the node. + + Returns: + type: type of the node or None. + """ + for potential_type in potential_types: + if isinstance(node, potential_type): + return potential_type + return None + + +def _check_arg_equality(node_a, node_b, attr_name): + """ + Check equality of nodes based on the comparison of their attributes named attr_name. + + Args: + node_a (astroid.node): first node to compare. + node_b (astroid.node): second node to compare. + attr_name (str): name of the nodes attribute to use for comparison. + + Returns: + bool: True if node_a.attr_name == node_b.attr_name, False otherwise. + """ + return getattr(node_a, attr_name) == getattr(node_b, attr_name) + + +def _has_different_parameters_default_value(original, overridden): + """ + Check if original and overridden methods arguments have different default values + + Return True if one of the overridden arguments has a default + value different from the default value of the original argument + If one of the method doesn't have argument (.args is None) + return False + """ + if original.args is None or overridden.args is None: + return False + + all_args = chain(original.args, original.kwonlyargs) + original_param_names = [param.name for param in all_args] + default_missing = object() + for param_name in original_param_names: + try: + original_default = original.default_value(param_name) + except astroid.exceptions.NoDefault: + original_default = default_missing + try: + overridden_default = overridden.default_value(param_name) + except astroid.exceptions.NoDefault: + overridden_default = default_missing + + default_list = [ + arg == default_missing for arg in (original_default, overridden_default) + ] + if any(default_list) and not all(default_list): + # Only one arg has no default value + return True + + astroid_type_compared_attr = { + astroid.Const: "value", + astroid.ClassDef: "name", + astroid.Tuple: "elts", + astroid.List: "elts", + } + handled_types = tuple( + astroid_type for astroid_type in astroid_type_compared_attr + ) + original_type = _get_node_type(original_default, handled_types) + if original_type: + #  We handle only astroid types that are inside the dict astroid_type_compared_attr + if not isinstance(overridden_default, original_type): + #  Two args with same name but different types + return True + if not _check_arg_equality( + original_default, + overridden_default, + astroid_type_compared_attr[original_type], + ): + # Two args with same type but different values + return True + return False + + +def _has_different_parameters(original, overridden, dummy_parameter_regex): + zipped = zip_longest(original, overridden) + for original_param, overridden_param in zipped: + params = (original_param, overridden_param) + if not all(params): + return True + + names = [param.name for param in params] + if any(map(dummy_parameter_regex.match, names)): + continue + if original_param.name != overridden_param.name: + return True + return False + + +def _different_parameters(original, overridden, dummy_parameter_regex): + """Determine if the two methods have different parameters + + They are considered to have different parameters if: + + * they have different positional parameters, including different names + + * one of the methods is having variadics, while the other is not + + * they have different keyword only parameters. + + """ + original_parameters = _positional_parameters(original) + overridden_parameters = _positional_parameters(overridden) + + different_positional = _has_different_parameters( + original_parameters, overridden_parameters, dummy_parameter_regex + ) + different_kwonly = _has_different_parameters( + original.args.kwonlyargs, overridden.args.kwonlyargs, dummy_parameter_regex + ) + if original.name in PYMETHODS: + # Ignore the difference for special methods. If the parameter + # numbers are different, then that is going to be caught by + # unexpected-special-method-signature. + # If the names are different, it doesn't matter, since they can't + # be used as keyword arguments anyway. + different_positional = different_kwonly = False + + # Both or none should have extra variadics, otherwise the method + # loses or gains capabilities that are not reflected into the parent method, + # leading to potential inconsistencies in the code. + different_kwarg = ( + sum(1 for param in (original.args.kwarg, overridden.args.kwarg) if not param) + == 1 + ) + different_vararg = ( + sum(1 for param in (original.args.vararg, overridden.args.vararg) if not param) + == 1 + ) + + return any( + (different_positional, different_kwarg, different_vararg, different_kwonly) + ) + + +def _is_invalid_base_class(cls): + return cls.name in INVALID_BASE_CLASSES and is_builtin_object(cls) + + +def _has_data_descriptor(cls, attr): + attributes = cls.getattr(attr) + for attribute in attributes: + try: + for inferred in attribute.infer(): + if isinstance(inferred, astroid.Instance): + try: + inferred.getattr("__get__") + inferred.getattr("__set__") + except astroid.NotFoundError: + continue + else: + return True + except astroid.InferenceError: + # Can't infer, avoid emitting a false positive in this case. + return True + return False + + +def _called_in_methods(func, klass, methods): + """ Check if the func was called in any of the given methods, + belonging to the *klass*. Returns True if so, False otherwise. + """ + if not isinstance(func, astroid.FunctionDef): + return False + for method in methods: + try: + infered = klass.getattr(method) + except astroid.NotFoundError: + continue + for infer_method in infered: + for call in infer_method.nodes_of_class(astroid.Call): + try: + bound = next(call.func.infer()) + except (astroid.InferenceError, StopIteration): + continue + if not isinstance(bound, astroid.BoundMethod): + continue + func_obj = bound._proxied + if isinstance(func_obj, astroid.UnboundMethod): + func_obj = func_obj._proxied + if func_obj.name == func.name: + return True + return False + + +def _is_attribute_property(name, klass): + """ Check if the given attribute *name* is a property + in the given *klass*. + + It will look for `property` calls or for functions + with the given name, decorated by `property` or `property` + subclasses. + Returns ``True`` if the name is a property in the given klass, + ``False`` otherwise. + """ + + try: + attributes = klass.getattr(name) + except astroid.NotFoundError: + return False + property_name = "{}.property".format(BUILTINS) + for attr in attributes: + if attr is astroid.Uninferable: + continue + try: + infered = next(attr.infer()) + except astroid.InferenceError: + continue + if isinstance(infered, astroid.FunctionDef) and decorated_with_property( + infered + ): + return True + if infered.pytype() == property_name: + return True + return False + + +def _has_bare_super_call(fundef_node): + for call in fundef_node.nodes_of_class(astroid.Call): + func = call.func + if isinstance(func, astroid.Name) and func.name == "super" and not call.args: + return True + return False + + +def _safe_infer_call_result(node, caller, context=None): + """ + Safely infer the return value of a function. + + Returns None if inference failed or if there is some ambiguity (more than + one node has been inferred). Otherwise returns infered value. + """ + try: + inferit = node.infer_call_result(caller, context=context) + value = next(inferit) + except astroid.InferenceError: + return None # inference failed + except StopIteration: + return None # no values infered + try: + next(inferit) + return None # there is ambiguity on the inferred node + except astroid.InferenceError: + return None # there is some kind of ambiguity + except StopIteration: + return value + + +def _has_same_layout_slots(slots, assigned_value): + inferred = next(assigned_value.infer()) + if isinstance(inferred, astroid.ClassDef): + other_slots = inferred.slots() + if all( + first_slot and second_slot and first_slot.value == second_slot.value + for (first_slot, second_slot) in zip_longest(slots, other_slots) + ): + return True + return False + + +MSGS = { + "F0202": ( + "Unable to check methods signature (%s / %s)", + "method-check-failed", + "Used when Pylint has been unable to check methods signature " + "compatibility for an unexpected reason. Please report this kind " + "if you don't make sense of it.", + ), + "E0202": ( + "An attribute defined in %s line %s hides this method", + "method-hidden", + "Used when a class defines a method which is hidden by an " + "instance attribute from an ancestor class or set by some " + "client code.", + ), + "E0203": ( + "Access to member %r before its definition line %s", + "access-member-before-definition", + "Used when an instance member is accessed before it's actually assigned.", + ), + "W0201": ( + "Attribute %r defined outside __init__", + "attribute-defined-outside-init", + "Used when an instance attribute is defined outside the __init__ method.", + ), + "W0212": ( + "Access to a protected member %s of a client class", # E0214 + "protected-access", + "Used when a protected member (i.e. class member with a name " + "beginning with an underscore) is access outside the class or a " + "descendant of the class where it's defined.", + ), + "E0211": ( + "Method has no argument", + "no-method-argument", + "Used when a method which should have the bound instance as " + "first argument has no argument defined.", + ), + "E0213": ( + 'Method should have "self" as first argument', + "no-self-argument", + 'Used when a method has an attribute different the "self" as ' + "first argument. This is considered as an error since this is " + "a so common convention that you shouldn't break it!", + ), + "C0202": ( + "Class method %s should have %s as first argument", + "bad-classmethod-argument", + "Used when a class method has a first argument named differently " + "than the value specified in valid-classmethod-first-arg option " + '(default to "cls"), recommended to easily differentiate them ' + "from regular instance methods.", + ), + "C0203": ( + "Metaclass method %s should have %s as first argument", + "bad-mcs-method-argument", + "Used when a metaclass method has a first argument named " + "differently than the value specified in valid-classmethod-first" + '-arg option (default to "cls"), recommended to easily ' + "differentiate them from regular instance methods.", + ), + "C0204": ( + "Metaclass class method %s should have %s as first argument", + "bad-mcs-classmethod-argument", + "Used when a metaclass class method has a first argument named " + "differently than the value specified in valid-metaclass-" + 'classmethod-first-arg option (default to "mcs"), recommended to ' + "easily differentiate them from regular instance methods.", + ), + "W0211": ( + "Static method with %r as first argument", + "bad-staticmethod-argument", + 'Used when a static method has "self" or a value specified in ' + "valid-classmethod-first-arg option or " + "valid-metaclass-classmethod-first-arg option as first argument.", + ), + "R0201": ( + "Method could be a function", + "no-self-use", + "Used when a method doesn't use its bound instance, and so could " + "be written as a function.", + ), + "W0221": ( + "Parameters differ from %s %r method", + "arguments-differ", + "Used when a method has a different number of arguments than in " + "the implemented interface or in an overridden method.", + ), + "W0222": ( + "Signature differs from %s %r method", + "signature-differs", + "Used when a method signature is different than in the " + "implemented interface or in an overridden method.", + ), + "W0223": ( + "Method %r is abstract in class %r but is not overridden", + "abstract-method", + "Used when an abstract method (i.e. raise NotImplementedError) is " + "not overridden in concrete class.", + ), + "W0231": ( + "__init__ method from base class %r is not called", + "super-init-not-called", + "Used when an ancestor class method has an __init__ method " + "which is not called by a derived class.", + ), + "W0232": ( + "Class has no __init__ method", + "no-init", + "Used when a class has no __init__ method, neither its parent classes.", + ), + "W0233": ( + "__init__ method from a non direct base class %r is called", + "non-parent-init-called", + "Used when an __init__ method is called on a class which is not " + "in the direct ancestors for the analysed class.", + ), + "W0235": ( + "Useless super delegation in method %r", + "useless-super-delegation", + "Used whenever we can detect that an overridden method is useless, " + "relying on super() delegation to do the same thing as another method " + "from the MRO.", + ), + "E0236": ( + "Invalid object %r in __slots__, must contain only non empty strings", + "invalid-slots-object", + "Used when an invalid (non-string) object occurs in __slots__.", + ), + "E0237": ( + "Assigning to attribute %r not defined in class slots", + "assigning-non-slot", + "Used when assigning to an attribute not defined in the class slots.", + ), + "E0238": ( + "Invalid __slots__ object", + "invalid-slots", + "Used when an invalid __slots__ is found in class. " + "Only a string, an iterable or a sequence is permitted.", + ), + "E0239": ( + "Inheriting %r, which is not a class.", + "inherit-non-class", + "Used when a class inherits from something which is not a class.", + ), + "E0240": ( + "Inconsistent method resolution order for class %r", + "inconsistent-mro", + "Used when a class has an inconsistent method resolution order.", + ), + "E0241": ( + "Duplicate bases for class %r", + "duplicate-bases", + "Used when a class has duplicate bases.", + ), + "R0202": ( + "Consider using a decorator instead of calling classmethod", + "no-classmethod-decorator", + "Used when a class method is defined without using the decorator syntax.", + ), + "R0203": ( + "Consider using a decorator instead of calling staticmethod", + "no-staticmethod-decorator", + "Used when a static method is defined without using the decorator syntax.", + ), + "C0205": ( + "Class __slots__ should be a non-string iterable", + "single-string-used-for-slots", + "Used when a class __slots__ is a simple string, rather than an iterable.", + ), + "R0205": ( + "Class %r inherits from object, can be safely removed from bases in python3", + "useless-object-inheritance", + "Used when a class inherit from object, which under python3 is implicit, " + "hence can be safely removed from bases.", + ), +} + + +class ScopeAccessMap: + """Store the accessed variables per scope.""" + + def __init__(self): + self._scopes = collections.defaultdict(lambda: collections.defaultdict(list)) + + def set_accessed(self, node): + """Set the given node as accessed.""" + + frame = node_frame_class(node) + if frame is None: + # The node does not live in a class. + return + self._scopes[frame][node.attrname].append(node) + + def accessed(self, scope): + """Get the accessed variables for the given scope.""" + return self._scopes.get(scope, {}) + + +class ClassChecker(BaseChecker): + """checks for : + * methods without self as first argument + * overridden methods signature + * access only to existent members via self + * attributes not defined in the __init__ method + * unreachable code + """ + + __implements__ = (IAstroidChecker,) + + # configuration section name + name = "classes" + # messages + msgs = MSGS + priority = -2 + # configuration options + options = ( + ( + "defining-attr-methods", + { + "default": ("__init__", "__new__", "setUp"), + "type": "csv", + "metavar": "<method names>", + "help": "List of method names used to declare (i.e. assign) \ +instance attributes.", + }, + ), + ( + "valid-classmethod-first-arg", + { + "default": ("cls",), + "type": "csv", + "metavar": "<argument names>", + "help": "List of valid names for the first argument in \ +a class method.", + }, + ), + ( + "valid-metaclass-classmethod-first-arg", + { + "default": ("cls",), + "type": "csv", + "metavar": "<argument names>", + "help": "List of valid names for the first argument in \ +a metaclass class method.", + }, + ), + ( + "exclude-protected", + { + "default": ( + # namedtuple public API. + "_asdict", + "_fields", + "_replace", + "_source", + "_make", + ), + "type": "csv", + "metavar": "<protected access exclusions>", + "help": ( + "List of member names, which should be excluded " + "from the protected access warning." + ), + }, + ), + ) + + def __init__(self, linter=None): + BaseChecker.__init__(self, linter) + self._accessed = ScopeAccessMap() + self._first_attrs = [] + self._meth_could_be_func = None + + @decorators.cachedproperty + def _dummy_rgx(self): + return get_global_option(self, "dummy-variables-rgx", default=None) + + @decorators.cachedproperty + def _ignore_mixin(self): + return get_global_option(self, "ignore-mixin-members", default=True) + + def visit_classdef(self, node): + """init visit variable _accessed + """ + self._check_bases_classes(node) + # if not an exception or a metaclass + if node.type == "class" and has_known_bases(node): + try: + node.local_attr("__init__") + except astroid.NotFoundError: + self.add_message("no-init", args=node, node=node) + self._check_slots(node) + self._check_proper_bases(node) + self._check_consistent_mro(node) + + def _check_consistent_mro(self, node): + """Detect that a class has a consistent mro or duplicate bases.""" + try: + node.mro() + except InconsistentMroError: + self.add_message("inconsistent-mro", args=node.name, node=node) + except DuplicateBasesError: + self.add_message("duplicate-bases", args=node.name, node=node) + except NotImplementedError: + # Old style class, there's no mro so don't do anything. + pass + + def _check_proper_bases(self, node): + """ + Detect that a class inherits something which is not + a class or a type. + """ + for base in node.bases: + ancestor = safe_infer(base) + if ancestor in (astroid.Uninferable, None): + continue + if isinstance(ancestor, astroid.Instance) and ancestor.is_subtype_of( + "%s.type" % (BUILTINS,) + ): + continue + + if not isinstance(ancestor, astroid.ClassDef) or _is_invalid_base_class( + ancestor + ): + self.add_message("inherit-non-class", args=base.as_string(), node=node) + + if ancestor.name == object.__name__: + self.add_message( + "useless-object-inheritance", args=node.name, node=node + ) + + def leave_classdef(self, cnode): + """close a class node: + check that instance attributes are defined in __init__ and check + access to existent members + """ + # check access to existent members on non metaclass classes + if self._ignore_mixin and cnode.name[-5:].lower() == "mixin": + # We are in a mixin class. No need to try to figure out if + # something is missing, since it is most likely that it will + # miss. + return + + accessed = self._accessed.accessed(cnode) + if cnode.type != "metaclass": + self._check_accessed_members(cnode, accessed) + # checks attributes are defined in an allowed method such as __init__ + if not self.linter.is_message_enabled("attribute-defined-outside-init"): + return + defining_methods = self.config.defining_attr_methods + current_module = cnode.root() + for attr, nodes in cnode.instance_attrs.items(): + # skip nodes which are not in the current module and it may screw up + # the output, while it's not worth it + nodes = [ + n + for n in nodes + if not isinstance(n.statement(), (astroid.Delete, astroid.AugAssign)) + and n.root() is current_module + ] + if not nodes: + continue # error detected by typechecking + # check if any method attr is defined in is a defining method + if any(node.frame().name in defining_methods for node in nodes): + continue + + # check attribute is defined in a parent's __init__ + for parent in cnode.instance_attr_ancestors(attr): + attr_defined = False + # check if any parent method attr is defined in is a defining method + for node in parent.instance_attrs[attr]: + if node.frame().name in defining_methods: + attr_defined = True + if attr_defined: + # we're done :) + break + else: + # check attribute is defined as a class attribute + try: + cnode.local_attr(attr) + except astroid.NotFoundError: + for node in nodes: + if node.frame().name not in defining_methods: + # If the attribute was set by a call in any + # of the defining methods, then don't emit + # the warning. + if _called_in_methods( + node.frame(), cnode, defining_methods + ): + continue + self.add_message( + "attribute-defined-outside-init", args=attr, node=node + ) + + def visit_functiondef(self, node): + """check method arguments, overriding""" + # ignore actual functions + if not node.is_method(): + return + + self._check_useless_super_delegation(node) + + klass = node.parent.frame() + self._meth_could_be_func = True + # check first argument is self if this is actually a method + self._check_first_arg_for_type(node, klass.type == "metaclass") + if node.name == "__init__": + self._check_init(node) + return + # check signature if the method overloads inherited method + for overridden in klass.local_attr_ancestors(node.name): + # get astroid for the searched method + try: + meth_node = overridden[node.name] + except KeyError: + # we have found the method but it's not in the local + # dictionary. + # This may happen with astroid build from living objects + continue + if not isinstance(meth_node, astroid.FunctionDef): + continue + self._check_signature(node, meth_node, "overridden", klass) + break + if node.decorators: + for decorator in node.decorators.nodes: + if isinstance(decorator, astroid.Attribute) and decorator.attrname in ( + "getter", + "setter", + "deleter", + ): + # attribute affectation will call this method, not hiding it + return + if isinstance(decorator, astroid.Name): + if decorator.name == "property": + # attribute affectation will either call a setter or raise + # an attribute error, anyway not hiding the function + return + + # Infer the decorator and see if it returns something useful + inferred = safe_infer(decorator) + if not inferred: + return + if isinstance(inferred, astroid.FunctionDef): + # Okay, it's a decorator, let's see what it can infer. + try: + inferred = next(inferred.infer_call_result(inferred)) + except astroid.InferenceError: + return + try: + if ( + isinstance(inferred, (astroid.Instance, astroid.ClassDef)) + and inferred.getattr("__get__") + and inferred.getattr("__set__") + ): + return + except astroid.AttributeInferenceError: + pass + + # check if the method is hidden by an attribute + try: + overridden = klass.instance_attr(node.name)[0] # XXX + overridden_frame = overridden.frame() + if ( + isinstance(overridden_frame, astroid.FunctionDef) + and overridden_frame.type == "method" + ): + overridden_frame = overridden_frame.parent.frame() + if isinstance(overridden_frame, astroid.ClassDef) and klass.is_subtype_of( + overridden_frame.qname() + ): + args = (overridden.root().name, overridden.fromlineno) + self.add_message("method-hidden", args=args, node=node) + except astroid.NotFoundError: + pass + + visit_asyncfunctiondef = visit_functiondef + + def _check_useless_super_delegation(self, function): + """Check if the given function node is an useless method override + + We consider it *useless* if it uses the super() builtin, but having + nothing additional whatsoever than not implementing the method at all. + If the method uses super() to delegate an operation to the rest of the MRO, + and if the method called is the same as the current one, the arguments + passed to super() are the same as the parameters that were passed to + this method, then the method could be removed altogether, by letting + other implementation to take precedence. + """ + + if ( + not function.is_method() + # With decorators is a change of use + or function.decorators + ): + return + + body = function.body + if len(body) != 1: + # Multiple statements, which means this overridden method + # could do multiple things we are not aware of. + return + + statement = body[0] + if not isinstance(statement, (astroid.Expr, astroid.Return)): + # Doing something else than what we are interested into. + return + + call = statement.value + if ( + not isinstance(call, astroid.Call) + # Not a super() attribute access. + or not isinstance(call.func, astroid.Attribute) + ): + return + + # Should be a super call. + try: + super_call = next(call.func.expr.infer()) + except astroid.InferenceError: + return + else: + if not isinstance(super_call, objects.Super): + return + + # The name should be the same. + if call.func.attrname != function.name: + return + + # Should be a super call with the MRO pointer being the + # current class and the type being the current instance. + current_scope = function.parent.scope() + if ( + super_call.mro_pointer != current_scope + or not isinstance(super_call.type, astroid.Instance) + or super_call.type.name != current_scope.name + ): + return + + #  Check values of default args + klass = function.parent.frame() + meth_node = None + for overridden in klass.local_attr_ancestors(function.name): + # get astroid for the searched method + try: + meth_node = overridden[function.name] + except KeyError: + # we have found the method but it's not in the local + # dictionary. + # This may happen with astroid build from living objects + continue + if ( + not isinstance(meth_node, astroid.FunctionDef) + # If the method have an ancestor which is not a + # function then it is legitimate to redefine it + or _has_different_parameters_default_value( + meth_node.args, function.args + ) + ): + return + break + + # Detect if the parameters are the same as the call's arguments. + params = _signature_from_arguments(function.args) + args = _signature_from_call(call) + + if meth_node is not None: + + def form_annotations(annotations): + return [ + annotation.as_string() for annotation in filter(None, annotations) + ] + + called_annotations = form_annotations(function.args.annotations) + overridden_annotations = form_annotations(meth_node.args.annotations) + if called_annotations and overridden_annotations: + if called_annotations != overridden_annotations: + return + + if _definition_equivalent_to_call(params, args): + self.add_message( + "useless-super-delegation", node=function, args=(function.name,) + ) + + def _check_slots(self, node): + if "__slots__" not in node.locals: + return + for slots in node.igetattr("__slots__"): + # check if __slots__ is a valid type + if slots is astroid.Uninferable: + continue + if not is_iterable(slots) and not is_comprehension(slots): + self.add_message("invalid-slots", node=node) + continue + + if isinstance(slots, astroid.Const): + # a string, ignore the following checks + self.add_message("single-string-used-for-slots", node=node) + continue + if not hasattr(slots, "itered"): + # we can't obtain the values, maybe a .deque? + continue + + if isinstance(slots, astroid.Dict): + values = [item[0] for item in slots.items] + else: + values = slots.itered() + if values is astroid.Uninferable: + return + + for elt in values: + try: + self._check_slots_elt(elt) + except astroid.InferenceError: + continue + + def _check_slots_elt(self, elt): + for infered in elt.infer(): + if infered is astroid.Uninferable: + continue + if not isinstance(infered, astroid.Const) or not isinstance( + infered.value, str + ): + self.add_message( + "invalid-slots-object", args=infered.as_string(), node=elt + ) + continue + if not infered.value: + self.add_message( + "invalid-slots-object", args=infered.as_string(), node=elt + ) + + def leave_functiondef(self, node): + """on method node, check if this method couldn't be a function + + ignore class, static and abstract methods, initializer, + methods overridden from a parent class. + """ + if node.is_method(): + if node.args.args is not None: + self._first_attrs.pop() + if not self.linter.is_message_enabled("no-self-use"): + return + class_node = node.parent.frame() + if ( + self._meth_could_be_func + and node.type == "method" + and node.name not in PYMETHODS + and not ( + node.is_abstract() + or overrides_a_method(class_node, node.name) + or decorated_with_property(node) + or _has_bare_super_call(node) + ) + ): + self.add_message("no-self-use", node=node) + + def visit_attribute(self, node): + """check if the getattr is an access to a class member + if so, register it. Also check for access to protected + class member from outside its class (but ignore __special__ + methods) + """ + # Check self + if self._uses_mandatory_method_param(node): + self._accessed.set_accessed(node) + return + if not self.linter.is_message_enabled("protected-access"): + return + + self._check_protected_attribute_access(node) + + def visit_assignattr(self, node): + if isinstance( + node.assign_type(), astroid.AugAssign + ) and self._uses_mandatory_method_param(node): + self._accessed.set_accessed(node) + self._check_in_slots(node) + + def _check_in_slots(self, node): + """ Check that the given AssignAttr node + is defined in the class slots. + """ + infered = safe_infer(node.expr) + if infered and isinstance(infered, astroid.Instance): + klass = infered._proxied + if "__slots__" not in klass.locals or not klass.newstyle: + return + + slots = klass.slots() + if slots is None: + return + # If any ancestor doesn't use slots, the slots + # defined for this class are superfluous. + if any( + "__slots__" not in ancestor.locals and ancestor.name != "object" + for ancestor in klass.ancestors() + ): + return + + if not any(slot.value == node.attrname for slot in slots): + # If we have a '__dict__' in slots, then + # assigning any name is valid. + if not any(slot.value == "__dict__" for slot in slots): + if _is_attribute_property(node.attrname, klass): + # Properties circumvent the slots mechanism, + # so we should not emit a warning for them. + return + if node.attrname in klass.locals and _has_data_descriptor( + klass, node.attrname + ): + # Descriptors circumvent the slots mechanism as well. + return + if node.attrname == "__class__" and _has_same_layout_slots( + slots, node.parent.value + ): + return + self.add_message( + "assigning-non-slot", args=(node.attrname,), node=node + ) + + @check_messages( + "protected-access", "no-classmethod-decorator", "no-staticmethod-decorator" + ) + def visit_assign(self, assign_node): + self._check_classmethod_declaration(assign_node) + node = assign_node.targets[0] + if not isinstance(node, astroid.AssignAttr): + return + + if self._uses_mandatory_method_param(node): + return + self._check_protected_attribute_access(node) + + def _check_classmethod_declaration(self, node): + """Checks for uses of classmethod() or staticmethod() + + When a @classmethod or @staticmethod decorator should be used instead. + A message will be emitted only if the assignment is at a class scope + and only if the classmethod's argument belongs to the class where it + is defined. + `node` is an assign node. + """ + if not isinstance(node.value, astroid.Call): + return + + # check the function called is "classmethod" or "staticmethod" + func = node.value.func + if not isinstance(func, astroid.Name) or func.name not in ( + "classmethod", + "staticmethod", + ): + return + + msg = ( + "no-classmethod-decorator" + if func.name == "classmethod" + else "no-staticmethod-decorator" + ) + # assignment must be at a class scope + parent_class = node.scope() + if not isinstance(parent_class, astroid.ClassDef): + return + + # Check if the arg passed to classmethod is a class member + classmeth_arg = node.value.args[0] + if not isinstance(classmeth_arg, astroid.Name): + return + + method_name = classmeth_arg.name + if any(method_name == member.name for member in parent_class.mymethods()): + self.add_message(msg, node=node.targets[0]) + + def _check_protected_attribute_access(self, node): + """Given an attribute access node (set or get), check if attribute + access is legitimate. Call _check_first_attr with node before calling + this method. Valid cases are: + * self._attr in a method or cls._attr in a classmethod. Checked by + _check_first_attr. + * Klass._attr inside "Klass" class. + * Klass2._attr inside "Klass" class when Klass2 is a base class of + Klass. + """ + attrname = node.attrname + + if ( + is_attr_protected(attrname) + and attrname not in self.config.exclude_protected + ): + + klass = node_frame_class(node) + + # XXX infer to be more safe and less dirty ?? + # in classes, check we are not getting a parent method + # through the class object or through super + callee = node.expr.as_string() + + # We are not in a class, no remaining valid case + if klass is None: + self.add_message("protected-access", node=node, args=attrname) + return + + # If the expression begins with a call to super, that's ok. + if ( + isinstance(node.expr, astroid.Call) + and isinstance(node.expr.func, astroid.Name) + and node.expr.func.name == "super" + ): + return + + # If the expression begins with a call to type(self), that's ok. + if self._is_type_self_call(node.expr): + return + + # We are in a class, one remaining valid cases, Klass._attr inside + # Klass + if not (callee == klass.name or callee in klass.basenames): + # Detect property assignments in the body of the class. + # This is acceptable: + # + # class A: + # b = property(lambda: self._b) + + stmt = node.parent.statement() + if ( + isinstance(stmt, astroid.Assign) + and len(stmt.targets) == 1 + and isinstance(stmt.targets[0], astroid.AssignName) + ): + name = stmt.targets[0].name + if _is_attribute_property(name, klass): + return + + self.add_message("protected-access", node=node, args=attrname) + + def _is_type_self_call(self, expr): + return ( + isinstance(expr, astroid.Call) + and isinstance(expr.func, astroid.Name) + and expr.func.name == "type" + and len(expr.args) == 1 + and self._is_mandatory_method_param(expr.args[0]) + ) + + def visit_name(self, node): + """check if the name handle an access to a class member + if so, register it + """ + if self._first_attrs and ( + node.name == self._first_attrs[-1] or not self._first_attrs[-1] + ): + self._meth_could_be_func = False + + def _check_accessed_members(self, node, accessed): + """check that accessed members are defined""" + # XXX refactor, probably much simpler now that E0201 is in type checker + excs = ("AttributeError", "Exception", "BaseException") + for attr, nodes in accessed.items(): + try: + # is it a class attribute ? + node.local_attr(attr) + # yes, stop here + continue + except astroid.NotFoundError: + pass + # is it an instance attribute of a parent class ? + try: + next(node.instance_attr_ancestors(attr)) + # yes, stop here + continue + except StopIteration: + pass + # is it an instance attribute ? + try: + defstmts = node.instance_attr(attr) + except astroid.NotFoundError: + pass + else: + # filter out augment assignment nodes + defstmts = [stmt for stmt in defstmts if stmt not in nodes] + if not defstmts: + # only augment assignment for this node, no-member should be + # triggered by the typecheck checker + continue + # filter defstmts to only pick the first one when there are + # several assignments in the same scope + scope = defstmts[0].scope() + defstmts = [ + stmt + for i, stmt in enumerate(defstmts) + if i == 0 or stmt.scope() is not scope + ] + # if there are still more than one, don't attempt to be smarter + # than we can be + if len(defstmts) == 1: + defstmt = defstmts[0] + # check that if the node is accessed in the same method as + # it's defined, it's accessed after the initial assignment + frame = defstmt.frame() + lno = defstmt.fromlineno + for _node in nodes: + if ( + _node.frame() is frame + and _node.fromlineno < lno + and not astroid.are_exclusive( + _node.statement(), defstmt, excs + ) + ): + self.add_message( + "access-member-before-definition", + node=_node, + args=(attr, lno), + ) + + def _check_first_arg_for_type(self, node, metaclass=0): + """check the name of first argument, expect: + + * 'self' for a regular method + * 'cls' for a class method or a metaclass regular method (actually + valid-classmethod-first-arg value) + * 'mcs' for a metaclass class method (actually + valid-metaclass-classmethod-first-arg) + * not one of the above for a static method + """ + # don't care about functions with unknown argument (builtins) + if node.args.args is None: + return + first_arg = node.args.args and node.argnames()[0] + self._first_attrs.append(first_arg) + first = self._first_attrs[-1] + # static method + if node.type == "staticmethod": + if ( + first_arg == "self" + or first_arg in self.config.valid_classmethod_first_arg + or first_arg in self.config.valid_metaclass_classmethod_first_arg + ): + self.add_message("bad-staticmethod-argument", args=first, node=node) + return + self._first_attrs[-1] = None + # class / regular method with no args + elif not node.args.args: + self.add_message("no-method-argument", node=node) + # metaclass + elif metaclass: + # metaclass __new__ or classmethod + if node.type == "classmethod": + self._check_first_arg_config( + first, + self.config.valid_metaclass_classmethod_first_arg, + node, + "bad-mcs-classmethod-argument", + node.name, + ) + # metaclass regular method + else: + self._check_first_arg_config( + first, + self.config.valid_classmethod_first_arg, + node, + "bad-mcs-method-argument", + node.name, + ) + # regular class + else: + # class method + if node.type == "classmethod": + self._check_first_arg_config( + first, + self.config.valid_classmethod_first_arg, + node, + "bad-classmethod-argument", + node.name, + ) + # regular method without self as argument + elif first != "self": + self.add_message("no-self-argument", node=node) + + def _check_first_arg_config(self, first, config, node, message, method_name): + if first not in config: + if len(config) == 1: + valid = repr(config[0]) + else: + valid = ", ".join(repr(v) for v in config[:-1]) + valid = "%s or %r" % (valid, config[-1]) + self.add_message(message, args=(method_name, valid), node=node) + + def _check_bases_classes(self, node): + """check that the given class node implements abstract methods from + base classes + """ + + def is_abstract(method): + return method.is_abstract(pass_is_abstract=False) + + # check if this class abstract + if class_is_abstract(node): + return + + methods = sorted( + unimplemented_abstract_methods(node, is_abstract).items(), + key=lambda item: item[0], + ) + for name, method in methods: + owner = method.parent.frame() + if owner is node: + continue + # owner is not this class, it must be a parent class + # check that the ancestor's method is not abstract + if name in node.locals: + # it is redefined as an attribute or with a descriptor + continue + self.add_message("abstract-method", node=node, args=(name, owner.name)) + + def _check_init(self, node): + """check that the __init__ method call super or ancestors'__init__ + method + """ + if not self.linter.is_message_enabled( + "super-init-not-called" + ) and not self.linter.is_message_enabled("non-parent-init-called"): + return + klass_node = node.parent.frame() + to_call = _ancestors_to_call(klass_node) + not_called_yet = dict(to_call) + for stmt in node.nodes_of_class(astroid.Call): + expr = stmt.func + if not isinstance(expr, astroid.Attribute) or expr.attrname != "__init__": + continue + # skip the test if using super + if ( + isinstance(expr.expr, astroid.Call) + and isinstance(expr.expr.func, astroid.Name) + and expr.expr.func.name == "super" + ): + return + try: + for klass in expr.expr.infer(): + if klass is astroid.Uninferable: + continue + # The infered klass can be super(), which was + # assigned to a variable and the `__init__` + # was called later. + # + # base = super() + # base.__init__(...) + + if ( + isinstance(klass, astroid.Instance) + and isinstance(klass._proxied, astroid.ClassDef) + and is_builtin_object(klass._proxied) + and klass._proxied.name == "super" + ): + return + if isinstance(klass, objects.Super): + return + try: + del not_called_yet[klass] + except KeyError: + if klass not in to_call: + self.add_message( + "non-parent-init-called", node=expr, args=klass.name + ) + except astroid.InferenceError: + continue + for klass, method in not_called_yet.items(): + cls = node_frame_class(method) + if klass.name == "object" or (cls and cls.name == "object"): + continue + self.add_message("super-init-not-called", args=klass.name, node=node) + + def _check_signature(self, method1, refmethod, class_type, cls): + """check that the signature of the two given methods match + """ + if not ( + isinstance(method1, astroid.FunctionDef) + and isinstance(refmethod, astroid.FunctionDef) + ): + self.add_message( + "method-check-failed", args=(method1, refmethod), node=method1 + ) + return + + instance = cls.instantiate_class() + method1 = function_to_method(method1, instance) + refmethod = function_to_method(refmethod, instance) + + # Don't care about functions with unknown argument (builtins). + if method1.args.args is None or refmethod.args.args is None: + return + + # Ignore private to class methods. + if is_attr_private(method1.name): + return + # Ignore setters, they have an implicit extra argument, + # which shouldn't be taken in consideration. + if method1.decorators: + for decorator in method1.decorators.nodes: + if ( + isinstance(decorator, astroid.Attribute) + and decorator.attrname == "setter" + ): + return + + if _different_parameters( + refmethod, method1, dummy_parameter_regex=self._dummy_rgx + ): + self.add_message( + "arguments-differ", args=(class_type, method1.name), node=method1 + ) + elif len(method1.args.defaults) < len(refmethod.args.defaults): + self.add_message( + "signature-differs", args=(class_type, method1.name), node=method1 + ) + + def _uses_mandatory_method_param(self, node): + """Check that attribute lookup name use first attribute variable name + + Name is `self` for method, `cls` for classmethod and `mcs` for metaclass. + """ + return self._is_mandatory_method_param(node.expr) + + def _is_mandatory_method_param(self, node): + """Check if astroid.Name corresponds to first attribute variable name + + Name is `self` for method, `cls` for classmethod and `mcs` for metaclass. + """ + return ( + self._first_attrs + and isinstance(node, astroid.Name) + and node.name == self._first_attrs[-1] + ) + + +class SpecialMethodsChecker(BaseChecker): + """Checker which verifies that special methods + are implemented correctly. + """ + + __implements__ = (IAstroidChecker,) + name = "classes" + msgs = { + "E0301": ( + "__iter__ returns non-iterator", + "non-iterator-returned", + "Used when an __iter__ method returns something which is not an " + "iterable (i.e. has no `%s` method)" % NEXT_METHOD, + { + "old_names": [ + ("W0234", "non-iterator-returned"), + ("E0234", "non-iterator-returned"), + ] + }, + ), + "E0302": ( + "The special method %r expects %s param(s), %d %s given", + "unexpected-special-method-signature", + "Emitted when a special method was defined with an " + "invalid number of parameters. If it has too few or " + "too many, it might not work at all.", + {"old_names": [("E0235", "bad-context-manager")]}, + ), + "E0303": ( + "__len__ does not return non-negative integer", + "invalid-length-returned", + "Used when a __len__ method returns something which is not a " + "non-negative integer", + {}, + ), + } + priority = -2 + + @check_messages( + "unexpected-special-method-signature", + "non-iterator-returned", + "invalid-length-returned", + ) + def visit_functiondef(self, node): + if not node.is_method(): + return + if node.name == "__iter__": + self._check_iter(node) + if node.name == "__len__": + self._check_len(node) + if node.name in PYMETHODS: + self._check_unexpected_method_signature(node) + + visit_asyncfunctiondef = visit_functiondef + + def _check_unexpected_method_signature(self, node): + expected_params = SPECIAL_METHODS_PARAMS[node.name] + + if expected_params is None: + # This can support a variable number of parameters. + return + if not node.args.args and not node.args.vararg: + # Method has no parameter, will be caught + # by no-method-argument. + return + + if decorated_with(node, [BUILTINS + ".staticmethod"]): + # We expect to not take in consideration self. + all_args = node.args.args + else: + all_args = node.args.args[1:] + mandatory = len(all_args) - len(node.args.defaults) + optional = len(node.args.defaults) + current_params = mandatory + optional + + if isinstance(expected_params, tuple): + # The expected number of parameters can be any value from this + # tuple, although the user should implement the method + # to take all of them in consideration. + emit = mandatory not in expected_params + expected_params = "between %d or %d" % expected_params + else: + # If the number of mandatory parameters doesn't + # suffice, the expected parameters for this + # function will be deduced from the optional + # parameters. + rest = expected_params - mandatory + if rest == 0: + emit = False + elif rest < 0: + emit = True + elif rest > 0: + emit = not ((optional - rest) >= 0 or node.args.vararg) + + if emit: + verb = "was" if current_params <= 1 else "were" + self.add_message( + "unexpected-special-method-signature", + args=(node.name, expected_params, current_params, verb), + node=node, + ) + + @staticmethod + def _is_iterator(node): + if node is astroid.Uninferable: + # Just ignore Uninferable objects. + return True + if isinstance(node, Generator): + # Generators can be itered. + return True + + if isinstance(node, astroid.Instance): + try: + node.local_attr(NEXT_METHOD) + return True + except astroid.NotFoundError: + pass + elif isinstance(node, astroid.ClassDef): + metaclass = node.metaclass() + if metaclass and isinstance(metaclass, astroid.ClassDef): + try: + metaclass.local_attr(NEXT_METHOD) + return True + except astroid.NotFoundError: + pass + return False + + def _check_iter(self, node): + infered = _safe_infer_call_result(node, node) + if infered is not None: + if not self._is_iterator(infered): + self.add_message("non-iterator-returned", node=node) + + def _check_len(self, node): + inferred = _safe_infer_call_result(node, node) + if not inferred or inferred is astroid.Uninferable: + return + + if ( + isinstance(inferred, astroid.Instance) + and inferred.name == "int" + and not isinstance(inferred, astroid.Const) + ): + # Assume it's good enough, since the int() call might wrap + # something that's uninferable for us + return + + if not isinstance(inferred, astroid.Const): + self.add_message("invalid-length-returned", node=node) + return + + value = inferred.value + if not isinstance(value, int) or value < 0: + self.add_message("invalid-length-returned", node=node) + + +def _ancestors_to_call(klass_node, method="__init__"): + """return a dictionary where keys are the list of base classes providing + the queried method, and so that should/may be called from the method node + """ + to_call = {} + for base_node in klass_node.ancestors(recurs=False): + try: + to_call[base_node] = next(base_node.igetattr(method)) + except astroid.InferenceError: + continue + return to_call + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(ClassChecker(linter)) + linter.register_checker(SpecialMethodsChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/design_analysis.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/design_analysis.py new file mode 100644 index 0000000..a0c48b9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/design_analysis.py @@ -0,0 +1,530 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006, 2009-2010, 2012-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012, 2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 ahirnish <ahirnish@gmail.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 Mark Miller <725mrm@gmail.com> +# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Copyright (c) 2018 Jakub Wilk <jwilk@jwilk.net> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""check for signs of poor design""" + +from collections import defaultdict +import re + +import astroid +from astroid import If, BoolOp +from astroid import decorators + +from pylint.interfaces import IAstroidChecker +from pylint.checkers import BaseChecker +from pylint.checkers.utils import check_messages +from pylint import utils + + +MSGS = { + "R0901": ( + "Too many ancestors (%s/%s)", + "too-many-ancestors", + "Used when class has too many parent classes, try to reduce " + "this to get a simpler (and so easier to use) class.", + ), + "R0902": ( + "Too many instance attributes (%s/%s)", + "too-many-instance-attributes", + "Used when class has too many instance attributes, try to reduce " + "this to get a simpler (and so easier to use) class.", + ), + "R0903": ( + "Too few public methods (%s/%s)", + "too-few-public-methods", + "Used when class has too few public methods, so be sure it's " + "really worth it.", + ), + "R0904": ( + "Too many public methods (%s/%s)", + "too-many-public-methods", + "Used when class has too many public methods, try to reduce " + "this to get a simpler (and so easier to use) class.", + ), + "R0911": ( + "Too many return statements (%s/%s)", + "too-many-return-statements", + "Used when a function or method has too many return statement, " + "making it hard to follow.", + ), + "R0912": ( + "Too many branches (%s/%s)", + "too-many-branches", + "Used when a function or method has too many branches, " + "making it hard to follow.", + ), + "R0913": ( + "Too many arguments (%s/%s)", + "too-many-arguments", + "Used when a function or method takes too many arguments.", + ), + "R0914": ( + "Too many local variables (%s/%s)", + "too-many-locals", + "Used when a function or method has too many local variables.", + ), + "R0915": ( + "Too many statements (%s/%s)", + "too-many-statements", + "Used when a function or method has too many statements. You " + "should then split it in smaller functions / methods.", + ), + "R0916": ( + "Too many boolean expressions in if statement (%s/%s)", + "too-many-boolean-expressions", + "Used when an if statement contains too many boolean expressions.", + ), +} +SPECIAL_OBJ = re.compile("^_{2}[a-z]+_{2}$") +DATACLASS_DECORATOR = "dataclass" +DATACLASS_IMPORT = "dataclasses" +TYPING_NAMEDTUPLE = "typing.NamedTuple" + + +def _is_typing_namedtuple(node: astroid.ClassDef) -> bool: + """Check if a class node is a typing.NamedTuple class""" + for base in node.ancestors(): + if base.qname() == TYPING_NAMEDTUPLE: + return True + return False + + +def _is_enum_class(node: astroid.ClassDef) -> bool: + """Check if a class definition defines an Enum class. + + :param node: The class node to check. + :type node: astroid.ClassDef + + :returns: True if the given node represents an Enum class. False otherwise. + :rtype: bool + """ + for base in node.bases: + try: + inferred_bases = base.inferred() + except astroid.InferenceError: + continue + + for ancestor in inferred_bases: + if not isinstance(ancestor, astroid.ClassDef): + continue + + if ancestor.name == "Enum" and ancestor.root().name == "enum": + return True + + return False + + +def _is_dataclass(node: astroid.ClassDef) -> bool: + """Check if a class definition defines a Python 3.7+ dataclass + + :param node: The class node to check. + :type node: astroid.ClassDef + + :returns: True if the given node represents a dataclass class. False otherwise. + :rtype: bool + """ + if not node.decorators: + return False + + root_locals = node.root().locals + for decorator in node.decorators.nodes: + if isinstance(decorator, astroid.Call): + decorator = decorator.func + if not isinstance(decorator, (astroid.Name, astroid.Attribute)): + continue + if isinstance(decorator, astroid.Name): + name = decorator.name + else: + name = decorator.attrname + if name == DATACLASS_DECORATOR and DATACLASS_DECORATOR in root_locals: + return True + return False + + +def _count_boolean_expressions(bool_op): + """Counts the number of boolean expressions in BoolOp `bool_op` (recursive) + + example: a and (b or c or (d and e)) ==> 5 boolean expressions + """ + nb_bool_expr = 0 + for bool_expr in bool_op.get_children(): + if isinstance(bool_expr, BoolOp): + nb_bool_expr += _count_boolean_expressions(bool_expr) + else: + nb_bool_expr += 1 + return nb_bool_expr + + +def _count_methods_in_class(node): + all_methods = sum(1 for method in node.methods() if not method.name.startswith("_")) + # Special methods count towards the number of public methods, + # but don't count towards there being too many methods. + for method in node.mymethods(): + if SPECIAL_OBJ.search(method.name) and method.name != "__init__": + all_methods += 1 + return all_methods + + +class MisdesignChecker(BaseChecker): + """checks for sign of poor/misdesign: + * number of methods, attributes, local variables... + * size, complexity of functions, methods + """ + + __implements__ = (IAstroidChecker,) + + # configuration section name + name = "design" + # messages + msgs = MSGS + priority = -2 + # configuration options + options = ( + ( + "max-args", + { + "default": 5, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of arguments for function / method.", + }, + ), + ( + "max-locals", + { + "default": 15, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of locals for function / method body.", + }, + ), + ( + "max-returns", + { + "default": 6, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of return / yield for function / " + "method body.", + }, + ), + ( + "max-branches", + { + "default": 12, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of branch for function / method body.", + }, + ), + ( + "max-statements", + { + "default": 50, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of statements in function / method " "body.", + }, + ), + ( + "max-parents", + { + "default": 7, + "type": "int", + "metavar": "<num>", + "help": "Maximum number of parents for a class (see R0901).", + }, + ), + ( + "max-attributes", + { + "default": 7, + "type": "int", + "metavar": "<num>", + "help": "Maximum number of attributes for a class \ +(see R0902).", + }, + ), + ( + "min-public-methods", + { + "default": 2, + "type": "int", + "metavar": "<num>", + "help": "Minimum number of public methods for a class \ +(see R0903).", + }, + ), + ( + "max-public-methods", + { + "default": 20, + "type": "int", + "metavar": "<num>", + "help": "Maximum number of public methods for a class \ +(see R0904).", + }, + ), + ( + "max-bool-expr", + { + "default": 5, + "type": "int", + "metavar": "<num>", + "help": "Maximum number of boolean expressions in an if " "statement.", + }, + ), + ) + + def __init__(self, linter=None): + BaseChecker.__init__(self, linter) + self.stats = None + self._returns = None + self._branches = None + self._stmts = None + + def open(self): + """initialize visit variables""" + self.stats = self.linter.add_stats() + self._returns = [] + self._branches = defaultdict(int) + self._stmts = [] + + def _inc_all_stmts(self, amount): + for i in range(len(self._stmts)): + self._stmts[i] += amount + + @decorators.cachedproperty + def _ignored_argument_names(self): + return utils.get_global_option(self, "ignored-argument-names", default=None) + + @check_messages( + "too-many-ancestors", + "too-many-instance-attributes", + "too-few-public-methods", + "too-many-public-methods", + ) + def visit_classdef(self, node): + """check size of inheritance hierarchy and number of instance attributes + """ + nb_parents = len(list(node.ancestors())) + if nb_parents > self.config.max_parents: + self.add_message( + "too-many-ancestors", + node=node, + args=(nb_parents, self.config.max_parents), + ) + + if len(node.instance_attrs) > self.config.max_attributes: + self.add_message( + "too-many-instance-attributes", + node=node, + args=(len(node.instance_attrs), self.config.max_attributes), + ) + + @check_messages("too-few-public-methods", "too-many-public-methods") + def leave_classdef(self, node): + """check number of public methods""" + my_methods = sum( + 1 for method in node.mymethods() if not method.name.startswith("_") + ) + + # Does the class contain less than n public methods ? + # This checks only the methods defined in the current class, + # since the user might not have control over the classes + # from the ancestors. It avoids some false positives + # for classes such as unittest.TestCase, which provides + # a lot of assert methods. It doesn't make sense to warn + # when the user subclasses TestCase to add his own tests. + if my_methods > self.config.max_public_methods: + self.add_message( + "too-many-public-methods", + node=node, + args=(my_methods, self.config.max_public_methods), + ) + + # Stop here for exception, metaclass, interface classes and other + # classes for which we don't need to count the methods. + if ( + node.type != "class" + or _is_enum_class(node) + or _is_dataclass(node) + or _is_typing_namedtuple(node) + ): + return + + # Does the class contain more than n public methods ? + # This checks all the methods defined by ancestors and + # by the current class. + all_methods = _count_methods_in_class(node) + if all_methods < self.config.min_public_methods: + self.add_message( + "too-few-public-methods", + node=node, + args=(all_methods, self.config.min_public_methods), + ) + + @check_messages( + "too-many-return-statements", + "too-many-branches", + "too-many-arguments", + "too-many-locals", + "too-many-statements", + "keyword-arg-before-vararg", + ) + def visit_functiondef(self, node): + """check function name, docstring, arguments, redefinition, + variable names, max locals + """ + # init branch and returns counters + self._returns.append(0) + # check number of arguments + args = node.args.args + ignored_argument_names = self._ignored_argument_names + if args is not None: + ignored_args_num = 0 + if ignored_argument_names: + ignored_args_num = sum( + 1 for arg in args if ignored_argument_names.match(arg.name) + ) + + argnum = len(args) - ignored_args_num + if argnum > self.config.max_args: + self.add_message( + "too-many-arguments", + node=node, + args=(len(args), self.config.max_args), + ) + else: + ignored_args_num = 0 + # check number of local variables + locnum = len(node.locals) - ignored_args_num + if locnum > self.config.max_locals: + self.add_message( + "too-many-locals", node=node, args=(locnum, self.config.max_locals) + ) + # init new statements counter + self._stmts.append(1) + + visit_asyncfunctiondef = visit_functiondef + + @check_messages( + "too-many-return-statements", + "too-many-branches", + "too-many-arguments", + "too-many-locals", + "too-many-statements", + ) + def leave_functiondef(self, node): + """most of the work is done here on close: + checks for max returns, branch, return in __init__ + """ + returns = self._returns.pop() + if returns > self.config.max_returns: + self.add_message( + "too-many-return-statements", + node=node, + args=(returns, self.config.max_returns), + ) + branches = self._branches[node] + if branches > self.config.max_branches: + self.add_message( + "too-many-branches", + node=node, + args=(branches, self.config.max_branches), + ) + # check number of statements + stmts = self._stmts.pop() + if stmts > self.config.max_statements: + self.add_message( + "too-many-statements", + node=node, + args=(stmts, self.config.max_statements), + ) + + leave_asyncfunctiondef = leave_functiondef + + def visit_return(self, _): + """count number of returns""" + if not self._returns: + return # return outside function, reported by the base checker + self._returns[-1] += 1 + + def visit_default(self, node): + """default visit method -> increments the statements counter if + necessary + """ + if node.is_statement: + self._inc_all_stmts(1) + + def visit_tryexcept(self, node): + """increments the branches counter""" + branches = len(node.handlers) + if node.orelse: + branches += 1 + self._inc_branch(node, branches) + self._inc_all_stmts(branches) + + def visit_tryfinally(self, node): + """increments the branches counter""" + self._inc_branch(node, 2) + self._inc_all_stmts(2) + + @check_messages("too-many-boolean-expressions") + def visit_if(self, node): + """increments the branches counter and checks boolean expressions""" + self._check_boolean_expressions(node) + branches = 1 + # don't double count If nodes coming from some 'elif' + if node.orelse and (len(node.orelse) > 1 or not isinstance(node.orelse[0], If)): + branches += 1 + self._inc_branch(node, branches) + self._inc_all_stmts(branches) + + def _check_boolean_expressions(self, node): + """Go through "if" node `node` and counts its boolean expressions + + if the "if" node test is a BoolOp node + """ + condition = node.test + if not isinstance(condition, BoolOp): + return + nb_bool_expr = _count_boolean_expressions(condition) + if nb_bool_expr > self.config.max_bool_expr: + self.add_message( + "too-many-boolean-expressions", + node=condition, + args=(nb_bool_expr, self.config.max_bool_expr), + ) + + def visit_while(self, node): + """increments the branches counter""" + branches = 1 + if node.orelse: + branches += 1 + self._inc_branch(node, branches) + + visit_for = visit_while + + def _inc_branch(self, node, branchesnum=1): + """increments the branches counter""" + self._branches[node.scope()] += branchesnum + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(MisdesignChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/exceptions.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/exceptions.py new file mode 100644 index 0000000..e0a449c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/exceptions.py @@ -0,0 +1,534 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2011-2014 Google, Inc. +# Copyright (c) 2012 Tim Hatch <tim@timhatch.com> +# Copyright (c) 2013-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Rene Zhang <rz99@cornell.edu> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Steven Myint <hg@stevenmyint.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Erik <erik.eriksson@yahoo.com> +# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Martin von Gagern <gagern@google.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Checks for various exception related errors.""" +import builtins +import inspect +import sys +import typing + +import astroid + +from pylint import checkers +from pylint.checkers import utils +from pylint import interfaces + + +def _builtin_exceptions(): + def predicate(obj): + return isinstance(obj, type) and issubclass(obj, BaseException) + + members = inspect.getmembers(builtins, predicate) + return {exc.__name__ for (_, exc) in members} + + +def _annotated_unpack_infer(stmt, context=None): + """ + Recursively generate nodes inferred by the given statement. + If the inferred value is a list or a tuple, recurse on the elements. + Returns an iterator which yields tuples in the format + ('original node', 'infered node'). + """ + if isinstance(stmt, (astroid.List, astroid.Tuple)): + for elt in stmt.elts: + inferred = utils.safe_infer(elt) + if inferred and inferred is not astroid.Uninferable: + yield elt, inferred + return + for infered in stmt.infer(context): + if infered is astroid.Uninferable: + continue + yield stmt, infered + + +def _is_raising(body: typing.List) -> bool: + """Return true if the given statement node raise an exception""" + for node in body: + if isinstance(node, astroid.Raise): + return True + return False + + +PY3K = sys.version_info >= (3, 0) +OVERGENERAL_EXCEPTIONS = ("Exception",) +BUILTINS_NAME = builtins.__name__ + +MSGS = { + "E0701": ( + "Bad except clauses order (%s)", + "bad-except-order", + "Used when except clauses are not in the correct order (from the " + "more specific to the more generic). If you don't fix the order, " + "some exceptions may not be caught by the most specific handler.", + ), + "E0702": ( + "Raising %s while only classes or instances are allowed", + "raising-bad-type", + "Used when something which is neither a class, an instance or a " + "string is raised (i.e. a `TypeError` will be raised).", + ), + "E0703": ( + "Exception context set to something which is not an exception, nor None", + "bad-exception-context", + 'Used when using the syntax "raise ... from ...", ' + "where the exception context is not an exception, " + "nor None.", + ), + "E0704": ( + "The raise statement is not inside an except clause", + "misplaced-bare-raise", + "Used when a bare raise is not used inside an except clause. " + "This generates an error, since there are no active exceptions " + "to be reraised. An exception to this rule is represented by " + "a bare raise inside a finally clause, which might work, as long " + "as an exception is raised inside the try block, but it is " + "nevertheless a code smell that must not be relied upon.", + ), + "E0710": ( + "Raising a new style class which doesn't inherit from BaseException", + "raising-non-exception", + "Used when a new style class which doesn't inherit from " + "BaseException is raised.", + ), + "E0711": ( + "NotImplemented raised - should raise NotImplementedError", + "notimplemented-raised", + "Used when NotImplemented is raised instead of NotImplementedError", + ), + "E0712": ( + "Catching an exception which doesn't inherit from Exception: %s", + "catching-non-exception", + "Used when a class which doesn't inherit from " + "Exception is used as an exception in an except clause.", + ), + "W0702": ( + "No exception type(s) specified", + "bare-except", + "Used when an except clause doesn't specify exceptions type to catch.", + ), + "W0703": ( + "Catching too general exception %s", + "broad-except", + "Used when an except catches a too general exception, " + "possibly burying unrelated errors.", + ), + "W0705": ( + "Catching previously caught exception type %s", + "duplicate-except", + "Used when an except catches a type that was already caught by " + "a previous handler.", + ), + "W0706": ( + "The except handler raises immediately", + "try-except-raise", + "Used when an except handler uses raise as its first or only " + "operator. This is useless because it raises back the exception " + "immediately. Remove the raise operator or the entire " + "try-except-raise block!", + ), + "W0711": ( + 'Exception to catch is the result of a binary "%s" operation', + "binary-op-exception", + "Used when the exception to catch is of the form " + '"except A or B:". If intending to catch multiple, ' + 'rewrite as "except (A, B):"', + ), + "W0715": ( + "Exception arguments suggest string formatting might be intended", + "raising-format-tuple", + "Used when passing multiple arguments to an exception " + "constructor, the first of them a string literal containing what " + "appears to be placeholders intended for formatting", + ), +} + + +class BaseVisitor: + """Base class for visitors defined in this module.""" + + def __init__(self, checker, node): + self._checker = checker + self._node = node + + def visit(self, node): + name = node.__class__.__name__.lower() + dispatch_meth = getattr(self, "visit_" + name, None) + if dispatch_meth: + dispatch_meth(node) + else: + self.visit_default(node) + + def visit_default(self, node): # pylint: disable=unused-argument + """Default implementation for all the nodes.""" + + +class ExceptionRaiseRefVisitor(BaseVisitor): + """Visit references (anything that is not an AST leaf).""" + + def visit_name(self, name): + if name.name == "NotImplemented": + self._checker.add_message("notimplemented-raised", node=self._node) + + def visit_call(self, call): + if isinstance(call.func, astroid.Name): + self.visit_name(call.func) + if ( + len(call.args) > 1 + and isinstance(call.args[0], astroid.Const) + and isinstance(call.args[0].value, str) + ): + msg = call.args[0].value + if "%" in msg or ("{" in msg and "}" in msg): + self._checker.add_message("raising-format-tuple", node=self._node) + + +class ExceptionRaiseLeafVisitor(BaseVisitor): + """Visitor for handling leaf kinds of a raise value.""" + + def visit_const(self, const): + if not isinstance(const.value, str): + # raising-string will be emitted from python3 porting checker. + self._checker.add_message( + "raising-bad-type", node=self._node, args=const.value.__class__.__name__ + ) + + def visit_instance(self, instance): + # pylint: disable=protected-access + cls = instance._proxied + self.visit_classdef(cls) + + # Exception instances have a particular class type + visit_exceptioninstance = visit_instance + + def visit_classdef(self, cls): + if not utils.inherit_from_std_ex(cls) and utils.has_known_bases(cls): + if cls.newstyle: + self._checker.add_message("raising-non-exception", node=self._node) + else: + self._checker.add_message("nonstandard-exception", node=self._node) + + def visit_tuple(self, tuple_node): + if PY3K or not tuple_node.elts: + self._checker.add_message("raising-bad-type", node=self._node, args="tuple") + return + + # On Python 2, using the following is not an error: + # raise (ZeroDivisionError, None) + # raise (ZeroDivisionError, ) + # What's left to do is to check that the first + # argument is indeed an exception. Verifying the other arguments + # is not the scope of this check. + first = tuple_node.elts[0] + inferred = utils.safe_infer(first) + if not inferred or inferred is astroid.Uninferable: + return + + if ( + isinstance(inferred, astroid.Instance) + and inferred.__class__.__name__ != "Instance" + ): + # TODO: explain why + self.visit_default(tuple_node) + else: + self.visit(inferred) + + def visit_default(self, node): + name = getattr(node, "name", node.__class__.__name__) + self._checker.add_message("raising-bad-type", node=self._node, args=name) + + +class ExceptionsChecker(checkers.BaseChecker): + """Exception related checks.""" + + __implements__ = interfaces.IAstroidChecker + + name = "exceptions" + msgs = MSGS + priority = -4 + options = ( + ( + "overgeneral-exceptions", + { + "default": OVERGENERAL_EXCEPTIONS, + "type": "csv", + "metavar": "<comma-separated class names>", + "help": "Exceptions that will emit a warning " + 'when being caught. Defaults to "%s".' + % (", ".join(OVERGENERAL_EXCEPTIONS),), + }, + ), + ) + + def open(self): + self._builtin_exceptions = _builtin_exceptions() + super(ExceptionsChecker, self).open() + + @utils.check_messages( + "nonstandard-exception", + "misplaced-bare-raise", + "raising-bad-type", + "raising-non-exception", + "notimplemented-raised", + "bad-exception-context", + "raising-format-tuple", + ) + def visit_raise(self, node): + if node.exc is None: + self._check_misplaced_bare_raise(node) + return + + if PY3K and node.cause: + self._check_bad_exception_context(node) + + expr = node.exc + ExceptionRaiseRefVisitor(self, node).visit(expr) + + try: + inferred_value = expr.inferred()[-1] + except astroid.InferenceError: + pass + else: + if inferred_value: + ExceptionRaiseLeafVisitor(self, node).visit(inferred_value) + + def _check_misplaced_bare_raise(self, node): + # Filter out if it's present in __exit__. + scope = node.scope() + if ( + isinstance(scope, astroid.FunctionDef) + and scope.is_method() + and scope.name == "__exit__" + ): + return + + current = node + # Stop when a new scope is generated or when the raise + # statement is found inside a TryFinally. + ignores = (astroid.ExceptHandler, astroid.FunctionDef) + while current and not isinstance(current.parent, ignores): + current = current.parent + + expected = (astroid.ExceptHandler,) + if not current or not isinstance(current.parent, expected): + self.add_message("misplaced-bare-raise", node=node) + + def _check_bad_exception_context(self, node): + """Verify that the exception context is properly set. + + An exception context can be only `None` or an exception. + """ + cause = utils.safe_infer(node.cause) + if cause in (astroid.Uninferable, None): + return + + if isinstance(cause, astroid.Const): + if cause.value is not None: + self.add_message("bad-exception-context", node=node) + elif not isinstance(cause, astroid.ClassDef) and not utils.inherit_from_std_ex( + cause + ): + self.add_message("bad-exception-context", node=node) + + def _check_catching_non_exception(self, handler, exc, part): + if isinstance(exc, astroid.Tuple): + # Check if it is a tuple of exceptions. + inferred = [utils.safe_infer(elt) for elt in exc.elts] + if any(node is astroid.Uninferable for node in inferred): + # Don't emit if we don't know every component. + return + if all( + node + and (utils.inherit_from_std_ex(node) or not utils.has_known_bases(node)) + for node in inferred + ): + return + + if not isinstance(exc, astroid.ClassDef): + # Don't emit the warning if the infered stmt + # is None, but the exception handler is something else, + # maybe it was redefined. + if isinstance(exc, astroid.Const) and exc.value is None: + if ( + isinstance(handler.type, astroid.Const) + and handler.type.value is None + ) or handler.type.parent_of(exc): + # If the exception handler catches None or + # the exception component, which is None, is + # defined by the entire exception handler, then + # emit a warning. + self.add_message( + "catching-non-exception", + node=handler.type, + args=(part.as_string(),), + ) + else: + self.add_message( + "catching-non-exception", + node=handler.type, + args=(part.as_string(),), + ) + return + + if ( + not utils.inherit_from_std_ex(exc) + and exc.name not in self._builtin_exceptions + ): + if utils.has_known_bases(exc): + self.add_message( + "catching-non-exception", node=handler.type, args=(exc.name,) + ) + + def _check_try_except_raise(self, node): + def gather_exceptions_from_handler(handler): + exceptions = [] + if handler.type: + exceptions_in_handler = utils.safe_infer(handler.type) + if isinstance(exceptions_in_handler, astroid.Tuple): + exceptions = { + exception + for exception in exceptions_in_handler.elts + if isinstance(exception, astroid.Name) + } + elif exceptions_in_handler: + exceptions = [exceptions_in_handler] + return exceptions + + bare_raise = False + handler_having_bare_raise = None + excs_in_bare_handler = [] + for handler in node.handlers: + if bare_raise: + # check that subsequent handler is not parent of handler which had bare raise. + # since utils.safe_infer can fail for bare except, check it before. + # also break early if bare except is followed by bare except. + + excs_in_current_handler = gather_exceptions_from_handler(handler) + if not excs_in_current_handler: + bare_raise = False + break + + for exc_in_current_handler in excs_in_current_handler: + inferred_current = utils.safe_infer(exc_in_current_handler) + if any( + utils.is_subclass_of( + utils.safe_infer(exc_in_bare_handler), inferred_current + ) + for exc_in_bare_handler in excs_in_bare_handler + ): + bare_raise = False + break + + # `raise` as the first operator inside the except handler + if _is_raising([handler.body[0]]): + # flags when there is a bare raise + if handler.body[0].exc is None: + bare_raise = True + handler_having_bare_raise = handler + excs_in_bare_handler = gather_exceptions_from_handler(handler) + if bare_raise: + self.add_message("try-except-raise", node=handler_having_bare_raise) + + @utils.check_messages( + "bare-except", + "broad-except", + "try-except-raise", + "binary-op-exception", + "bad-except-order", + "catching-non-exception", + "duplicate-except", + ) + def visit_tryexcept(self, node): + """check for empty except""" + self._check_try_except_raise(node) + exceptions_classes = [] + nb_handlers = len(node.handlers) + for index, handler in enumerate(node.handlers): + if handler.type is None: + if not _is_raising(handler.body): + self.add_message("bare-except", node=handler) + + # check if an "except:" is followed by some other + # except + if index < (nb_handlers - 1): + msg = "empty except clause should always appear last" + self.add_message("bad-except-order", node=node, args=msg) + + elif isinstance(handler.type, astroid.BoolOp): + self.add_message( + "binary-op-exception", node=handler, args=handler.type.op + ) + else: + try: + excs = list(_annotated_unpack_infer(handler.type)) + except astroid.InferenceError: + continue + + for part, exc in excs: + if exc is astroid.Uninferable: + continue + if isinstance(exc, astroid.Instance) and utils.inherit_from_std_ex( + exc + ): + # pylint: disable=protected-access + exc = exc._proxied + + self._check_catching_non_exception(handler, exc, part) + + if not isinstance(exc, astroid.ClassDef): + continue + + exc_ancestors = [ + anc + for anc in exc.ancestors() + if isinstance(anc, astroid.ClassDef) + ] + + for previous_exc in exceptions_classes: + if previous_exc in exc_ancestors: + msg = "%s is an ancestor class of %s" % ( + previous_exc.name, + exc.name, + ) + self.add_message( + "bad-except-order", node=handler.type, args=msg + ) + if ( + exc.name in self.config.overgeneral_exceptions + and exc.root().name == utils.EXCEPTIONS_MODULE + and not _is_raising(handler.body) + ): + self.add_message( + "broad-except", args=exc.name, node=handler.type + ) + + if exc in exceptions_classes: + self.add_message( + "duplicate-except", args=exc.name, node=handler.type + ) + + exceptions_classes += [exc for _, exc in excs] + + +def register(linter): + """required method to auto register this checker""" + linter.register_checker(ExceptionsChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/format.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/format.py new file mode 100644 index 0000000..38b6649 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/format.py @@ -0,0 +1,1341 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012-2015 Google, Inc. +# Copyright (c) 2013 moxian <aleftmail@inbox.ru> +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 frost-nzcr4 <frost.nzcr4@jagmort.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Mike Frysinger <vapier@gentoo.org> +# Copyright (c) 2015 Fabio Natali <me@fabionatali.com> +# Copyright (c) 2015 Harut <yes@harutune.name> +# Copyright (c) 2015 Mihai Balint <balint.mihai@gmail.com> +# Copyright (c) 2015 Pavel Roskin <proski@gnu.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Petr Pulc <petrpulc@gmail.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2017-2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Krzysztof Czapla <k.czapla68@gmail.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 James M. Allen <james.m.allen@gmail.com> +# Copyright (c) 2017 vinnyrose <vinnyrose@users.noreply.github.com> +# Copyright (c) 2018 Bryce Guinta <bryce.guinta@protonmail.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Fureigh <rhys.fureigh@gsa.gov> +# Copyright (c) 2018 Pierre Sassoulas <pierre.sassoulas@wisebim.fr> +# Copyright (c) 2018 Andreas Freimuth <andreas.freimuth@united-bits.de> +# Copyright (c) 2018 Jakub Wilk <jwilk@jwilk.net> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Python code format's checker. + +By default try to follow Guido's style guide : + +https://www.python.org/doc/essays/styleguide/ + +Some parts of the process_token method is based from The Tab Nanny std module. +""" + +import keyword +import sys +import tokenize +from functools import reduce # pylint: disable=redefined-builtin + +from astroid import nodes + +from pylint.interfaces import ITokenChecker, IAstroidChecker, IRawChecker +from pylint.checkers import BaseTokenChecker +from pylint.checkers.utils import check_messages +from pylint.utils import WarningScope, OPTION_RGX + +_ASYNC_TOKEN = "async" +_CONTINUATION_BLOCK_OPENERS = [ + "elif", + "except", + "for", + "if", + "while", + "def", + "class", + "with", +] +_KEYWORD_TOKENS = [ + "assert", + "del", + "elif", + "except", + "for", + "if", + "in", + "not", + "raise", + "return", + "while", + "yield", + "with", +] +if sys.version_info < (3, 0): + _KEYWORD_TOKENS.append("print") + +_SPACED_OPERATORS = [ + "==", + "<", + ">", + "!=", + "<>", + "<=", + ">=", + "+=", + "-=", + "*=", + "**=", + "/=", + "//=", + "&=", + "|=", + "^=", + "%=", + ">>=", + "<<=", +] +_OPENING_BRACKETS = ["(", "[", "{"] +_CLOSING_BRACKETS = [")", "]", "}"] +_TAB_LENGTH = 8 + +_EOL = frozenset([tokenize.NEWLINE, tokenize.NL, tokenize.COMMENT]) +_JUNK_TOKENS = (tokenize.COMMENT, tokenize.NL) + +# Whitespace checking policy constants +_MUST = 0 +_MUST_NOT = 1 +_IGNORE = 2 + +# Whitespace checking config constants +_DICT_SEPARATOR = "dict-separator" +_TRAILING_COMMA = "trailing-comma" +_EMPTY_LINE = "empty-line" +_NO_SPACE_CHECK_CHOICES = [_TRAILING_COMMA, _DICT_SEPARATOR, _EMPTY_LINE] +_DEFAULT_NO_SPACE_CHECK_CHOICES = [_TRAILING_COMMA, _DICT_SEPARATOR] + +MSGS = { + "C0301": ( + "Line too long (%s/%s)", + "line-too-long", + "Used when a line is longer than a given number of characters.", + ), + "C0302": ( + "Too many lines in module (%s/%s)", # was W0302 + "too-many-lines", + "Used when a module has too many lines, reducing its readability.", + ), + "C0303": ( + "Trailing whitespace", + "trailing-whitespace", + "Used when there is whitespace between the end of a line and the newline.", + ), + "C0304": ( + "Final newline missing", + "missing-final-newline", + "Used when the last line in a file is missing a newline.", + ), + "C0305": ( + "Trailing newlines", + "trailing-newlines", + "Used when there are trailing blank lines in a file.", + ), + "W0311": ( + "Bad indentation. Found %s %s, expected %s", + "bad-indentation", + "Used when an unexpected number of indentation's tabulations or " + "spaces has been found.", + ), + "C0330": ("Wrong %s indentation%s%s.\n%s%s", "bad-continuation", "TODO"), + "W0312": ( + "Found indentation with %ss instead of %ss", + "mixed-indentation", + "Used when there are some mixed tabs and spaces in a module.", + ), + "W0301": ( + "Unnecessary semicolon", # was W0106 + "unnecessary-semicolon", + 'Used when a statement is ended by a semi-colon (";"), which ' + "isn't necessary (that's python, not C ;).", + ), + "C0321": ( + "More than one statement on a single line", + "multiple-statements", + "Used when more than on statement are found on the same line.", + {"scope": WarningScope.NODE}, + ), + "C0325": ( + "Unnecessary parens after %r keyword", + "superfluous-parens", + "Used when a single item in parentheses follows an if, for, or " + "other keyword.", + ), + "C0326": ( + "%s space %s %s %s\n%s", + "bad-whitespace", + ( + "Used when a wrong number of spaces is used around an operator, " + "bracket or block opener." + ), + { + "old_names": [ + ("C0323", "no-space-after-operator"), + ("C0324", "no-space-after-comma"), + ("C0322", "no-space-before-operator"), + ] + }, + ), + "C0327": ( + "Mixed line endings LF and CRLF", + "mixed-line-endings", + "Used when there are mixed (LF and CRLF) newline signs in a file.", + ), + "C0328": ( + "Unexpected line ending format. There is '%s' while it should be '%s'.", + "unexpected-line-ending-format", + "Used when there is different newline than expected.", + ), +} + + +def _underline_token(token): + length = token[3][1] - token[2][1] + offset = token[2][1] + referenced_line = token[4] + # If the referenced line does not end with a newline char, fix it + if referenced_line[-1] != "\n": + referenced_line += "\n" + return referenced_line + (" " * offset) + ("^" * length) + + +def _column_distance(token1, token2): + if token1 == token2: + return 0 + if token2[3] < token1[3]: + token1, token2 = token2, token1 + if token1[3][0] != token2[2][0]: + return None + return token2[2][1] - token1[3][1] + + +def _last_token_on_line_is(tokens, line_end, token): + return ( + line_end > 0 + and tokens.token(line_end - 1) == token + or line_end > 1 + and tokens.token(line_end - 2) == token + and tokens.type(line_end - 1) == tokenize.COMMENT + ) + + +def _token_followed_by_eol(tokens, position): + return ( + tokens.type(position + 1) == tokenize.NL + or tokens.type(position + 1) == tokenize.COMMENT + and tokens.type(position + 2) == tokenize.NL + ) + + +def _get_indent_string(line): + """Return the indention string of the given line.""" + result = "" + for char in line: + if char in " \t": + result += char + else: + break + return result + + +def _get_indent_length(line): + """Return the length of the indentation on the given token's line.""" + result = 0 + for char in line: + if char == " ": + result += 1 + elif char == "\t": + result += _TAB_LENGTH + else: + break + return result + + +def _get_indent_hint_line(bar_positions, bad_position): + """Return a line with |s for each of the positions in the given lists.""" + if not bar_positions: + return ("", "") + # TODO tabs should not be replaced by some random (8) number of spaces + bar_positions = [_get_indent_length(indent) for indent in bar_positions] + bad_position = _get_indent_length(bad_position) + delta_message = "" + markers = [(pos, "|") for pos in bar_positions] + if len(markers) == 1: + # if we have only one marker we'll provide an extra hint on how to fix + expected_position = markers[0][0] + delta = abs(expected_position - bad_position) + direction = "add" if expected_position > bad_position else "remove" + delta_message = _CONTINUATION_HINT_MESSAGE % ( + direction, + delta, + "s" if delta > 1 else "", + ) + markers.append((bad_position, "^")) + markers.sort() + line = [" "] * (markers[-1][0] + 1) + for position, marker in markers: + line[position] = marker + return ("".join(line), delta_message) + + +class _ContinuedIndent: + __slots__ = ( + "valid_outdent_strings", + "valid_continuation_strings", + "context_type", + "token", + "position", + ) + + def __init__( + self, + context_type, + token, + position, + valid_outdent_strings, + valid_continuation_strings, + ): + self.valid_outdent_strings = valid_outdent_strings + self.valid_continuation_strings = valid_continuation_strings + self.context_type = context_type + self.position = position + self.token = token + + +# The contexts for hanging indents. +# A hanging indented dictionary value after : +HANGING_DICT_VALUE = "dict-value" +# Hanging indentation in an expression. +HANGING = "hanging" +# Hanging indentation in a block header. +HANGING_BLOCK = "hanging-block" +# Continued indentation inside an expression. +CONTINUED = "continued" +# Continued indentation in a block header. +CONTINUED_BLOCK = "continued-block" + +SINGLE_LINE = "single" +WITH_BODY = "multi" + +_CONTINUATION_MSG_PARTS = { + HANGING_DICT_VALUE: ("hanging", " in dict value"), + HANGING: ("hanging", ""), + HANGING_BLOCK: ("hanging", " before block"), + CONTINUED: ("continued", ""), + CONTINUED_BLOCK: ("continued", " before block"), +} + +_CONTINUATION_HINT_MESSAGE = " (%s %d space%s)" # Ex: (remove 2 spaces) + + +def _Indentations(*args): + """Valid indentation strings for a continued line.""" + return {a: None for a in args} + + +def _BeforeBlockIndentations(single, with_body): + """Valid alternative indentation strings for continued lines before blocks. + + :param int single: Valid indentation string for statements on a single logical line. + :param int with_body: Valid indentation string for statements on several lines. + + :returns: A dictionary mapping indent offsets to a string representing + whether the indent if for a line or block. + :rtype: dict + """ + return {single: SINGLE_LINE, with_body: WITH_BODY} + + +class TokenWrapper: + """A wrapper for readable access to token information.""" + + def __init__(self, tokens): + self._tokens = tokens + + def token(self, idx): + return self._tokens[idx][1] + + def type(self, idx): + return self._tokens[idx][0] + + def start_line(self, idx): + return self._tokens[idx][2][0] + + def start_col(self, idx): + return self._tokens[idx][2][1] + + def line(self, idx): + return self._tokens[idx][4] + + def line_indent(self, idx): + """Get the string of TABs and Spaces used for indentation of the line of this token""" + return _get_indent_string(self.line(idx)) + + def token_indent(self, idx): + """Get an indentation string for hanging indentation, consisting of the line-indent plus + a number of spaces to fill up to the column of this token. + + e.g. the token indent for foo + in "<TAB><TAB>print(foo)" + is "<TAB><TAB> " + """ + line_indent = self.line_indent(idx) + return line_indent + " " * (self.start_col(idx) - len(line_indent)) + + +class ContinuedLineState: + """Tracker for continued indentation inside a logical line.""" + + def __init__(self, tokens, config): + self._line_start = -1 + self._cont_stack = [] + self._is_block_opener = False + self.retained_warnings = [] + self._config = config + self._tokens = TokenWrapper(tokens) + + @property + def has_content(self): + return bool(self._cont_stack) + + @property + def _block_indent_string(self): + return self._config.indent_string.replace("\\t", "\t") + + @property + def _continuation_string(self): + return self._block_indent_string[0] * self._config.indent_after_paren + + @property + def _continuation_size(self): + return self._config.indent_after_paren + + def handle_line_start(self, pos): + """Record the first non-junk token at the start of a line.""" + if self._line_start > -1: + return + + check_token_position = pos + if self._tokens.token(pos) == _ASYNC_TOKEN: + check_token_position += 1 + self._is_block_opener = ( + self._tokens.token(check_token_position) in _CONTINUATION_BLOCK_OPENERS + ) + self._line_start = pos + + def next_physical_line(self): + """Prepares the tracker for a new physical line (NL).""" + self._line_start = -1 + self._is_block_opener = False + + def next_logical_line(self): + """Prepares the tracker for a new logical line (NEWLINE). + + A new logical line only starts with block indentation. + """ + self.next_physical_line() + self.retained_warnings = [] + self._cont_stack = [] + + def add_block_warning(self, token_position, state, valid_indentations): + self.retained_warnings.append((token_position, state, valid_indentations)) + + def get_valid_indentations(self, idx): + """Returns the valid offsets for the token at the given position.""" + # The closing brace on a dict or the 'for' in a dict comprehension may + # reset two indent levels because the dict value is ended implicitly + stack_top = -1 + if ( + self._tokens.token(idx) in ("}", "for") + and self._cont_stack[-1].token == ":" + ): + stack_top = -2 + indent = self._cont_stack[stack_top] + if self._tokens.token(idx) in _CLOSING_BRACKETS: + valid_indentations = indent.valid_outdent_strings + else: + valid_indentations = indent.valid_continuation_strings + return indent, valid_indentations.copy() + + def _hanging_indent_after_bracket(self, bracket, position): + """Extracts indentation information for a hanging indent + + Case of hanging indent after a bracket (including parenthesis) + + :param str bracket: bracket in question + :param int position: Position of bracket in self._tokens + + :returns: the state and valid positions for hanging indentation + :rtype: _ContinuedIndent + """ + indentation = self._tokens.line_indent(position) + if ( + self._is_block_opener + and self._continuation_string == self._block_indent_string + ): + return _ContinuedIndent( + HANGING_BLOCK, + bracket, + position, + _Indentations(indentation + self._continuation_string, indentation), + _BeforeBlockIndentations( + indentation + self._continuation_string, + indentation + self._continuation_string * 2, + ), + ) + if bracket == ":": + # If the dict key was on the same line as the open brace, the new + # correct indent should be relative to the key instead of the + # current indent level + paren_align = self._cont_stack[-1].valid_outdent_strings + next_align = self._cont_stack[-1].valid_continuation_strings.copy() + next_align_keys = list(next_align.keys()) + next_align[next_align_keys[0] + self._continuation_string] = True + # Note that the continuation of + # d = { + # 'a': 'b' + # 'c' + # } + # is handled by the special-casing for hanging continued string indents. + return _ContinuedIndent( + HANGING_DICT_VALUE, bracket, position, paren_align, next_align + ) + return _ContinuedIndent( + HANGING, + bracket, + position, + _Indentations(indentation, indentation + self._continuation_string), + _Indentations(indentation + self._continuation_string), + ) + + def _continuation_inside_bracket(self, bracket, position): + """Extracts indentation information for a continued indent.""" + indentation = self._tokens.line_indent(position) + token_indent = self._tokens.token_indent(position) + next_token_indent = self._tokens.token_indent(position + 1) + if ( + self._is_block_opener + and next_token_indent == indentation + self._block_indent_string + ): + return _ContinuedIndent( + CONTINUED_BLOCK, + bracket, + position, + _Indentations(token_indent), + _BeforeBlockIndentations( + next_token_indent, next_token_indent + self._continuation_string + ), + ) + return _ContinuedIndent( + CONTINUED, + bracket, + position, + _Indentations(token_indent, next_token_indent), + _Indentations(next_token_indent), + ) + + def pop_token(self): + self._cont_stack.pop() + + def push_token(self, token, position): + """Pushes a new token for continued indentation on the stack. + + Tokens that can modify continued indentation offsets are: + * opening brackets + * 'lambda' + * : inside dictionaries + + push_token relies on the caller to filter out those + interesting tokens. + + :param int token: The concrete token + :param int position: The position of the token in the stream. + """ + if _token_followed_by_eol(self._tokens, position): + self._cont_stack.append(self._hanging_indent_after_bracket(token, position)) + else: + self._cont_stack.append(self._continuation_inside_bracket(token, position)) + + +class FormatChecker(BaseTokenChecker): + """checks for : + * unauthorized constructions + * strict indentation + * line length + """ + + __implements__ = (ITokenChecker, IAstroidChecker, IRawChecker) + + # configuration section name + name = "format" + # messages + msgs = MSGS + # configuration options + # for available dict keys/values see the optik parser 'add_option' method + options = ( + ( + "max-line-length", + { + "default": 100, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of characters on a single line.", + }, + ), + ( + "ignore-long-lines", + { + "type": "regexp", + "metavar": "<regexp>", + "default": r"^\s*(# )?<?https?://\S+>?$", + "help": ( + "Regexp for a line that is allowed to be longer than " "the limit." + ), + }, + ), + ( + "single-line-if-stmt", + { + "default": False, + "type": "yn", + "metavar": "<y_or_n>", + "help": ( + "Allow the body of an if to be on the same " + "line as the test if there is no else." + ), + }, + ), + ( + "single-line-class-stmt", + { + "default": False, + "type": "yn", + "metavar": "<y_or_n>", + "help": ( + "Allow the body of a class to be on the same " + "line as the declaration if body contains " + "single statement." + ), + }, + ), + ( + "no-space-check", + { + "default": ",".join(_DEFAULT_NO_SPACE_CHECK_CHOICES), + "metavar": ",".join(_NO_SPACE_CHECK_CHOICES), + "type": "multiple_choice", + "choices": _NO_SPACE_CHECK_CHOICES, + "help": ( + "List of optional constructs for which whitespace " + "checking is disabled. " + "`" + _DICT_SEPARATOR + "` is used to allow tabulation " + "in dicts, etc.: {1 : 1,\\n222: 2}. " + "`" + _TRAILING_COMMA + "` allows a space between comma " + "and closing bracket: (a, ). " + "`" + _EMPTY_LINE + "` allows space-only lines." + ), + }, + ), + ( + "max-module-lines", + { + "default": 1000, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of lines in a module.", + }, + ), + ( + "indent-string", + { + "default": " ", + "type": "non_empty_string", + "metavar": "<string>", + "help": "String used as indentation unit. This is usually " + '" " (4 spaces) or "\\t" (1 tab).', + }, + ), + ( + "indent-after-paren", + { + "type": "int", + "metavar": "<int>", + "default": 4, + "help": "Number of spaces of indent required inside a hanging " + "or continued line.", + }, + ), + ( + "expected-line-ending-format", + { + "type": "choice", + "metavar": "<empty or LF or CRLF>", + "default": "", + "choices": ["", "LF", "CRLF"], + "help": ( + "Expected format of line ending, " + "e.g. empty (any line ending), LF or CRLF." + ), + }, + ), + ) + + def __init__(self, linter=None): + BaseTokenChecker.__init__(self, linter) + self._lines = None + self._visited_lines = None + self._bracket_stack = [None] + + def _pop_token(self): + self._bracket_stack.pop() + self._current_line.pop_token() + + def _push_token(self, token, idx): + self._bracket_stack.append(token) + self._current_line.push_token(token, idx) + + def new_line(self, tokens, line_end, line_start): + """a new line has been encountered, process it if necessary""" + if _last_token_on_line_is(tokens, line_end, ";"): + self.add_message("unnecessary-semicolon", line=tokens.start_line(line_end)) + + line_num = tokens.start_line(line_start) + line = tokens.line(line_start) + if tokens.type(line_start) not in _JUNK_TOKENS: + self._lines[line_num] = line.split("\n")[0] + self.check_lines(line, line_num) + + def process_module(self, module): + self._keywords_with_parens = set() + if "print_function" in module.future_imports: + self._keywords_with_parens.add("print") + + def _check_keyword_parentheses(self, tokens, start): + """Check that there are not unnecessary parens after a keyword. + + Parens are unnecessary if there is exactly one balanced outer pair on a + line, and it is followed by a colon, and contains no commas (i.e. is not a + tuple). + + Args: + tokens: list of Tokens; the entire list of Tokens. + start: int; the position of the keyword in the token list. + """ + # If the next token is not a paren, we're fine. + if self._inside_brackets(":") and tokens[start][1] == "for": + self._pop_token() + if tokens[start + 1][1] != "(": + return + + found_and_or = False + depth = 0 + keyword_token = str(tokens[start][1]) + line_num = tokens[start][2][0] + + for i in range(start, len(tokens) - 1): + token = tokens[i] + + # If we hit a newline, then assume any parens were for continuation. + if token[0] == tokenize.NL: + return + + if token[1] == "(": + depth += 1 + elif token[1] == ")": + depth -= 1 + if depth: + continue + # ')' can't happen after if (foo), since it would be a syntax error. + if tokens[i + 1][1] in (":", ")", "]", "}", "in") or tokens[i + 1][ + 0 + ] in (tokenize.NEWLINE, tokenize.ENDMARKER, tokenize.COMMENT): + # The empty tuple () is always accepted. + if i == start + 2: + return + if keyword_token == "not": + if not found_and_or: + self.add_message( + "superfluous-parens", line=line_num, args=keyword_token + ) + elif keyword_token in ("return", "yield"): + self.add_message( + "superfluous-parens", line=line_num, args=keyword_token + ) + elif keyword_token not in self._keywords_with_parens: + if not found_and_or: + self.add_message( + "superfluous-parens", line=line_num, args=keyword_token + ) + return + elif depth == 1: + # This is a tuple, which is always acceptable. + if token[1] == ",": + return + # 'and' and 'or' are the only boolean operators with lower precedence + # than 'not', so parens are only required when they are found. + if token[1] in ("and", "or"): + found_and_or = True + # A yield inside an expression must always be in parentheses, + # quit early without error. + elif token[1] == "yield": + return + # A generator expression always has a 'for' token in it, and + # the 'for' token is only legal inside parens when it is in a + # generator expression. The parens are necessary here, so bail + # without an error. + elif token[1] == "for": + return + + def _opening_bracket(self, tokens, i): + self._push_token(tokens[i][1], i) + # Special case: ignore slices + if tokens[i][1] == "[" and tokens[i + 1][1] == ":": + return + + if i > 0 and ( + tokens[i - 1][0] == tokenize.NAME + and not (keyword.iskeyword(tokens[i - 1][1])) + or tokens[i - 1][1] in _CLOSING_BRACKETS + ): + self._check_space(tokens, i, (_MUST_NOT, _MUST_NOT)) + else: + self._check_space(tokens, i, (_IGNORE, _MUST_NOT)) + + def _closing_bracket(self, tokens, i): + if self._inside_brackets(":"): + self._pop_token() + self._pop_token() + # Special case: ignore slices + if tokens[i - 1][1] == ":" and tokens[i][1] == "]": + return + policy_before = _MUST_NOT + if tokens[i][1] in _CLOSING_BRACKETS and tokens[i - 1][1] == ",": + if _TRAILING_COMMA in self.config.no_space_check: + policy_before = _IGNORE + + self._check_space(tokens, i, (policy_before, _IGNORE)) + + def _has_valid_type_annotation(self, tokens, i): + """Extended check of PEP-484 type hint presence""" + if not self._inside_brackets("("): + return False + # token_info + # type string start end line + # 0 1 2 3 4 + bracket_level = 0 + for token in tokens[i - 1 :: -1]: + if token[1] == ":": + return True + if token[1] == "(": + return False + if token[1] == "]": + bracket_level += 1 + elif token[1] == "[": + bracket_level -= 1 + elif token[1] == ",": + if not bracket_level: + return False + elif token[1] in (".", "..."): + continue + elif token[0] not in (tokenize.NAME, tokenize.STRING, tokenize.NL): + return False + return False + + def _check_equals_spacing(self, tokens, i): + """Check the spacing of a single equals sign.""" + if self._has_valid_type_annotation(tokens, i): + self._check_space(tokens, i, (_MUST, _MUST)) + elif self._inside_brackets("(") or self._inside_brackets("lambda"): + self._check_space(tokens, i, (_MUST_NOT, _MUST_NOT)) + else: + self._check_space(tokens, i, (_MUST, _MUST)) + + def _open_lambda(self, tokens, i): # pylint:disable=unused-argument + self._push_token("lambda", i) + + def _handle_colon(self, tokens, i): + # Special case: ignore slices + if self._inside_brackets("["): + return + if self._inside_brackets("{") and _DICT_SEPARATOR in self.config.no_space_check: + policy = (_IGNORE, _IGNORE) + else: + policy = (_MUST_NOT, _MUST) + self._check_space(tokens, i, policy) + + if self._inside_brackets("lambda"): + self._pop_token() + elif self._inside_brackets("{"): + self._push_token(":", i) + + def _handle_comma(self, tokens, i): + # Only require a following whitespace if this is + # not a hanging comma before a closing bracket. + if tokens[i + 1][1] in _CLOSING_BRACKETS: + self._check_space(tokens, i, (_MUST_NOT, _IGNORE)) + else: + self._check_space(tokens, i, (_MUST_NOT, _MUST)) + if self._inside_brackets(":"): + self._pop_token() + + def _check_surrounded_by_space(self, tokens, i): + """Check that a binary operator is surrounded by exactly one space.""" + self._check_space(tokens, i, (_MUST, _MUST)) + + def _check_space(self, tokens, i, policies): + def _policy_string(policy): + if policy == _MUST: + return "Exactly one", "required" + return "No", "allowed" + + def _name_construct(token): + if token[1] == ",": + return "comma" + if token[1] == ":": + return ":" + if token[1] in "()[]{}": + return "bracket" + if token[1] in ("<", ">", "<=", ">=", "!=", "=="): + return "comparison" + if self._inside_brackets("("): + return "keyword argument assignment" + return "assignment" + + good_space = [True, True] + token = tokens[i] + pairs = [(tokens[i - 1], token), (token, tokens[i + 1])] + + for other_idx, (policy, token_pair) in enumerate(zip(policies, pairs)): + if token_pair[other_idx][0] in _EOL or policy == _IGNORE: + continue + + distance = _column_distance(*token_pair) + if distance is None: + continue + good_space[other_idx] = (policy == _MUST and distance == 1) or ( + policy == _MUST_NOT and distance == 0 + ) + + warnings = [] + if not any(good_space) and policies[0] == policies[1]: + warnings.append((policies[0], "around")) + else: + for ok, policy, position in zip(good_space, policies, ("before", "after")): + if not ok: + warnings.append((policy, position)) + for policy, position in warnings: + construct = _name_construct(token) + count, state = _policy_string(policy) + self.add_message( + "bad-whitespace", + line=token[2][0], + args=(count, state, position, construct, _underline_token(token)), + col_offset=token[2][1], + ) + + def _inside_brackets(self, left): + return self._bracket_stack[-1] == left + + def _prepare_token_dispatcher(self): + raw = [ + (_KEYWORD_TOKENS, self._check_keyword_parentheses), + (_OPENING_BRACKETS, self._opening_bracket), + (_CLOSING_BRACKETS, self._closing_bracket), + (["="], self._check_equals_spacing), + (_SPACED_OPERATORS, self._check_surrounded_by_space), + ([","], self._handle_comma), + ([":"], self._handle_colon), + (["lambda"], self._open_lambda), + ] + + dispatch = {} + for tokens, handler in raw: + for token in tokens: + dispatch[token] = handler + return dispatch + + def process_tokens(self, tokens): + """process tokens and search for : + + _ non strict indentation (i.e. not always using the <indent> parameter as + indent unit) + _ too long lines (i.e. longer than <max_chars>) + _ optionally bad construct (if given, bad_construct must be a compiled + regular expression). + """ + self._bracket_stack = [None] + indents = [0] + check_equal = False + line_num = 0 + self._lines = {} + self._visited_lines = {} + token_handlers = self._prepare_token_dispatcher() + self._last_line_ending = None + last_blank_line_num = 0 + + self._current_line = ContinuedLineState(tokens, self.config) + for idx, (tok_type, token, start, _, line) in enumerate(tokens): + if start[0] != line_num: + line_num = start[0] + # A tokenizer oddity: if an indented line contains a multi-line + # docstring, the line member of the INDENT token does not contain + # the full line; therefore we check the next token on the line. + if tok_type == tokenize.INDENT: + self.new_line(TokenWrapper(tokens), idx - 1, idx + 1) + else: + self.new_line(TokenWrapper(tokens), idx - 1, idx) + + if tok_type == tokenize.NEWLINE: + # a program statement, or ENDMARKER, will eventually follow, + # after some (possibly empty) run of tokens of the form + # (NL | COMMENT)* (INDENT | DEDENT+)? + # If an INDENT appears, setting check_equal is wrong, and will + # be undone when we see the INDENT. + check_equal = True + self._process_retained_warnings(TokenWrapper(tokens), idx) + self._current_line.next_logical_line() + self._check_line_ending(token, line_num) + elif tok_type == tokenize.INDENT: + check_equal = False + self.check_indent_level(token, indents[-1] + 1, line_num) + indents.append(indents[-1] + 1) + elif tok_type == tokenize.DEDENT: + # there's nothing we need to check here! what's important is + # that when the run of DEDENTs ends, the indentation of the + # program statement (or ENDMARKER) that triggered the run is + # equal to what's left at the top of the indents stack + check_equal = True + if len(indents) > 1: + del indents[-1] + elif tok_type == tokenize.NL: + if not line.strip("\r\n"): + last_blank_line_num = line_num + self._check_continued_indentation(TokenWrapper(tokens), idx + 1) + self._current_line.next_physical_line() + elif tok_type not in (tokenize.COMMENT, tokenize.ENCODING): + self._current_line.handle_line_start(idx) + # This is the first concrete token following a NEWLINE, so it + # must be the first token of the next program statement, or an + # ENDMARKER; the "line" argument exposes the leading whitespace + # for this statement; in the case of ENDMARKER, line is an empty + # string, so will properly match the empty string with which the + # "indents" stack was seeded + if check_equal: + check_equal = False + self.check_indent_level(line, indents[-1], line_num) + + if tok_type == tokenize.NUMBER and token.endswith("l"): + self.add_message("lowercase-l-suffix", line=line_num) + + try: + handler = token_handlers[token] + except KeyError: + pass + else: + handler(tokens, idx) + + line_num -= 1 # to be ok with "wc -l" + if line_num > self.config.max_module_lines: + # Get the line where the too-many-lines (or its message id) + # was disabled or default to 1. + symbol = self.linter.msgs_store.get_message_definition("too-many-lines") + names = (symbol.msgid, "too-many-lines") + line = next(filter(None, map(self.linter._pragma_lineno.get, names)), 1) + self.add_message( + "too-many-lines", + args=(line_num, self.config.max_module_lines), + line=line, + ) + + # See if there are any trailing lines. Do not complain about empty + # files like __init__.py markers. + if line_num == last_blank_line_num and line_num > 0: + self.add_message("trailing-newlines", line=line_num) + + def _check_line_ending(self, line_ending, line_num): + # check if line endings are mixed + if self._last_line_ending is not None: + # line_ending == "" indicates a synthetic newline added at + # the end of a file that does not, in fact, end with a + # newline. + if line_ending and line_ending != self._last_line_ending: + self.add_message("mixed-line-endings", line=line_num) + + self._last_line_ending = line_ending + + # check if line ending is as expected + expected = self.config.expected_line_ending_format + if expected: + # reduce multiple \n\n\n\n to one \n + line_ending = reduce(lambda x, y: x + y if x != y else x, line_ending, "") + line_ending = "LF" if line_ending == "\n" else "CRLF" + if line_ending != expected: + self.add_message( + "unexpected-line-ending-format", + args=(line_ending, expected), + line=line_num, + ) + + def _process_retained_warnings(self, tokens, current_pos): + single_line_block_stmt = not _last_token_on_line_is(tokens, current_pos, ":") + + for indent_pos, state, indentations in self._current_line.retained_warnings: + block_type = indentations[tokens.token_indent(indent_pos)] + hints = {k: v for k, v in indentations.items() if v != block_type} + if single_line_block_stmt and block_type == WITH_BODY: + self._add_continuation_message(state, hints, tokens, indent_pos) + elif not single_line_block_stmt and block_type == SINGLE_LINE: + self._add_continuation_message(state, hints, tokens, indent_pos) + + def _check_continued_indentation(self, tokens, next_idx): + def same_token_around_nl(token_type): + return ( + tokens.type(next_idx) == token_type + and tokens.type(next_idx - 2) == token_type + ) + + # Do not issue any warnings if the next line is empty. + if not self._current_line.has_content or tokens.type(next_idx) == tokenize.NL: + return + + state, valid_indentations = self._current_line.get_valid_indentations(next_idx) + # Special handling for hanging comments and strings. If the last line ended + # with a comment (string) and the new line contains only a comment, the line + # may also be indented to the start of the previous token. + if same_token_around_nl(tokenize.COMMENT) or same_token_around_nl( + tokenize.STRING + ): + valid_indentations[tokens.token_indent(next_idx - 2)] = True + + # We can only decide if the indentation of a continued line before opening + # a new block is valid once we know of the body of the block is on the + # same line as the block opener. Since the token processing is single-pass, + # emitting those warnings is delayed until the block opener is processed. + if ( + state.context_type in (HANGING_BLOCK, CONTINUED_BLOCK) + and tokens.token_indent(next_idx) in valid_indentations + ): + self._current_line.add_block_warning(next_idx, state, valid_indentations) + elif tokens.token_indent(next_idx) not in valid_indentations: + length_indentation = len(tokens.token_indent(next_idx)) + if not any( + length_indentation == 2 * len(indentation) + for indentation in valid_indentations + ): + self._add_continuation_message( + state, valid_indentations, tokens, next_idx + ) + + def _add_continuation_message(self, state, indentations, tokens, position): + readable_type, readable_position = _CONTINUATION_MSG_PARTS[state.context_type] + hint_line, delta_message = _get_indent_hint_line( + indentations, tokens.token_indent(position) + ) + self.add_message( + "bad-continuation", + line=tokens.start_line(position), + args=( + readable_type, + readable_position, + delta_message, + tokens.line(position), + hint_line, + ), + ) + + @check_messages("multiple-statements") + def visit_default(self, node): + """check the node line number and check it if not yet done""" + if not node.is_statement: + return + if not node.root().pure_python: + return # XXX block visit of child nodes + prev_sibl = node.previous_sibling() + if prev_sibl is not None: + prev_line = prev_sibl.fromlineno + else: + # The line on which a finally: occurs in a try/finally + # is not directly represented in the AST. We infer it + # by taking the last line of the body and adding 1, which + # should be the line of finally: + if ( + isinstance(node.parent, nodes.TryFinally) + and node in node.parent.finalbody + ): + prev_line = node.parent.body[0].tolineno + 1 + else: + prev_line = node.parent.statement().fromlineno + line = node.fromlineno + assert line, node + if prev_line == line and self._visited_lines.get(line) != 2: + self._check_multi_statement_line(node, line) + return + if line in self._visited_lines: + return + try: + tolineno = node.blockstart_tolineno + except AttributeError: + tolineno = node.tolineno + assert tolineno, node + lines = [] + for line in range(line, tolineno + 1): + self._visited_lines[line] = 1 + try: + lines.append(self._lines[line].rstrip()) + except KeyError: + lines.append("") + + def _check_multi_statement_line(self, node, line): + """Check for lines containing multiple statements.""" + # Do not warn about multiple nested context managers + # in with statements. + if isinstance(node, nodes.With): + return + # For try... except... finally..., the two nodes + # appear to be on the same line due to how the AST is built. + if isinstance(node, nodes.TryExcept) and isinstance( + node.parent, nodes.TryFinally + ): + return + if ( + isinstance(node.parent, nodes.If) + and not node.parent.orelse + and self.config.single_line_if_stmt + ): + return + if ( + isinstance(node.parent, nodes.ClassDef) + and len(node.parent.body) == 1 + and self.config.single_line_class_stmt + ): + return + self.add_message("multiple-statements", node=node) + self._visited_lines[line] = 2 + + def check_lines(self, lines, i): + """check lines have less than a maximum number of characters + """ + max_chars = self.config.max_line_length + ignore_long_line = self.config.ignore_long_lines + + def check_line(line, i): + if not line.endswith("\n"): + self.add_message("missing-final-newline", line=i) + else: + # exclude \f (formfeed) from the rstrip + stripped_line = line.rstrip("\t\n\r\v ") + if not stripped_line and _EMPTY_LINE in self.config.no_space_check: + # allow empty lines + pass + elif line[len(stripped_line) :] not in ("\n", "\r\n"): + self.add_message( + "trailing-whitespace", line=i, col_offset=len(stripped_line) + ) + # Don't count excess whitespace in the line length. + line = stripped_line + mobj = OPTION_RGX.search(line) + if mobj and "=" in line: + front_of_equal, _, back_of_equal = mobj.group(1).partition("=") + if front_of_equal.strip() == "disable": + if "line-too-long" in { + _msg_id.strip() for _msg_id in back_of_equal.split(",") + }: + return None + line = line.rsplit("#", 1)[0].rstrip() + + if len(line) > max_chars and not ignore_long_line.search(line): + self.add_message("line-too-long", line=i, args=(len(line), max_chars)) + return i + 1 + + unsplit_ends = { + "\v", + "\x0b", + "\f", + "\x0c", + "\x1c", + "\x1d", + "\x1e", + "\x85", + "\u2028", + "\u2029", + } + unsplit = [] + for line in lines.splitlines(True): + if line[-1] in unsplit_ends: + unsplit.append(line) + continue + + if unsplit: + unsplit.append(line) + line = "".join(unsplit) + unsplit = [] + + i = check_line(line, i) + if i is None: + break + + if unsplit: + check_line("".join(unsplit), i) + + def check_indent_level(self, string, expected, line_num): + """return the indent level of the string + """ + indent = self.config.indent_string + if indent == "\\t": # \t is not interpreted in the configuration file + indent = "\t" + level = 0 + unit_size = len(indent) + while string[:unit_size] == indent: + string = string[unit_size:] + level += 1 + suppl = "" + while string and string[0] in " \t": + if string[0] != indent[0]: + if string[0] == "\t": + args = ("tab", "space") + else: + args = ("space", "tab") + self.add_message("mixed-indentation", args=args, line=line_num) + return level + suppl += string[0] + string = string[1:] + if level != expected or suppl: + i_type = "spaces" + if indent[0] == "\t": + i_type = "tabs" + self.add_message( + "bad-indentation", + line=line_num, + args=(level * unit_size + len(suppl), i_type, expected * unit_size), + ) + return None + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(FormatChecker(linter)) + + +def funkier(): + for val in range(3): + pass + print(val) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/imports.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/imports.py new file mode 100644 index 0000000..07ae01f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/imports.py @@ -0,0 +1,934 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2013 buck@yelp.com <buck@yelp.com> +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Cezar <celnazli@bitdefender.com> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Noam Yorav-Raphael <noamraph@gmail.com> +# Copyright (c) 2015 James Morgensen <james.morgensen@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Jared Garst <cultofjared@gmail.com> +# Copyright (c) 2016 Maik Röder <maikroeder@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Michka Popoff <michkapopoff@gmail.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Erik Wright <erik.wright@shopify.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Marianna Polatoglou <mpolatoglou@bloomberg.net> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""imports checkers for Python code""" + +import collections +from distutils import sysconfig +import os +import sys +import copy + +import astroid +from astroid import are_exclusive, decorators +from astroid.modutils import get_module_part, is_standard_module +import isort + +from pylint.interfaces import IAstroidChecker +from pylint.utils import get_global_option +from pylint.exceptions import EmptyReportError +from pylint.checkers import BaseChecker +from pylint.checkers.utils import ( + check_messages, + node_ignores_exception, + is_from_fallback_block, +) +from pylint.graph import get_cycles, DotBackend +from pylint.reporters.ureports.nodes import VerbatimText, Paragraph + + +def _qualified_names(modname): + """Split the names of the given module into subparts + + For example, + _qualified_names('pylint.checkers.ImportsChecker') + returns + ['pylint', 'pylint.checkers', 'pylint.checkers.ImportsChecker'] + """ + names = modname.split(".") + return [".".join(names[0 : i + 1]) for i in range(len(names))] + + +def _get_import_name(importnode, modname): + """Get a prepared module name from the given import node + + In the case of relative imports, this will return the + absolute qualified module name, which might be useful + for debugging. Otherwise, the initial module name + is returned unchanged. + """ + if isinstance(importnode, astroid.ImportFrom): + if importnode.level: + root = importnode.root() + if isinstance(root, astroid.Module): + modname = root.relative_to_absolute_name( + modname, level=importnode.level + ) + return modname + + +def _get_first_import(node, context, name, base, level, alias): + """return the node where [base.]<name> is imported or None if not found + """ + fullname = "%s.%s" % (base, name) if base else name + + first = None + found = False + for first in context.body: + if first is node: + continue + if first.scope() is node.scope() and first.fromlineno > node.fromlineno: + continue + if isinstance(first, astroid.Import): + if any(fullname == iname[0] for iname in first.names): + found = True + break + elif isinstance(first, astroid.ImportFrom): + if level == first.level: + for imported_name, imported_alias in first.names: + if fullname == "%s.%s" % (first.modname, imported_name): + found = True + break + if ( + name != "*" + and name == imported_name + and not (alias or imported_alias) + ): + found = True + break + if found: + break + if found and not are_exclusive(first, node): + return first + return None + + +def _ignore_import_failure(node, modname, ignored_modules): + for submodule in _qualified_names(modname): + if submodule in ignored_modules: + return True + + return node_ignores_exception(node, ImportError) + + +# utilities to represents import dependencies as tree and dot graph ########### + + +def _make_tree_defs(mod_files_list): + """get a list of 2-uple (module, list_of_files_which_import_this_module), + it will return a dictionary to represent this as a tree + """ + tree_defs = {} + for mod, files in mod_files_list: + node = (tree_defs, ()) + for prefix in mod.split("."): + node = node[0].setdefault(prefix, [{}, []]) + node[1] += files + return tree_defs + + +def _repr_tree_defs(data, indent_str=None): + """return a string which represents imports as a tree""" + lines = [] + nodes = data.items() + for i, (mod, (sub, files)) in enumerate(sorted(nodes, key=lambda x: x[0])): + if not files: + files = "" + else: + files = "(%s)" % ",".join(sorted(files)) + if indent_str is None: + lines.append("%s %s" % (mod, files)) + sub_indent_str = " " + else: + lines.append(r"%s\-%s %s" % (indent_str, mod, files)) + if i == len(nodes) - 1: + sub_indent_str = "%s " % indent_str + else: + sub_indent_str = "%s| " % indent_str + if sub: + lines.append(_repr_tree_defs(sub, sub_indent_str)) + return "\n".join(lines) + + +def _dependencies_graph(filename, dep_info): + """write dependencies as a dot (graphviz) file + """ + done = {} + printer = DotBackend(filename[:-4], rankdir="LR") + printer.emit('URL="." node[shape="box"]') + for modname, dependencies in sorted(dep_info.items()): + done[modname] = 1 + printer.emit_node(modname) + for depmodname in dependencies: + if depmodname not in done: + done[depmodname] = 1 + printer.emit_node(depmodname) + for depmodname, dependencies in sorted(dep_info.items()): + for modname in dependencies: + printer.emit_edge(modname, depmodname) + printer.generate(filename) + + +def _make_graph(filename, dep_info, sect, gtype): + """generate a dependencies graph and add some information about it in the + report's section + """ + _dependencies_graph(filename, dep_info) + sect.append(Paragraph("%simports graph has been written to %s" % (gtype, filename))) + + +# the import checker itself ################################################### + +MSGS = { + "E0401": ( + "Unable to import %s", + "import-error", + "Used when pylint has been unable to import a module.", + {"old_names": [("F0401", "import-error")]}, + ), + "E0402": ( + "Attempted relative import beyond top-level package", + "relative-beyond-top-level", + "Used when a relative import tries to access too many levels " + "in the current package.", + ), + "R0401": ( + "Cyclic import (%s)", + "cyclic-import", + "Used when a cyclic import between two or more modules is detected.", + ), + "W0401": ( + "Wildcard import %s", + "wildcard-import", + "Used when `from module import *` is detected.", + ), + "W0402": ( + "Uses of a deprecated module %r", + "deprecated-module", + "Used a module marked as deprecated is imported.", + ), + "W0403": ( + "Relative import %r, should be %r", + "relative-import", + "Used when an import relative to the package directory is detected.", + {"maxversion": (3, 0)}, + ), + "W0404": ( + "Reimport %r (imported line %s)", + "reimported", + "Used when a module is reimported multiple times.", + ), + "W0406": ( + "Module import itself", + "import-self", + "Used when a module is importing itself.", + ), + "W0410": ( + "__future__ import is not the first non docstring statement", + "misplaced-future", + "Python 2.5 and greater require __future__ import to be the " + "first non docstring statement in the module.", + ), + "C0410": ( + "Multiple imports on one line (%s)", + "multiple-imports", + "Used when import statement importing multiple modules is detected.", + ), + "C0411": ( + "%s should be placed before %s", + "wrong-import-order", + "Used when PEP8 import order is not respected (standard imports " + "first, then third-party libraries, then local imports)", + ), + "C0412": ( + "Imports from package %s are not grouped", + "ungrouped-imports", + "Used when imports are not grouped by packages", + ), + "C0413": ( + 'Import "%s" should be placed at the top of the module', + "wrong-import-position", + "Used when code and imports are mixed", + ), + "C0414": ( + "Import alias does not rename original package", + "useless-import-alias", + "Used when an import alias is same as original package." + "e.g using import numpy as numpy instead of import numpy as np", + ), +} + + +DEFAULT_STANDARD_LIBRARY = () +DEFAULT_KNOWN_THIRD_PARTY = ("enchant",) + + +class ImportsChecker(BaseChecker): + """checks for + * external modules dependencies + * relative / wildcard imports + * cyclic imports + * uses of deprecated modules + """ + + __implements__ = IAstroidChecker + + name = "imports" + msgs = MSGS + priority = -2 + + if sys.version_info < (3, 5): + deprecated_modules = ("optparse",) + else: + deprecated_modules = ("optparse", "tkinter.tix") + options = ( + ( + "deprecated-modules", + { + "default": deprecated_modules, + "type": "csv", + "metavar": "<modules>", + "help": "Deprecated modules which should not be used," + " separated by a comma.", + }, + ), + ( + "import-graph", + { + "default": "", + "type": "string", + "metavar": "<file.dot>", + "help": "Create a graph of every (i.e. internal and" + " external) dependencies in the given file" + " (report RP0402 must not be disabled).", + }, + ), + ( + "ext-import-graph", + { + "default": "", + "type": "string", + "metavar": "<file.dot>", + "help": "Create a graph of external dependencies in the" + " given file (report RP0402 must not be disabled).", + }, + ), + ( + "int-import-graph", + { + "default": "", + "type": "string", + "metavar": "<file.dot>", + "help": "Create a graph of internal dependencies in the" + " given file (report RP0402 must not be disabled).", + }, + ), + ( + "known-standard-library", + { + "default": DEFAULT_STANDARD_LIBRARY, + "type": "csv", + "metavar": "<modules>", + "help": "Force import order to recognize a module as part of " + "the standard compatibility libraries.", + }, + ), + ( + "known-third-party", + { + "default": DEFAULT_KNOWN_THIRD_PARTY, + "type": "csv", + "metavar": "<modules>", + "help": "Force import order to recognize a module as part of " + "a third party library.", + }, + ), + ( + "analyse-fallback-blocks", + { + "default": False, + "type": "yn", + "metavar": "<y_or_n>", + "help": "Analyse import fallback blocks. This can be used to " + "support both Python 2 and 3 compatible code, which " + "means that the block might have code that exists " + "only in one or another interpreter, leading to false " + "positives when analysed.", + }, + ), + ( + "allow-wildcard-with-all", + { + "default": False, + "type": "yn", + "metavar": "<y_or_n>", + "help": "Allow wildcard imports from modules that define __all__.", + }, + ), + ) + + def __init__(self, linter=None): + BaseChecker.__init__(self, linter) + self.stats = None + self.import_graph = None + self._imports_stack = [] + self._first_non_import_node = None + self._module_pkg = {} # mapping of modules to the pkg they belong in + self.reports = ( + ("RP0401", "External dependencies", self._report_external_dependencies), + ("RP0402", "Modules dependencies graph", self._report_dependencies_graph), + ) + + self._site_packages = self._compute_site_packages() + + @staticmethod + def _compute_site_packages(): + def _normalized_path(path): + return os.path.normcase(os.path.abspath(path)) + + paths = set() + real_prefix = getattr(sys, "real_prefix", None) + for prefix in filter(None, (real_prefix, sys.prefix)): + path = sysconfig.get_python_lib(prefix=prefix) + path = _normalized_path(path) + paths.add(path) + + # Handle Debian's derivatives /usr/local. + if os.path.isfile("/etc/debian_version"): + for prefix in filter(None, (real_prefix, sys.prefix)): + libpython = os.path.join( + prefix, + "local", + "lib", + "python" + sysconfig.get_python_version(), + "dist-packages", + ) + paths.add(libpython) + return paths + + def open(self): + """called before visiting project (i.e set of modules)""" + self.linter.add_stats(dependencies={}) + self.linter.add_stats(cycles=[]) + self.stats = self.linter.stats + self.import_graph = collections.defaultdict(set) + self._module_pkg = {} # mapping of modules to the pkg they belong in + self._excluded_edges = collections.defaultdict(set) + self._ignored_modules = get_global_option(self, "ignored-modules", default=[]) + + def _import_graph_without_ignored_edges(self): + filtered_graph = copy.deepcopy(self.import_graph) + for node in filtered_graph: + filtered_graph[node].difference_update(self._excluded_edges[node]) + return filtered_graph + + def close(self): + """called before visiting project (i.e set of modules)""" + if self.linter.is_message_enabled("cyclic-import"): + graph = self._import_graph_without_ignored_edges() + vertices = list(graph) + for cycle in get_cycles(graph, vertices=vertices): + self.add_message("cyclic-import", args=" -> ".join(cycle)) + + @check_messages(*MSGS) + def visit_import(self, node): + """triggered when an import statement is seen""" + self._check_reimport(node) + self._check_import_as_rename(node) + + modnode = node.root() + names = [name for name, _ in node.names] + if len(names) >= 2: + self.add_message("multiple-imports", args=", ".join(names), node=node) + + for name in names: + self._check_deprecated_module(node, name) + imported_module = self._get_imported_module(node, name) + if isinstance(node.parent, astroid.Module): + # Allow imports nested + self._check_position(node) + if isinstance(node.scope(), astroid.Module): + self._record_import(node, imported_module) + + if imported_module is None: + continue + + self._check_relative_import(modnode, node, imported_module, name) + self._add_imported_module(node, imported_module.name) + + @check_messages(*MSGS) + def visit_importfrom(self, node): + """triggered when a from statement is seen""" + basename = node.modname + imported_module = self._get_imported_module(node, basename) + + self._check_import_as_rename(node) + self._check_misplaced_future(node) + self._check_deprecated_module(node, basename) + self._check_wildcard_imports(node, imported_module) + self._check_same_line_imports(node) + self._check_reimport(node, basename=basename, level=node.level) + + if isinstance(node.parent, astroid.Module): + # Allow imports nested + self._check_position(node) + if isinstance(node.scope(), astroid.Module): + self._record_import(node, imported_module) + if imported_module is None: + return + modnode = node.root() + self._check_relative_import(modnode, node, imported_module, basename) + + for name, _ in node.names: + if name != "*": + self._add_imported_module(node, "%s.%s" % (imported_module.name, name)) + else: + self._add_imported_module(node, imported_module.name) + + @check_messages(*MSGS) + def leave_module(self, node): + # Check imports are grouped by category (standard, 3rd party, local) + std_imports, ext_imports, loc_imports = self._check_imports_order(node) + + # Check imports are grouped by package within a given category + met = set() + current_package = None + for import_node, import_name in std_imports + ext_imports + loc_imports: + if not self.linter.is_message_enabled( + "ungrouped-imports", import_node.fromlineno + ): + continue + package, _, _ = import_name.partition(".") + if current_package and current_package != package and package in met: + self.add_message("ungrouped-imports", node=import_node, args=package) + current_package = package + met.add(package) + + self._imports_stack = [] + self._first_non_import_node = None + + def compute_first_non_import_node(self, node): + if not self.linter.is_message_enabled("wrong-import-position", node.fromlineno): + return + # if the node does not contain an import instruction, and if it is the + # first node of the module, keep a track of it (all the import positions + # of the module will be compared to the position of this first + # instruction) + if self._first_non_import_node: + return + if not isinstance(node.parent, astroid.Module): + return + nested_allowed = [astroid.TryExcept, astroid.TryFinally] + is_nested_allowed = [ + allowed for allowed in nested_allowed if isinstance(node, allowed) + ] + if is_nested_allowed and any( + node.nodes_of_class((astroid.Import, astroid.ImportFrom)) + ): + return + if isinstance(node, astroid.Assign): + # Add compatibility for module level dunder names + # https://www.python.org/dev/peps/pep-0008/#module-level-dunder-names + valid_targets = [ + isinstance(target, astroid.AssignName) + and target.name.startswith("__") + and target.name.endswith("__") + for target in node.targets + ] + if all(valid_targets): + return + self._first_non_import_node = node + + visit_tryfinally = ( + visit_tryexcept + ) = ( + visit_assignattr + ) = ( + visit_assign + ) = ( + visit_ifexp + ) = visit_comprehension = visit_expr = visit_if = compute_first_non_import_node + + def visit_functiondef(self, node): + if not self.linter.is_message_enabled("wrong-import-position", node.fromlineno): + return + # If it is the first non import instruction of the module, record it. + if self._first_non_import_node: + return + + # Check if the node belongs to an `If` or a `Try` block. If they + # contain imports, skip recording this node. + if not isinstance(node.parent.scope(), astroid.Module): + return + + root = node + while not isinstance(root.parent, astroid.Module): + root = root.parent + + if isinstance(root, (astroid.If, astroid.TryFinally, astroid.TryExcept)): + if any(root.nodes_of_class((astroid.Import, astroid.ImportFrom))): + return + + self._first_non_import_node = node + + visit_classdef = visit_for = visit_while = visit_functiondef + + def _check_misplaced_future(self, node): + basename = node.modname + if basename == "__future__": + # check if this is the first non-docstring statement in the module + prev = node.previous_sibling() + if prev: + # consecutive future statements are possible + if not ( + isinstance(prev, astroid.ImportFrom) + and prev.modname == "__future__" + ): + self.add_message("misplaced-future", node=node) + return + + def _check_same_line_imports(self, node): + # Detect duplicate imports on the same line. + names = (name for name, _ in node.names) + counter = collections.Counter(names) + for name, count in counter.items(): + if count > 1: + self.add_message("reimported", node=node, args=(name, node.fromlineno)) + + def _check_position(self, node): + """Check `node` import or importfrom node position is correct + + Send a message if `node` comes before another instruction + """ + # if a first non-import instruction has already been encountered, + # it means the import comes after it and therefore is not well placed + if self._first_non_import_node: + self.add_message("wrong-import-position", node=node, args=node.as_string()) + + def _record_import(self, node, importedmodnode): + """Record the package `node` imports from""" + if isinstance(node, astroid.ImportFrom): + importedname = node.modname + else: + importedname = importedmodnode.name if importedmodnode else None + if not importedname: + importedname = node.names[0][0].split(".")[0] + + if isinstance(node, astroid.ImportFrom) and (node.level or 0) >= 1: + # We need the importedname with first point to detect local package + # Example of node: + # 'from .my_package1 import MyClass1' + # the output should be '.my_package1' instead of 'my_package1' + # Example of node: + # 'from . import my_package2' + # the output should be '.my_package2' instead of '{pyfile}' + importedname = "." + importedname + + self._imports_stack.append((node, importedname)) + + @staticmethod + def _is_fallback_import(node, imports): + imports = [import_node for (import_node, _) in imports] + return any(astroid.are_exclusive(import_node, node) for import_node in imports) + + def _check_imports_order(self, _module_node): + """Checks imports of module `node` are grouped by category + + Imports must follow this order: standard, 3rd party, local + """ + std_imports = [] + third_party_imports = [] + first_party_imports = [] + # need of a list that holds third or first party ordered import + external_imports = [] + local_imports = [] + third_party_not_ignored = [] + first_party_not_ignored = [] + local_not_ignored = [] + isort_obj = isort.SortImports( + file_contents="", + known_third_party=self.config.known_third_party, + known_standard_library=self.config.known_standard_library, + ) + for node, modname in self._imports_stack: + if modname.startswith("."): + package = "." + modname.split(".")[1] + else: + package = modname.split(".")[0] + nested = not isinstance(node.parent, astroid.Module) + ignore_for_import_order = not self.linter.is_message_enabled( + "wrong-import-order", node.fromlineno + ) + import_category = isort_obj.place_module(package) + node_and_package_import = (node, package) + if import_category in ("FUTURE", "STDLIB"): + std_imports.append(node_and_package_import) + wrong_import = ( + third_party_not_ignored + or first_party_not_ignored + or local_not_ignored + ) + if self._is_fallback_import(node, wrong_import): + continue + if wrong_import and not nested: + self.add_message( + "wrong-import-order", + node=node, + args=( + 'standard import "%s"' % node.as_string(), + '"%s"' % wrong_import[0][0].as_string(), + ), + ) + elif import_category == "THIRDPARTY": + third_party_imports.append(node_and_package_import) + external_imports.append(node_and_package_import) + if not nested and not ignore_for_import_order: + third_party_not_ignored.append(node_and_package_import) + wrong_import = first_party_not_ignored or local_not_ignored + if wrong_import and not nested: + self.add_message( + "wrong-import-order", + node=node, + args=( + 'third party import "%s"' % node.as_string(), + '"%s"' % wrong_import[0][0].as_string(), + ), + ) + elif import_category == "FIRSTPARTY": + first_party_imports.append(node_and_package_import) + external_imports.append(node_and_package_import) + if not nested and not ignore_for_import_order: + first_party_not_ignored.append(node_and_package_import) + wrong_import = local_not_ignored + if wrong_import and not nested: + self.add_message( + "wrong-import-order", + node=node, + args=( + 'first party import "%s"' % node.as_string(), + '"%s"' % wrong_import[0][0].as_string(), + ), + ) + elif import_category == "LOCALFOLDER": + local_imports.append((node, package)) + if not nested and not ignore_for_import_order: + local_not_ignored.append((node, package)) + return std_imports, external_imports, local_imports + + def _get_imported_module(self, importnode, modname): + try: + return importnode.do_import_module(modname) + except astroid.TooManyLevelsError: + if _ignore_import_failure(importnode, modname, self._ignored_modules): + return None + + self.add_message("relative-beyond-top-level", node=importnode) + except astroid.AstroidSyntaxError as exc: + message = "Cannot import {!r} due to syntax error {!r}".format( + modname, str(exc.error) # pylint: disable=no-member; false positive + ) + self.add_message("syntax-error", line=importnode.lineno, args=message) + + except astroid.AstroidBuildingException: + if not self.linter.is_message_enabled("import-error"): + return None + if _ignore_import_failure(importnode, modname, self._ignored_modules): + return None + if not self.config.analyse_fallback_blocks and is_from_fallback_block( + importnode + ): + return None + + dotted_modname = _get_import_name(importnode, modname) + self.add_message("import-error", args=repr(dotted_modname), node=importnode) + + def _check_relative_import( + self, modnode, importnode, importedmodnode, importedasname + ): + """check relative import. node is either an Import or From node, modname + the imported module name. + """ + if not self.linter.is_message_enabled("relative-import"): + return None + if importedmodnode.file is None: + return False # built-in module + if modnode is importedmodnode: + return False # module importing itself + if modnode.absolute_import_activated() or getattr(importnode, "level", None): + return False + if importedmodnode.name != importedasname: + # this must be a relative import... + self.add_message( + "relative-import", + args=(importedasname, importedmodnode.name), + node=importnode, + ) + return None + return None + + def _add_imported_module(self, node, importedmodname): + """notify an imported module, used to analyze dependencies""" + module_file = node.root().file + context_name = node.root().name + base = os.path.splitext(os.path.basename(module_file))[0] + + try: + importedmodname = get_module_part(importedmodname, module_file) + except ImportError: + pass + + if context_name == importedmodname: + self.add_message("import-self", node=node) + + elif not is_standard_module(importedmodname): + # if this is not a package __init__ module + if base != "__init__" and context_name not in self._module_pkg: + # record the module's parent, or the module itself if this is + # a top level module, as the package it belongs to + self._module_pkg[context_name] = context_name.rsplit(".", 1)[0] + + # handle dependencies + importedmodnames = self.stats["dependencies"].setdefault( + importedmodname, set() + ) + if context_name not in importedmodnames: + importedmodnames.add(context_name) + + # update import graph + self.import_graph[context_name].add(importedmodname) + if not self.linter.is_message_enabled("cyclic-import", line=node.lineno): + self._excluded_edges[context_name].add(importedmodname) + + def _check_deprecated_module(self, node, mod_path): + """check if the module is deprecated""" + for mod_name in self.config.deprecated_modules: + if mod_path == mod_name or mod_path.startswith(mod_name + "."): + self.add_message("deprecated-module", node=node, args=mod_path) + + def _check_import_as_rename(self, node): + names = node.names + for name in names: + if not all(name): + return + + real_name = name[0] + splitted_packages = real_name.rsplit(".") + real_name = splitted_packages[-1] + imported_name = name[1] + # consider only following cases + # import x as x + # and ignore following + # import x.y.z as z + if real_name == imported_name and len(splitted_packages) == 1: + self.add_message("useless-import-alias", node=node) + + def _check_reimport(self, node, basename=None, level=None): + """check if the import is necessary (i.e. not already done)""" + if not self.linter.is_message_enabled("reimported"): + return + + frame = node.frame() + root = node.root() + contexts = [(frame, level)] + if root is not frame: + contexts.append((root, None)) + + for known_context, known_level in contexts: + for name, alias in node.names: + first = _get_first_import( + node, known_context, name, basename, known_level, alias + ) + if first is not None: + self.add_message( + "reimported", node=node, args=(name, first.fromlineno) + ) + + def _report_external_dependencies(self, sect, _, _dummy): + """return a verbatim layout for displaying dependencies""" + dep_info = _make_tree_defs(self._external_dependencies_info().items()) + if not dep_info: + raise EmptyReportError() + tree_str = _repr_tree_defs(dep_info) + sect.append(VerbatimText(tree_str)) + + def _report_dependencies_graph(self, sect, _, _dummy): + """write dependencies as a dot (graphviz) file""" + dep_info = self.stats["dependencies"] + if not dep_info or not ( + self.config.import_graph + or self.config.ext_import_graph + or self.config.int_import_graph + ): + raise EmptyReportError() + filename = self.config.import_graph + if filename: + _make_graph(filename, dep_info, sect, "") + filename = self.config.ext_import_graph + if filename: + _make_graph(filename, self._external_dependencies_info(), sect, "external ") + filename = self.config.int_import_graph + if filename: + _make_graph(filename, self._internal_dependencies_info(), sect, "internal ") + + def _filter_dependencies_graph(self, internal): + """build the internal or the external depedency graph""" + graph = collections.defaultdict(set) + for importee, importers in self.stats["dependencies"].items(): + for importer in importers: + package = self._module_pkg.get(importer, importer) + is_inside = importee.startswith(package) + if is_inside and internal or not is_inside and not internal: + graph[importee].add(importer) + return graph + + @decorators.cached + def _external_dependencies_info(self): + """return cached external dependencies information or build and + cache them + """ + return self._filter_dependencies_graph(internal=False) + + @decorators.cached + def _internal_dependencies_info(self): + """return cached internal dependencies information or build and + cache them + """ + return self._filter_dependencies_graph(internal=True) + + def _check_wildcard_imports(self, node, imported_module): + if node.root().package: + # Skip the check if in __init__.py issue #2026 + return + + wildcard_import_is_allowed = self._wildcard_import_is_allowed(imported_module) + for name, _ in node.names: + if name == "*" and not wildcard_import_is_allowed: + self.add_message("wildcard-import", args=node.modname, node=node) + + def _wildcard_import_is_allowed(self, imported_module): + return ( + self.config.allow_wildcard_with_all + and imported_module is not None + and "__all__" in imported_module.locals + ) + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(ImportsChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/logging.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/logging.py new file mode 100644 index 0000000..442cf0e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/logging.py @@ -0,0 +1,371 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2009, 2012, 2014 Google, Inc. +# Copyright (c) 2012 Mike Bryant <leachim@leachim.info> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Chris Murray <chris@chrismurray.scot> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2017 guillaume2 <guillaume.peillex@gmail.col> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 Mariatta Wijaya <mariatta@python.org> +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""checker for use of Python logging +""" +import string + +import astroid + +from pylint import checkers +from pylint import interfaces +from pylint.checkers import utils +from pylint.checkers.utils import check_messages + + +MSGS = { + "W1201": ( + "Specify string format arguments as logging function parameters", + "logging-not-lazy", + "Used when a logging statement has a call form of " + '"logging.<logging method>(format_string % (format_args...))". ' + "Such calls should leave string interpolation to the logging " + "method itself and be written " + '"logging.<logging method>(format_string, format_args...)" ' + "so that the program may avoid incurring the cost of the " + "interpolation in those cases in which no message will be " + "logged. For more, see " + "http://www.python.org/dev/peps/pep-0282/.", + ), + "W1202": ( + "Use % formatting in logging functions and pass the % " + "parameters as arguments", + "logging-format-interpolation", + "Used when a logging statement has a call form of " + '"logging.<logging method>(format_string.format(format_args...))"' + ". Such calls should use % formatting instead, but leave " + "interpolation to the logging function by passing the parameters " + "as arguments.", + ), + "W1203": ( + "Use % formatting in logging functions and pass the % " + "parameters as arguments", + "logging-fstring-interpolation", + "Used when a logging statement has a call form of " + '"logging.method(f"..."))"' + ". Such calls should use % formatting instead, but leave " + "interpolation to the logging function by passing the parameters " + "as arguments.", + ), + "E1200": ( + "Unsupported logging format character %r (%#02x) at index %d", + "logging-unsupported-format", + "Used when an unsupported format character is used in a logging " + "statement format string.", + ), + "E1201": ( + "Logging format string ends in middle of conversion specifier", + "logging-format-truncated", + "Used when a logging statement format string terminates before " + "the end of a conversion specifier.", + ), + "E1205": ( + "Too many arguments for logging format string", + "logging-too-many-args", + "Used when a logging format string is given too many arguments.", + ), + "E1206": ( + "Not enough arguments for logging format string", + "logging-too-few-args", + "Used when a logging format string is given too few arguments.", + ), +} + + +CHECKED_CONVENIENCE_FUNCTIONS = { + "critical", + "debug", + "error", + "exception", + "fatal", + "info", + "warn", + "warning", +} + + +def is_method_call(func, types=(), methods=()): + """Determines if a BoundMethod node represents a method call. + + Args: + func (astroid.BoundMethod): The BoundMethod AST node to check. + types (Optional[String]): Optional sequence of caller type names to restrict check. + methods (Optional[String]): Optional sequence of method names to restrict check. + + Returns: + bool: true if the node represents a method call for the given type and + method names, False otherwise. + """ + return ( + isinstance(func, astroid.BoundMethod) + and isinstance(func.bound, astroid.Instance) + and (func.bound.name in types if types else True) + and (func.name in methods if methods else True) + ) + + +class LoggingChecker(checkers.BaseChecker): + """Checks use of the logging module.""" + + __implements__ = interfaces.IAstroidChecker + name = "logging" + msgs = MSGS + + options = ( + ( + "logging-modules", + { + "default": ("logging",), + "type": "csv", + "metavar": "<comma separated list>", + "help": "Logging modules to check that the string format " + "arguments are in logging function parameter format.", + }, + ), + ( + "logging-format-style", + { + "default": "old", + "type": "choice", + "metavar": "<old (%) or new ({)>", + "choices": ["old", "new"], + "help": "Format style used to check logging format string. " + "`old` means using % formatting, while `new` is for `{}` formatting.", + }, + ), + ) + + def visit_module(self, node): # pylint: disable=unused-argument + """Clears any state left in this checker from last module checked.""" + # The code being checked can just as easily "import logging as foo", + # so it is necessary to process the imports and store in this field + # what name the logging module is actually given. + self._logging_names = set() + logging_mods = self.config.logging_modules + + self._format_style = self.config.logging_format_style + self._logging_modules = set(logging_mods) + self._from_imports = {} + for logging_mod in logging_mods: + parts = logging_mod.rsplit(".", 1) + if len(parts) > 1: + self._from_imports[parts[0]] = parts[1] + + def visit_importfrom(self, node): + """Checks to see if a module uses a non-Python logging module.""" + try: + logging_name = self._from_imports[node.modname] + for module, as_name in node.names: + if module == logging_name: + self._logging_names.add(as_name or module) + except KeyError: + pass + + def visit_import(self, node): + """Checks to see if this module uses Python's built-in logging.""" + for module, as_name in node.names: + if module in self._logging_modules: + self._logging_names.add(as_name or module) + + @check_messages(*MSGS) + def visit_call(self, node): + """Checks calls to logging methods.""" + + def is_logging_name(): + return ( + isinstance(node.func, astroid.Attribute) + and isinstance(node.func.expr, astroid.Name) + and node.func.expr.name in self._logging_names + ) + + def is_logger_class(): + try: + for inferred in node.func.infer(): + if isinstance(inferred, astroid.BoundMethod): + parent = inferred._proxied.parent + if isinstance(parent, astroid.ClassDef) and ( + parent.qname() == "logging.Logger" + or any( + ancestor.qname() == "logging.Logger" + for ancestor in parent.ancestors() + ) + ): + return True, inferred._proxied.name + except astroid.exceptions.InferenceError: + pass + return False, None + + if is_logging_name(): + name = node.func.attrname + else: + result, name = is_logger_class() + if not result: + return + self._check_log_method(node, name) + + def _check_log_method(self, node, name): + """Checks calls to logging.log(level, format, *format_args).""" + if name == "log": + if node.starargs or node.kwargs or len(node.args) < 2: + # Either a malformed call, star args, or double-star args. Beyond + # the scope of this checker. + return + format_pos = 1 + elif name in CHECKED_CONVENIENCE_FUNCTIONS: + if node.starargs or node.kwargs or not node.args: + # Either no args, star args, or double-star args. Beyond the + # scope of this checker. + return + format_pos = 0 + else: + return + + if isinstance(node.args[format_pos], astroid.BinOp): + binop = node.args[format_pos] + emit = binop.op == "%" + if binop.op == "+": + total_number_of_strings = sum( + 1 + for operand in (binop.left, binop.right) + if self._is_operand_literal_str(utils.safe_infer(operand)) + ) + emit = total_number_of_strings > 0 + if emit: + self.add_message("logging-not-lazy", node=node) + elif isinstance(node.args[format_pos], astroid.Call): + self._check_call_func(node.args[format_pos]) + elif isinstance(node.args[format_pos], astroid.Const): + self._check_format_string(node, format_pos) + elif isinstance( + node.args[format_pos], (astroid.FormattedValue, astroid.JoinedStr) + ): + self.add_message("logging-fstring-interpolation", node=node) + + @staticmethod + def _is_operand_literal_str(operand): + """ + Return True if the operand in argument is a literal string + """ + return isinstance(operand, astroid.Const) and operand.name == "str" + + def _check_call_func(self, node): + """Checks that function call is not format_string.format(). + + Args: + node (astroid.node_classes.Call): + Call AST node to be checked. + """ + func = utils.safe_infer(node.func) + types = ("str", "unicode") + methods = ("format",) + if is_method_call(func, types, methods) and not is_complex_format_str( + func.bound + ): + self.add_message("logging-format-interpolation", node=node) + + def _check_format_string(self, node, format_arg): + """Checks that format string tokens match the supplied arguments. + + Args: + node (astroid.node_classes.NodeNG): AST node to be checked. + format_arg (int): Index of the format string in the node arguments. + """ + num_args = _count_supplied_tokens(node.args[format_arg + 1 :]) + if not num_args: + # If no args were supplied, then all format strings are valid - + # don't check any further. + return + format_string = node.args[format_arg].value + if not isinstance(format_string, str): + # If the log format is constant non-string (e.g. logging.debug(5)), + # ensure there are no arguments. + required_num_args = 0 + else: + try: + if self._format_style == "old": + keyword_args, required_num_args, _, _ = utils.parse_format_string( + format_string + ) + if keyword_args: + # Keyword checking on logging strings is complicated by + # special keywords - out of scope. + return + elif self._format_style == "new": + keys, num_args, manual_pos_arg = utils.parse_format_method_string( + format_string + ) + + kargs = len(set(k for k, l in keys if not isinstance(k, int))) + required_num_args = kargs + num_args + manual_pos_arg + except utils.UnsupportedFormatCharacter as ex: + char = format_string[ex.index] + self.add_message( + "logging-unsupported-format", + node=node, + args=(char, ord(char), ex.index), + ) + return + except utils.IncompleteFormatString: + self.add_message("logging-format-truncated", node=node) + return + if num_args > required_num_args: + self.add_message("logging-too-many-args", node=node) + elif num_args < required_num_args: + self.add_message("logging-too-few-args", node=node) + + +def is_complex_format_str(node): + """Checks if node represents a string with complex formatting specs. + + Args: + node (astroid.node_classes.NodeNG): AST node to check + Returns: + bool: True if inferred string uses complex formatting, False otherwise + """ + inferred = utils.safe_infer(node) + if inferred is None or not isinstance(inferred.value, str): + return True + try: + parsed = list(string.Formatter().parse(inferred.value)) + except ValueError: + # This format string is invalid + return False + for _, _, format_spec, _ in parsed: + if format_spec: + return True + return False + + +def _count_supplied_tokens(args): + """Counts the number of tokens in an args list. + + The Python log functions allow for special keyword arguments: func, + exc_info and extra. To handle these cases correctly, we only count + arguments that aren't keywords. + + Args: + args (list): AST nodes that are arguments for a log format string. + + Returns: + int: Number of AST nodes that aren't keywords. + """ + return sum(1 for arg in args if not isinstance(arg, astroid.Keyword)) + + +def register(linter): + """Required method to auto-register this checker.""" + linter.register_checker(LoggingChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/misc.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/misc.py new file mode 100644 index 0000000..b0f52ca --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/misc.py @@ -0,0 +1,194 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006, 2009-2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Alexandru Coman <fcoman@bitdefender.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 glegoux <gilles.legoux@gmail.com> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Mikhail Fesenko <proggga@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@iki.fi> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + + +"""Check source code is ascii only or has an encoding declaration (PEP 263)""" + +# pylint: disable=W0511 + +import re + +from pylint.interfaces import IRawChecker +from pylint.checkers import BaseChecker +from pylint.utils import OPTION_RGX, MessagesHandlerMixIn + + +class ByIdManagedMessagesChecker(BaseChecker): + + """checks for messages that are enabled or disabled by id instead of symbol.""" + + __implements__ = IRawChecker + + # configuration section name + name = "miscellaneous" + msgs = { + "I0023": ( + "%s", + "use-symbolic-message-instead", + "Used when a message is enabled or disabled by id.", + ) + } + + options = () + + def process_module(self, module): + """inspect the source file to find messages activated or deactivated by id.""" + managed_msgs = MessagesHandlerMixIn.get_by_id_managed_msgs() + for (mod_name, msg_id, msg_symbol, lineno, is_disabled) in managed_msgs: + if mod_name == module.name: + if is_disabled: + txt = "Id '{ident}' is used to disable '{symbol}' message emission".format( + ident=msg_id, symbol=msg_symbol + ) + else: + txt = "Id '{ident}' is used to enable '{symbol}' message emission".format( + ident=msg_id, symbol=msg_symbol + ) + self.add_message("use-symbolic-message-instead", line=lineno, args=txt) + MessagesHandlerMixIn.clear_by_id_managed_msgs() + + +class EncodingChecker(BaseChecker): + + """checks for: + * warning notes in the code like FIXME, XXX + * encoding issues. + """ + + __implements__ = IRawChecker + + # configuration section name + name = "miscellaneous" + msgs = { + "W0511": ( + "%s", + "fixme", + "Used when a warning note as FIXME or XXX is detected.", + ), + "W0512": ( + 'Cannot decode using encoding "%s", unexpected byte at position %d', + "invalid-encoded-data", + "Used when a source line cannot be decoded using the specified " + "source file encoding.", + {"maxversion": (3, 0)}, + ), + } + + options = ( + ( + "notes", + { + "type": "csv", + "metavar": "<comma separated values>", + "default": ("FIXME", "XXX", "TODO"), + "help": ( + "List of note tags to take in consideration, " + "separated by a comma." + ), + }, + ), + ) + + def _check_note(self, notes, lineno, line, module_last_lineno): + """ + Add the message 'fixme' in case a note is found in the line. + + :param notes: regular expression object matching any notes + (XXX, TODO, FIXME) behind a '#' + :type notes: re.pattern object + :param lineno: line number + :type lineno: int + :param line: line to be checked + :type line: str + :param module_last_lineno: last line number of the module as parsed by astroid + (may be different from real last line number in case + commented lines exist at the end of the module) + :type module_last_lineno: int + """ + match = notes.search(line) + if not match: + return + # In case the module ends with commented lines, the astroid parser + # don't take into account those lines, then: + # - the line number of those lines is greater than the + # module last line number (module.tolineno) + # - astroid module object can't inform pylint + # of disabled messages in those extra lines. + if lineno > module_last_lineno: + disable_option_match = OPTION_RGX.search(line) + if disable_option_match: + try: + _, value = disable_option_match.group(1).split("=", 1) + values = [_val.strip().upper() for _val in value.split(",")] + if set(values) & set(self.config.notes): + return + except ValueError: + self.add_message( + "bad-inline-option", + args=disable_option_match.group(1).strip(), + line=line, + ) + return + self.add_message( + "fixme", + args=line[match.start(1) :].rstrip(), + line=lineno, + col_offset=match.start(1), + ) + + def _check_encoding(self, lineno, line, file_encoding): + try: + return line.decode(file_encoding) + except UnicodeDecodeError as ex: + self.add_message( + "invalid-encoded-data", line=lineno, args=(file_encoding, ex.args[2]) + ) + except LookupError as ex: + if line.startswith("#") and "coding" in line and file_encoding in line: + self.add_message( + "syntax-error", + line=lineno, + args='Cannot decode using encoding "{}",' + " bad encoding".format(file_encoding), + ) + + def process_module(self, module): + """inspect the source file to find encoding problem or fixmes like + notes + """ + if self.config.notes: + notes = re.compile( + r"#\s*(%s)\b" % "|".join(map(re.escape, self.config.notes)), re.I + ) + else: + notes = None + if module.file_encoding: + encoding = module.file_encoding + else: + encoding = "ascii" + + with module.stream() as stream: + for lineno, line in enumerate(stream): + line = self._check_encoding(lineno + 1, line, encoding) + if line is not None and notes: + self._check_note(notes, lineno + 1, line, module.tolineno) + + +def register(linter): + """required method to auto register this checker""" + linter.register_checker(EncodingChecker(linter)) + linter.register_checker(ByIdManagedMessagesChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/newstyle.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/newstyle.py new file mode 100644 index 0000000..89d3165 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/newstyle.py @@ -0,0 +1,142 @@ +# Copyright (c) 2006, 2008-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2013-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""check for new / old style related problems +""" +import sys + +import astroid + +from pylint.interfaces import IAstroidChecker +from pylint.checkers import BaseChecker +from pylint.checkers.utils import check_messages, node_frame_class, has_known_bases + +MSGS = { + "E1003": ( + "Bad first argument %r given to super()", + "bad-super-call", + "Used when another argument than the current class is given as " + "first argument of the super builtin.", + ), + "E1004": ( + "Missing argument to super()", + "missing-super-argument", + "Used when the super builtin didn't receive an argument.", + {"maxversion": (3, 0)}, + ), +} + + +class NewStyleConflictChecker(BaseChecker): + """checks for usage of new style capabilities on old style classes and + other new/old styles conflicts problems + * use of property, __slots__, super + * "super" usage + """ + + __implements__ = (IAstroidChecker,) + + # configuration section name + name = "newstyle" + # messages + msgs = MSGS + priority = -2 + # configuration options + options = () + + @check_messages("bad-super-call", "missing-super-argument") + def visit_functiondef(self, node): + """check use of super""" + # ignore actual functions or method within a new style class + if not node.is_method(): + return + klass = node.parent.frame() + for stmt in node.nodes_of_class(astroid.Call): + if node_frame_class(stmt) != node_frame_class(node): + # Don't look down in other scopes. + continue + + expr = stmt.func + if not isinstance(expr, astroid.Attribute): + continue + + call = expr.expr + # skip the test if using super + if not ( + isinstance(call, astroid.Call) + and isinstance(call.func, astroid.Name) + and call.func.name == "super" + ): + continue + + if not klass.newstyle and has_known_bases(klass): + # super should not be used on an old style class + continue + else: + # super first arg should be the class + if not call.args: + if sys.version_info[0] == 3: + # unless Python 3 + continue + else: + self.add_message("missing-super-argument", node=call) + continue + + # calling super(type(self), self) can lead to recursion loop + # in derived classes + arg0 = call.args[0] + if ( + isinstance(arg0, astroid.Call) + and isinstance(arg0.func, astroid.Name) + and arg0.func.name == "type" + ): + self.add_message("bad-super-call", node=call, args=("type",)) + continue + + # calling super(self.__class__, self) can lead to recursion loop + # in derived classes + if ( + len(call.args) >= 2 + and isinstance(call.args[1], astroid.Name) + and call.args[1].name == "self" + and isinstance(arg0, astroid.Attribute) + and arg0.attrname == "__class__" + ): + self.add_message( + "bad-super-call", node=call, args=("self.__class__",) + ) + continue + + try: + supcls = call.args and next(call.args[0].infer(), None) + except astroid.InferenceError: + continue + + if klass is not supcls: + name = None + # if supcls is not Uninferable, then supcls was infered + # and use its name. Otherwise, try to look + # for call.args[0].name + if supcls: + name = supcls.name + elif call.args and hasattr(call.args[0], "name"): + name = call.args[0].name + if name: + self.add_message("bad-super-call", node=call, args=(name,)) + + visit_asyncfunctiondef = visit_functiondef + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(NewStyleConflictChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/python3.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/python3.py new file mode 100644 index 0000000..44ebf29 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/python3.py @@ -0,0 +1,1392 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014-2015 Brett Cannon <brett@python.org> +# Copyright (c) 2015 Simu Toni <simutoni@gmail.com> +# Copyright (c) 2015 Pavel Roskin <proski@gnu.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2015 Cosmin Poieana <cmin@ropython.org> +# Copyright (c) 2015 Viorel Stirbu <viorels@gmail.com> +# Copyright (c) 2016, 2018 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2016-2017 Roy Williams <roy.williams.iii@gmail.com> +# Copyright (c) 2016 Roy Williams <rwilliams@lyft.com> +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Erik <erik.eriksson@yahoo.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2017 Daniel Miller <millerdev@gmail.com> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 ahirnish <ahirnish@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Copyright (c) 2018 gaurikholkar <f2013002@goa.bits-pilani.ac.in> +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Check Python 2 code for Python 2/3 source-compatible issues.""" +from __future__ import absolute_import, print_function + +from collections import namedtuple +import re +import sys +import tokenize +from typing import FrozenSet + +import astroid +from astroid import bases + +from pylint import checkers, interfaces +from pylint.checkers.utils import node_ignores_exception, find_try_except_wrapper_node +from pylint.interfaces import INFERENCE_FAILURE, INFERENCE +from pylint.utils import WarningScope +from pylint.checkers import utils + + +_ZERO = re.compile("^0+$") + + +def _is_old_octal(literal): + if _ZERO.match(literal): + return False + if re.match(r"0\d+", literal): + try: + int(literal, 8) + except ValueError: + return False + return True + return None + + +def _inferred_value_is_dict(value): + if isinstance(value, astroid.Dict): + return True + return isinstance(value, astroid.Instance) and "dict" in value.basenames + + +def _is_builtin(node): + return getattr(node, "name", None) in ("__builtin__", "builtins") + + +_ACCEPTS_ITERATOR = { + "iter", + "list", + "tuple", + "sorted", + "set", + "sum", + "any", + "all", + "enumerate", + "dict", + "filter", + "reversed", + "max", + "min", + "frozenset", +} +ATTRIBUTES_ACCEPTS_ITERATOR = {"join", "from_iterable"} +_BUILTIN_METHOD_ACCEPTS_ITERATOR = { + "builtins.list.extend", + "builtins.dict.update", + "builtins.set.update", +} +DICT_METHODS = {"items", "keys", "values"} + + +def _in_iterating_context(node): + """Check if the node is being used as an iterator. + + Definition is taken from lib2to3.fixer_util.in_special_context(). + """ + parent = node.parent + # Since a call can't be the loop variant we only need to know if the node's + # parent is a 'for' loop to know it's being used as the iterator for the + # loop. + if isinstance(parent, astroid.For): + return True + # Need to make sure the use of the node is in the iterator part of the + # comprehension. + if isinstance(parent, astroid.Comprehension): + if parent.iter == node: + return True + # Various built-ins can take in an iterable or list and lead to the same + # value. + elif isinstance(parent, astroid.Call): + if isinstance(parent.func, astroid.Name): + parent_scope = parent.func.lookup(parent.func.name)[0] + if _is_builtin(parent_scope) and parent.func.name in _ACCEPTS_ITERATOR: + return True + elif isinstance(parent.func, astroid.Attribute): + if parent.func.attrname in ATTRIBUTES_ACCEPTS_ITERATOR: + return True + try: + inferred = next(parent.func.infer()) + except astroid.InferenceError: + pass + else: + if inferred is not astroid.Uninferable: + if inferred.qname() in _BUILTIN_METHOD_ACCEPTS_ITERATOR: + return True + # If the call is in an unpacking, there's no need to warn, + # since it can be considered iterating. + elif isinstance(parent, astroid.Assign) and isinstance( + parent.targets[0], (astroid.List, astroid.Tuple) + ): + if len(parent.targets[0].elts) > 1: + return True + # If the call is in a containment check, we consider that to + # be an iterating context + elif ( + isinstance(parent, astroid.Compare) + and len(parent.ops) == 1 + and parent.ops[0][0] == "in" + ): + return True + return False + + +def _is_conditional_import(node): + """Checks if an import node is in the context of a conditional. + """ + parent = node.parent + return isinstance( + parent, (astroid.TryExcept, astroid.ExceptHandler, astroid.If, astroid.IfExp) + ) + + +Branch = namedtuple("Branch", ["node", "is_py2_only"]) + + +class Python3Checker(checkers.BaseChecker): + + __implements__ = interfaces.IAstroidChecker + enabled = False + name = "python3" + + msgs = { + # Errors for what will syntactically break in Python 3, warnings for + # everything else. + "E1601": ( + "print statement used", + "print-statement", + "Used when a print statement is used " + "(`print` is a function in Python 3)", + ), + "E1602": ( + "Parameter unpacking specified", + "parameter-unpacking", + "Used when parameter unpacking is specified for a function" + "(Python 3 doesn't allow it)", + ), + "E1603": ( + "Implicit unpacking of exceptions is not supported in Python 3", + "unpacking-in-except", + "Python3 will not allow implicit unpacking of " + "exceptions in except clauses. " + "See http://www.python.org/dev/peps/pep-3110/", + {"old_names": [("W0712", "unpacking-in-except")]}, + ), + "E1604": ( + "Use raise ErrorClass(args) instead of raise ErrorClass, args.", + "old-raise-syntax", + "Used when the alternate raise syntax " + "'raise foo, bar' is used " + "instead of 'raise foo(bar)'.", + {"old_names": [("W0121", "old-raise-syntax")]}, + ), + "E1605": ( + "Use of the `` operator", + "backtick", + 'Used when the deprecated "``" (backtick) operator is used ' + "instead of the str() function.", + {"scope": WarningScope.NODE, "old_names": [("W0333", "backtick")]}, + ), + "E1609": ( + "Import * only allowed at module level", + "import-star-module-level", + "Used when the import star syntax is used somewhere " + "else than the module level.", + {"maxversion": (3, 0)}, + ), + "W1601": ( + "apply built-in referenced", + "apply-builtin", + "Used when the apply built-in function is referenced " + "(missing from Python 3)", + ), + "W1602": ( + "basestring built-in referenced", + "basestring-builtin", + "Used when the basestring built-in function is referenced " + "(missing from Python 3)", + ), + "W1603": ( + "buffer built-in referenced", + "buffer-builtin", + "Used when the buffer built-in function is referenced " + "(missing from Python 3)", + ), + "W1604": ( + "cmp built-in referenced", + "cmp-builtin", + "Used when the cmp built-in function is referenced " + "(missing from Python 3)", + ), + "W1605": ( + "coerce built-in referenced", + "coerce-builtin", + "Used when the coerce built-in function is referenced " + "(missing from Python 3)", + ), + "W1606": ( + "execfile built-in referenced", + "execfile-builtin", + "Used when the execfile built-in function is referenced " + "(missing from Python 3)", + ), + "W1607": ( + "file built-in referenced", + "file-builtin", + "Used when the file built-in function is referenced " + "(missing from Python 3)", + ), + "W1608": ( + "long built-in referenced", + "long-builtin", + "Used when the long built-in function is referenced " + "(missing from Python 3)", + ), + "W1609": ( + "raw_input built-in referenced", + "raw_input-builtin", + "Used when the raw_input built-in function is referenced " + "(missing from Python 3)", + ), + "W1610": ( + "reduce built-in referenced", + "reduce-builtin", + "Used when the reduce built-in function is referenced " + "(missing from Python 3)", + ), + "W1611": ( + "StandardError built-in referenced", + "standarderror-builtin", + "Used when the StandardError built-in function is referenced " + "(missing from Python 3)", + ), + "W1612": ( + "unicode built-in referenced", + "unicode-builtin", + "Used when the unicode built-in function is referenced " + "(missing from Python 3)", + ), + "W1613": ( + "xrange built-in referenced", + "xrange-builtin", + "Used when the xrange built-in function is referenced " + "(missing from Python 3)", + ), + "W1614": ( + "__coerce__ method defined", + "coerce-method", + "Used when a __coerce__ method is defined " + "(method is not used by Python 3)", + ), + "W1615": ( + "__delslice__ method defined", + "delslice-method", + "Used when a __delslice__ method is defined " + "(method is not used by Python 3)", + ), + "W1616": ( + "__getslice__ method defined", + "getslice-method", + "Used when a __getslice__ method is defined " + "(method is not used by Python 3)", + ), + "W1617": ( + "__setslice__ method defined", + "setslice-method", + "Used when a __setslice__ method is defined " + "(method is not used by Python 3)", + ), + "W1618": ( + "import missing `from __future__ import absolute_import`", + "no-absolute-import", + "Used when an import is not accompanied by " + "``from __future__ import absolute_import`` " + "(default behaviour in Python 3)", + ), + "W1619": ( + "division w/o __future__ statement", + "old-division", + "Used for non-floor division w/o a float literal or " + "``from __future__ import division`` " + "(Python 3 returns a float for int division unconditionally)", + ), + "W1620": ( + "Calling a dict.iter*() method", + "dict-iter-method", + "Used for calls to dict.iterkeys(), itervalues() or iteritems() " + "(Python 3 lacks these methods)", + ), + "W1621": ( + "Calling a dict.view*() method", + "dict-view-method", + "Used for calls to dict.viewkeys(), viewvalues() or viewitems() " + "(Python 3 lacks these methods)", + ), + "W1622": ( + "Called a next() method on an object", + "next-method-called", + "Used when an object's next() method is called " + "(Python 3 uses the next() built-in function)", + ), + "W1623": ( + "Assigning to a class's __metaclass__ attribute", + "metaclass-assignment", + "Used when a metaclass is specified by assigning to __metaclass__ " + "(Python 3 specifies the metaclass as a class statement argument)", + ), + "W1624": ( + "Indexing exceptions will not work on Python 3", + "indexing-exception", + "Indexing exceptions will not work on Python 3. Use " + "`exception.args[index]` instead.", + {"old_names": [("W0713", "indexing-exception")]}, + ), + "W1625": ( + "Raising a string exception", + "raising-string", + "Used when a string exception is raised. This will not " + "work on Python 3.", + {"old_names": [("W0701", "raising-string")]}, + ), + "W1626": ( + "reload built-in referenced", + "reload-builtin", + "Used when the reload built-in function is referenced " + "(missing from Python 3). You can use instead imp.reload " + "or importlib.reload.", + ), + "W1627": ( + "__oct__ method defined", + "oct-method", + "Used when an __oct__ method is defined " + "(method is not used by Python 3)", + ), + "W1628": ( + "__hex__ method defined", + "hex-method", + "Used when a __hex__ method is defined (method is not used by Python 3)", + ), + "W1629": ( + "__nonzero__ method defined", + "nonzero-method", + "Used when a __nonzero__ method is defined " + "(method is not used by Python 3)", + ), + "W1630": ( + "__cmp__ method defined", + "cmp-method", + "Used when a __cmp__ method is defined (method is not used by Python 3)", + ), + # 'W1631': replaced by W1636 + "W1632": ( + "input built-in referenced", + "input-builtin", + "Used when the input built-in is referenced " + "(backwards-incompatible semantics in Python 3)", + ), + "W1633": ( + "round built-in referenced", + "round-builtin", + "Used when the round built-in is referenced " + "(backwards-incompatible semantics in Python 3)", + ), + "W1634": ( + "intern built-in referenced", + "intern-builtin", + "Used when the intern built-in is referenced " + "(Moved to sys.intern in Python 3)", + ), + "W1635": ( + "unichr built-in referenced", + "unichr-builtin", + "Used when the unichr built-in is referenced (Use chr in Python 3)", + ), + "W1636": ( + "map built-in referenced when not iterating", + "map-builtin-not-iterating", + "Used when the map built-in is referenced in a non-iterating " + "context (returns an iterator in Python 3)", + {"old_names": [("W1631", "implicit-map-evaluation")]}, + ), + "W1637": ( + "zip built-in referenced when not iterating", + "zip-builtin-not-iterating", + "Used when the zip built-in is referenced in a non-iterating " + "context (returns an iterator in Python 3)", + ), + "W1638": ( + "range built-in referenced when not iterating", + "range-builtin-not-iterating", + "Used when the range built-in is referenced in a non-iterating " + "context (returns an iterator in Python 3)", + ), + "W1639": ( + "filter built-in referenced when not iterating", + "filter-builtin-not-iterating", + "Used when the filter built-in is referenced in a non-iterating " + "context (returns an iterator in Python 3)", + ), + "W1640": ( + "Using the cmp argument for list.sort / sorted", + "using-cmp-argument", + "Using the cmp argument for list.sort or the sorted " + "builtin should be avoided, since it was removed in " + "Python 3. Using either `key` or `functools.cmp_to_key` " + "should be preferred.", + ), + "W1641": ( + "Implementing __eq__ without also implementing __hash__", + "eq-without-hash", + "Used when a class implements __eq__ but not __hash__. In Python 2, objects " + "get object.__hash__ as the default implementation, in Python 3 objects get " + "None as their default __hash__ implementation if they also implement __eq__.", + ), + "W1642": ( + "__div__ method defined", + "div-method", + "Used when a __div__ method is defined. Using `__truediv__` and setting" + "__div__ = __truediv__ should be preferred." + "(method is not used by Python 3)", + ), + "W1643": ( + "__idiv__ method defined", + "idiv-method", + "Used when an __idiv__ method is defined. Using `__itruediv__` and setting" + "__idiv__ = __itruediv__ should be preferred." + "(method is not used by Python 3)", + ), + "W1644": ( + "__rdiv__ method defined", + "rdiv-method", + "Used when a __rdiv__ method is defined. Using `__rtruediv__` and setting" + "__rdiv__ = __rtruediv__ should be preferred." + "(method is not used by Python 3)", + ), + "W1645": ( + "Exception.message removed in Python 3", + "exception-message-attribute", + "Used when the message attribute is accessed on an Exception. Use " + "str(exception) instead.", + ), + "W1646": ( + "non-text encoding used in str.decode", + "invalid-str-codec", + "Used when using str.encode or str.decode with a non-text encoding. Use " + "codecs module to handle arbitrary codecs.", + ), + "W1647": ( + "sys.maxint removed in Python 3", + "sys-max-int", + "Used when accessing sys.maxint. Use sys.maxsize instead.", + ), + "W1648": ( + "Module moved in Python 3", + "bad-python3-import", + "Used when importing a module that no longer exists in Python 3.", + ), + "W1649": ( + "Accessing a deprecated function on the string module", + "deprecated-string-function", + "Used when accessing a string function that has been deprecated in Python 3.", + ), + "W1650": ( + "Using str.translate with deprecated deletechars parameters", + "deprecated-str-translate-call", + "Used when using the deprecated deletechars parameters from str.translate. Use " + "re.sub to remove the desired characters ", + ), + "W1651": ( + "Accessing a deprecated function on the itertools module", + "deprecated-itertools-function", + "Used when accessing a function on itertools that has been removed in Python 3.", + ), + "W1652": ( + "Accessing a deprecated fields on the types module", + "deprecated-types-field", + "Used when accessing a field on types that has been removed in Python 3.", + ), + "W1653": ( + "next method defined", + "next-method-defined", + "Used when a next method is defined that would be an iterator in Python 2 but " + "is treated as a normal function in Python 3.", + ), + "W1654": ( + "dict.items referenced when not iterating", + "dict-items-not-iterating", + "Used when dict.items is referenced in a non-iterating " + "context (returns an iterator in Python 3)", + ), + "W1655": ( + "dict.keys referenced when not iterating", + "dict-keys-not-iterating", + "Used when dict.keys is referenced in a non-iterating " + "context (returns an iterator in Python 3)", + ), + "W1656": ( + "dict.values referenced when not iterating", + "dict-values-not-iterating", + "Used when dict.values is referenced in a non-iterating " + "context (returns an iterator in Python 3)", + ), + "W1657": ( + "Accessing a removed attribute on the operator module", + "deprecated-operator-function", + "Used when accessing a field on operator module that has been " + "removed in Python 3.", + ), + "W1658": ( + "Accessing a removed attribute on the urllib module", + "deprecated-urllib-function", + "Used when accessing a field on urllib module that has been " + "removed or moved in Python 3.", + ), + "W1659": ( + "Accessing a removed xreadlines attribute", + "xreadlines-attribute", + "Used when accessing the xreadlines() function on a file stream, " + "removed in Python 3.", + ), + "W1660": ( + "Accessing a removed attribute on the sys module", + "deprecated-sys-function", + "Used when accessing a field on sys module that has been " + "removed in Python 3.", + ), + "W1661": ( + "Using an exception object that was bound by an except handler", + "exception-escape", + "Emitted when using an exception, that was bound in an except " + "handler, outside of the except handler. On Python 3 these " + "exceptions will be deleted once they get out " + "of the except handler.", + ), + "W1662": ( + "Using a variable that was bound inside a comprehension", + "comprehension-escape", + "Emitted when using a variable, that was bound in a comprehension " + "handler, outside of the comprehension itself. On Python 3 these " + "variables will be deleted outside of the " + "comprehension.", + ), + } + + _bad_builtins = frozenset( + [ + "apply", + "basestring", + "buffer", + "cmp", + "coerce", + "execfile", + "file", + "input", # Not missing, but incompatible semantics + "intern", + "long", + "raw_input", + "reduce", + "round", # Not missing, but incompatible semantics + "StandardError", + "unichr", + "unicode", + "xrange", + "reload", + ] + ) + + _unused_magic_methods = frozenset( + [ + "__coerce__", + "__delslice__", + "__getslice__", + "__setslice__", + "__oct__", + "__hex__", + "__nonzero__", + "__cmp__", + "__div__", + "__idiv__", + "__rdiv__", + ] + ) + + _invalid_encodings = frozenset( + [ + "base64_codec", + "base64", + "base_64", + "bz2_codec", + "bz2", + "hex_codec", + "hex", + "quopri_codec", + "quopri", + "quotedprintable", + "quoted_printable", + "uu_codec", + "uu", + "zlib_codec", + "zlib", + "zip", + "rot13", + "rot_13", + ] + ) + + _bad_python3_module_map = { + "sys-max-int": {"sys": frozenset(["maxint"])}, + "deprecated-itertools-function": { + "itertools": frozenset( + ["izip", "ifilter", "imap", "izip_longest", "ifilterfalse"] + ) + }, + "deprecated-types-field": { + "types": frozenset( + [ + "EllipsisType", + "XRangeType", + "ComplexType", + "StringType", + "TypeType", + "LongType", + "UnicodeType", + "ClassType", + "BufferType", + "StringTypes", + "NotImplementedType", + "NoneType", + "InstanceType", + "FloatType", + "SliceType", + "UnboundMethodType", + "ObjectType", + "IntType", + "TupleType", + "ListType", + "DictType", + "FileType", + "DictionaryType", + "BooleanType", + "DictProxyType", + ] + ) + }, + "bad-python3-import": frozenset( + [ + "anydbm", + "BaseHTTPServer", + "__builtin__", + "CGIHTTPServer", + "ConfigParser", + "copy_reg", + "cPickle", + "cStringIO", + "Cookie", + "cookielib", + "dbhash", + "dumbdbm", + "dumbdb", + "Dialog", + "DocXMLRPCServer", + "FileDialog", + "FixTk", + "gdbm", + "htmlentitydefs", + "HTMLParser", + "httplib", + "markupbase", + "Queue", + "repr", + "robotparser", + "ScrolledText", + "SimpleDialog", + "SimpleHTTPServer", + "SimpleXMLRPCServer", + "StringIO", + "dummy_thread", + "SocketServer", + "test.test_support", + "Tkinter", + "Tix", + "Tkconstants", + "tkColorChooser", + "tkCommonDialog", + "Tkdnd", + "tkFileDialog", + "tkFont", + "tkMessageBox", + "tkSimpleDialog", + "UserList", + "UserString", + "whichdb", + "_winreg", + "xmlrpclib", + "audiodev", + "Bastion", + "bsddb185", + "bsddb3", + "Canvas", + "cfmfile", + "cl", + "commands", + "compiler", + "dircache", + "dl", + "exception", + "fpformat", + "htmllib", + "ihooks", + "imageop", + "imputil", + "linuxaudiodev", + "md5", + "mhlib", + "mimetools", + "MimeWriter", + "mimify", + "multifile", + "mutex", + "new", + "popen2", + "posixfile", + "pure", + "rexec", + "rfc822", + "sets", + "sha", + "sgmllib", + "sre", + "stringold", + "sunaudio", + "sv", + "test.testall", + "thread", + "timing", + "toaiff", + "user", + "urllib2", + "urlparse", + ] + ), + "deprecated-string-function": { + "string": frozenset( + [ + "maketrans", + "atof", + "atoi", + "atol", + "capitalize", + "expandtabs", + "find", + "rfind", + "index", + "rindex", + "count", + "lower", + "letters", + "split", + "rsplit", + "splitfields", + "join", + "joinfields", + "lstrip", + "rstrip", + "strip", + "swapcase", + "translate", + "upper", + "ljust", + "rjust", + "center", + "zfill", + "replace", + "lowercase", + "letters", + "uppercase", + "atol_error", + "atof_error", + "atoi_error", + "index_error", + ] + ) + }, + "deprecated-operator-function": {"operator": frozenset({"div"})}, + "deprecated-urllib-function": { + "urllib": frozenset( + { + "addbase", + "addclosehook", + "addinfo", + "addinfourl", + "always_safe", + "basejoin", + "ftpcache", + "ftperrors", + "ftpwrapper", + "getproxies", + "getproxies_environment", + "getproxies_macosx_sysconf", + "main", + "noheaders", + "pathname2url", + "proxy_bypass", + "proxy_bypass_environment", + "proxy_bypass_macosx_sysconf", + "quote", + "quote_plus", + "reporthook", + "splitattr", + "splithost", + "splitnport", + "splitpasswd", + "splitport", + "splitquery", + "splittag", + "splittype", + "splituser", + "splitvalue", + "unquote", + "unquote_plus", + "unwrap", + "url2pathname", + "urlcleanup", + "urlencode", + "urlopen", + "urlretrieve", + } + ) + }, + "deprecated-sys-function": {"sys": frozenset({"exc_clear"})}, + } + + if (3, 4) <= sys.version_info < (3, 4, 4): + # Python 3.4.0 -> 3.4.3 has a bug which breaks `repr_tree()`: + # https://bugs.python.org/issue23572 + _python_2_tests = frozenset() # type: FrozenSet[str] + else: + _python_2_tests = frozenset( + [ + astroid.extract_node(x).repr_tree() + for x in [ + "sys.version_info[0] == 2", + "sys.version_info[0] < 3", + "sys.version_info == (2, 7)", + "sys.version_info <= (2, 7)", + "sys.version_info < (3, 0)", + ] + ] + ) + + def __init__(self, *args, **kwargs): + self._future_division = False + self._future_absolute_import = False + self._modules_warned_about = set() + self._branch_stack = [] + super(Python3Checker, self).__init__(*args, **kwargs) + + # pylint: disable=keyword-arg-before-vararg, arguments-differ + def add_message(self, msg_id, always_warn=False, *args, **kwargs): + if always_warn or not ( + self._branch_stack and self._branch_stack[-1].is_py2_only + ): + super(Python3Checker, self).add_message(msg_id, *args, **kwargs) + + def _is_py2_test(self, node): + if isinstance(node.test, astroid.Attribute) and isinstance( + node.test.expr, astroid.Name + ): + if node.test.expr.name == "six" and node.test.attrname == "PY2": + return True + elif ( + isinstance(node.test, astroid.Compare) + and node.test.repr_tree() in self._python_2_tests + ): + return True + return False + + def visit_if(self, node): + self._branch_stack.append(Branch(node, self._is_py2_test(node))) + + def leave_if(self, node): + assert self._branch_stack.pop().node == node + + def visit_ifexp(self, node): + self._branch_stack.append(Branch(node, self._is_py2_test(node))) + + def leave_ifexp(self, node): + assert self._branch_stack.pop().node == node + + def visit_module(self, node): # pylint: disable=unused-argument + """Clear checker state after previous module.""" + self._future_division = False + self._future_absolute_import = False + + def visit_functiondef(self, node): + if node.is_method(): + if node.name in self._unused_magic_methods: + method_name = node.name + if node.name.startswith("__"): + method_name = node.name[2:-2] + self.add_message(method_name + "-method", node=node) + elif node.name == "next": + # If there is a method named `next` declared, if it is invokable + # with zero arguments then it implements the Iterator protocol. + # This means if the method is an instance method or a + # classmethod 1 argument should cause a failure, if it is a + # staticmethod 0 arguments should cause a failure. + failing_arg_count = 1 + if utils.decorated_with(node, [bases.BUILTINS + ".staticmethod"]): + failing_arg_count = 0 + if len(node.args.args) == failing_arg_count: + self.add_message("next-method-defined", node=node) + + @utils.check_messages("parameter-unpacking") + def visit_arguments(self, node): + for arg in node.args: + if isinstance(arg, astroid.Tuple): + self.add_message("parameter-unpacking", node=arg) + + @utils.check_messages("comprehension-escape") + def visit_listcomp(self, node): + names = { + generator.target.name + for generator in node.generators + if isinstance(generator.target, astroid.AssignName) + } + scope = node.parent.scope() + scope_names = scope.nodes_of_class(astroid.Name, skip_klass=astroid.FunctionDef) + has_redefined_assign_name = any( + assign_name + for assign_name in scope.nodes_of_class( + astroid.AssignName, skip_klass=astroid.FunctionDef + ) + if assign_name.name in names and assign_name.lineno > node.lineno + ) + if has_redefined_assign_name: + return + + emitted_for_names = set() + scope_names = list(scope_names) + for scope_name in scope_names: + if ( + scope_name.name not in names + or scope_name.lineno <= node.lineno + or scope_name.name in emitted_for_names + or scope_name.scope() == node + ): + continue + + emitted_for_names.add(scope_name.name) + self.add_message("comprehension-escape", node=scope_name) + + def visit_name(self, node): + """Detect when a "bad" built-in is referenced.""" + found_node, _ = node.lookup(node.name) + if not _is_builtin(found_node): + return + if node.name not in self._bad_builtins: + return + if node_ignores_exception(node) or isinstance( + find_try_except_wrapper_node(node), astroid.ExceptHandler + ): + return + + message = node.name.lower() + "-builtin" + self.add_message(message, node=node) + + @utils.check_messages("print-statement") + def visit_print(self, node): + self.add_message("print-statement", node=node, always_warn=True) + + def _warn_if_deprecated(self, node, module, attributes, report_on_modules=True): + for message, module_map in self._bad_python3_module_map.items(): + if module in module_map and module not in self._modules_warned_about: + if isinstance(module_map, frozenset): + if report_on_modules: + self._modules_warned_about.add(module) + self.add_message(message, node=node) + elif attributes and module_map[module].intersection(attributes): + self.add_message(message, node=node) + + def visit_importfrom(self, node): + if node.modname == "__future__": + for name, _ in node.names: + if name == "division": + self._future_division = True + elif name == "absolute_import": + self._future_absolute_import = True + else: + if not self._future_absolute_import: + if self.linter.is_message_enabled("no-absolute-import"): + self.add_message("no-absolute-import", node=node) + self._future_absolute_import = True + if not _is_conditional_import(node) and not node.level: + self._warn_if_deprecated(node, node.modname, {x[0] for x in node.names}) + + if node.names[0][0] == "*": + if self.linter.is_message_enabled("import-star-module-level"): + if not isinstance(node.scope(), astroid.Module): + self.add_message("import-star-module-level", node=node) + + def visit_import(self, node): + if not self._future_absolute_import: + if self.linter.is_message_enabled("no-absolute-import"): + self.add_message("no-absolute-import", node=node) + self._future_absolute_import = True + if not _is_conditional_import(node): + for name, _ in node.names: + self._warn_if_deprecated(node, name, None) + + @utils.check_messages("metaclass-assignment") + def visit_classdef(self, node): + if "__metaclass__" in node.locals: + self.add_message("metaclass-assignment", node=node) + locals_and_methods = set(node.locals).union(x.name for x in node.mymethods()) + if "__eq__" in locals_and_methods and "__hash__" not in locals_and_methods: + self.add_message("eq-without-hash", node=node) + + @utils.check_messages("old-division") + def visit_binop(self, node): + if not self._future_division and node.op == "/": + for arg in (node.left, node.right): + if isinstance(arg, astroid.Const) and isinstance(arg.value, float): + break + else: + self.add_message("old-division", node=node) + + def _check_cmp_argument(self, node): + # Check that the `cmp` argument is used + kwargs = [] + if isinstance(node.func, astroid.Attribute) and node.func.attrname == "sort": + inferred = utils.safe_infer(node.func.expr) + if not inferred: + return + + builtins_list = "{}.list".format(bases.BUILTINS) + if isinstance(inferred, astroid.List) or inferred.qname() == builtins_list: + kwargs = node.keywords + + elif isinstance(node.func, astroid.Name) and node.func.name == "sorted": + inferred = utils.safe_infer(node.func) + if not inferred: + return + + builtins_sorted = "{}.sorted".format(bases.BUILTINS) + if inferred.qname() == builtins_sorted: + kwargs = node.keywords + + for kwarg in kwargs or []: + if kwarg.arg == "cmp": + self.add_message("using-cmp-argument", node=node) + return + + @staticmethod + def _is_constant_string_or_name(node): + if isinstance(node, astroid.Const): + return isinstance(node.value, str) + return isinstance(node, astroid.Name) + + @staticmethod + def _is_none(node): + return isinstance(node, astroid.Const) and node.value is None + + @staticmethod + def _has_only_n_positional_args(node, number_of_args): + return len(node.args) == number_of_args and all(node.args) and not node.keywords + + @staticmethod + def _could_be_string(inferred_types): + confidence = INFERENCE if inferred_types else INFERENCE_FAILURE + for inferred_type in inferred_types: + if inferred_type is astroid.Uninferable: + confidence = INFERENCE_FAILURE + elif not ( + isinstance(inferred_type, astroid.Const) + and isinstance(inferred_type.value, str) + ): + return None + return confidence + + def visit_call(self, node): + self._check_cmp_argument(node) + + if isinstance(node.func, astroid.Attribute): + inferred_types = set() + try: + for inferred_receiver in node.func.expr.infer(): + if inferred_receiver is astroid.Uninferable: + continue + inferred_types.add(inferred_receiver) + if isinstance(inferred_receiver, astroid.Module): + self._warn_if_deprecated( + node, + inferred_receiver.name, + {node.func.attrname}, + report_on_modules=False, + ) + if ( + _inferred_value_is_dict(inferred_receiver) + and node.func.attrname in DICT_METHODS + ): + if not _in_iterating_context(node): + checker = "dict-{}-not-iterating".format(node.func.attrname) + self.add_message(checker, node=node) + except astroid.InferenceError: + pass + if node.args: + is_str_confidence = self._could_be_string(inferred_types) + if is_str_confidence: + if ( + node.func.attrname in ("encode", "decode") + and len(node.args) >= 1 + and node.args[0] + ): + first_arg = node.args[0] + self._validate_encoding(first_arg, node) + if ( + node.func.attrname == "translate" + and self._has_only_n_positional_args(node, 2) + and self._is_none(node.args[0]) + and self._is_constant_string_or_name(node.args[1]) + ): + # The above statement looking for calls of the form: + # + # foo.translate(None, 'abc123') + # + # or + # + # foo.translate(None, some_variable) + # + # This check is somewhat broad and _may_ have some false positives, but + # after checking several large codebases it did not have any false + # positives while finding several real issues. This call pattern seems + # rare enough that the trade off is worth it. + self.add_message( + "deprecated-str-translate-call", + node=node, + confidence=is_str_confidence, + ) + return + if node.keywords: + return + if node.func.attrname == "next": + self.add_message("next-method-called", node=node) + else: + if node.func.attrname in ("iterkeys", "itervalues", "iteritems"): + self.add_message("dict-iter-method", node=node) + elif node.func.attrname in ("viewkeys", "viewvalues", "viewitems"): + self.add_message("dict-view-method", node=node) + elif isinstance(node.func, astroid.Name): + found_node = node.func.lookup(node.func.name)[0] + if _is_builtin(found_node): + if node.func.name in ("filter", "map", "range", "zip"): + if not _in_iterating_context(node): + checker = "{}-builtin-not-iterating".format(node.func.name) + self.add_message(checker, node=node) + if node.func.name == "open" and node.keywords: + kwargs = node.keywords + for kwarg in kwargs or []: + if kwarg.arg == "encoding": + self._validate_encoding(kwarg.value, node) + break + + def _validate_encoding(self, encoding, node): + if isinstance(encoding, astroid.Const): + value = encoding.value + if value in self._invalid_encodings: + self.add_message("invalid-str-codec", node=node) + + @utils.check_messages("indexing-exception") + def visit_subscript(self, node): + """ Look for indexing exceptions. """ + try: + for inferred in node.value.infer(): + if not isinstance(inferred, astroid.Instance): + continue + if utils.inherit_from_std_ex(inferred): + self.add_message("indexing-exception", node=node) + except astroid.InferenceError: + return + + def visit_assignattr(self, node): + if isinstance(node.assign_type(), astroid.AugAssign): + self.visit_attribute(node) + + def visit_delattr(self, node): + self.visit_attribute(node) + + @utils.check_messages("exception-message-attribute", "xreadlines-attribute") + def visit_attribute(self, node): + """Look for removed attributes""" + if node.attrname == "xreadlines": + self.add_message("xreadlines-attribute", node=node) + return + + exception_message = "message" + try: + for inferred in node.expr.infer(): + if isinstance(inferred, astroid.Instance) and utils.inherit_from_std_ex( + inferred + ): + if node.attrname == exception_message: + + # Exceptions with .message clearly defined are an exception + if exception_message in inferred.instance_attrs: + continue + self.add_message("exception-message-attribute", node=node) + if isinstance(inferred, astroid.Module): + self._warn_if_deprecated( + node, inferred.name, {node.attrname}, report_on_modules=False + ) + except astroid.InferenceError: + return + + @utils.check_messages("unpacking-in-except", "comprehension-escape") + def visit_excepthandler(self, node): + """Visit an except handler block and check for exception unpacking.""" + + def _is_used_in_except_block(node): + scope = node.scope() + current = node + while ( + current + and current != scope + and not isinstance(current, astroid.ExceptHandler) + ): + current = current.parent + return isinstance(current, astroid.ExceptHandler) and current.type != node + + if isinstance(node.name, (astroid.Tuple, astroid.List)): + self.add_message("unpacking-in-except", node=node) + return + + if not node.name: + return + + # Find any names + scope = node.parent.scope() + scope_names = scope.nodes_of_class(astroid.Name, skip_klass=astroid.FunctionDef) + scope_names = list(scope_names) + potential_leaked_names = [ + scope_name + for scope_name in scope_names + if scope_name.name == node.name.name + and scope_name.lineno > node.lineno + and not _is_used_in_except_block(scope_name) + ] + reassignments_for_same_name = { + assign_name.lineno + for assign_name in scope.nodes_of_class( + astroid.AssignName, skip_klass=astroid.FunctionDef + ) + if assign_name.name == node.name.name + } + for leaked_name in potential_leaked_names: + if any( + node.lineno < elem < leaked_name.lineno + for elem in reassignments_for_same_name + ): + continue + self.add_message("exception-escape", node=leaked_name) + + @utils.check_messages("backtick") + def visit_repr(self, node): + self.add_message("backtick", node=node) + + @utils.check_messages("raising-string", "old-raise-syntax") + def visit_raise(self, node): + """Visit a raise statement and check for raising + strings or old-raise-syntax. + """ + + # Ignore empty raise. + if node.exc is None: + return + expr = node.exc + if self._check_raise_value(node, expr): + return + try: + value = next(astroid.unpack_infer(expr)) + except astroid.InferenceError: + return + self._check_raise_value(node, value) + + def _check_raise_value(self, node, expr): + if isinstance(expr, astroid.Const): + value = expr.value + if isinstance(value, str): + self.add_message("raising-string", node=node) + return True + return None + + +class Python3TokenChecker(checkers.BaseTokenChecker): + __implements__ = interfaces.ITokenChecker + name = "python3" + enabled = False + + msgs = { + "E1606": ( + "Use of long suffix", + "long-suffix", + 'Used when "l" or "L" is used to mark a long integer. ' + "This will not work in Python 3, since `int` and `long` " + "types have merged.", + {"maxversion": (3, 0)}, + ), + "E1607": ( + "Use of the <> operator", + "old-ne-operator", + 'Used when the deprecated "<>" operator is used instead ' + 'of "!=". This is removed in Python 3.', + {"maxversion": (3, 0), "old_names": [("W0331", "old-ne-operator")]}, + ), + "E1608": ( + "Use of old octal literal", + "old-octal-literal", + "Used when encountering the old octal syntax, " + "removed in Python 3. To use the new syntax, " + "prepend 0o on the number.", + {"maxversion": (3, 0)}, + ), + "E1610": ( + "Non-ascii bytes literals not supported in 3.x", + "non-ascii-bytes-literal", + "Used when non-ascii bytes literals are found in a program. " + "They are no longer supported in Python 3.", + {"maxversion": (3, 0)}, + ), + } + + def process_tokens(self, tokens): + for idx, (tok_type, token, start, _, _) in enumerate(tokens): + if tok_type == tokenize.NUMBER: + if token.lower().endswith("l"): + # This has a different semantic than lowercase-l-suffix. + self.add_message("long-suffix", line=start[0]) + elif _is_old_octal(token): + self.add_message("old-octal-literal", line=start[0]) + if tokens[idx][1] == "<>": + self.add_message("old-ne-operator", line=tokens[idx][2][0]) + if tok_type == tokenize.STRING and token.startswith("b"): + if any(elem for elem in token if ord(elem) > 127): + self.add_message("non-ascii-bytes-literal", line=start[0]) + + +def register(linter): + linter.register_checker(Python3Checker(linter)) + linter.register_checker(Python3TokenChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/raw_metrics.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/raw_metrics.py new file mode 100644 index 0000000..7ab1656 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/raw_metrics.py @@ -0,0 +1,125 @@ +# Copyright (c) 2007, 2010, 2013, 2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2013 Google, Inc. +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Mike Frysinger <vapier@gentoo.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" Copyright (c) 2003-2010 LOGILAB S.A. (Paris, FRANCE). + http://www.logilab.fr/ -- mailto:contact@logilab.fr + +Raw metrics checker +""" + +import tokenize +from typing import Any + +from pylint.interfaces import ITokenChecker +from pylint.exceptions import EmptyReportError +from pylint.checkers import BaseTokenChecker +from pylint.reporters import diff_string +from pylint.reporters.ureports.nodes import Table + + +def report_raw_stats(sect, stats, old_stats): + """calculate percentage of code / doc / comment / empty + """ + total_lines = stats["total_lines"] + if not total_lines: + raise EmptyReportError() + sect.description = "%s lines have been analyzed" % total_lines + lines = ("type", "number", "%", "previous", "difference") + for node_type in ("code", "docstring", "comment", "empty"): + key = node_type + "_lines" + total = stats[key] + percent = float(total * 100) / total_lines + old = old_stats.get(key, None) + if old is not None: + diff_str = diff_string(old, total) + else: + old, diff_str = "NC", "NC" + lines += (node_type, str(total), "%.2f" % percent, str(old), diff_str) + sect.append(Table(children=lines, cols=5, rheaders=1)) + + +class RawMetricsChecker(BaseTokenChecker): + """does not check anything but gives some raw metrics : + * total number of lines + * total number of code lines + * total number of docstring lines + * total number of comments lines + * total number of empty lines + """ + + __implements__ = (ITokenChecker,) + + # configuration section name + name = "metrics" + # configuration options + options = () + # messages + msgs = {} # type: Any + # reports + reports = (("RP0701", "Raw metrics", report_raw_stats),) + + def __init__(self, linter): + BaseTokenChecker.__init__(self, linter) + self.stats = None + + def open(self): + """init statistics""" + self.stats = self.linter.add_stats( + total_lines=0, + code_lines=0, + empty_lines=0, + docstring_lines=0, + comment_lines=0, + ) + + def process_tokens(self, tokens): + """update stats""" + i = 0 + tokens = list(tokens) + while i < len(tokens): + i, lines_number, line_type = get_type(tokens, i) + self.stats["total_lines"] += lines_number + self.stats[line_type] += lines_number + + +JUNK = (tokenize.NL, tokenize.INDENT, tokenize.NEWLINE, tokenize.ENDMARKER) + + +def get_type(tokens, start_index): + """return the line type : docstring, comment, code, empty""" + i = start_index + tok_type = tokens[i][0] + start = tokens[i][2] + pos = start + line_type = None + while i < len(tokens) and tokens[i][2][0] == start[0]: + tok_type = tokens[i][0] + pos = tokens[i][3] + if line_type is None: + if tok_type == tokenize.STRING: + line_type = "docstring_lines" + elif tok_type == tokenize.COMMENT: + line_type = "comment_lines" + elif tok_type in JUNK: + pass + else: + line_type = "code_lines" + i += 1 + if line_type is None: + line_type = "empty_lines" + elif i < len(tokens) and tokens[i][0] == tokenize.NEWLINE: + i += 1 + return i, pos[0] - start[0] + 1, line_type + + +def register(linter): + """ required method to auto register this checker """ + linter.register_checker(RawMetricsChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/refactoring.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/refactoring.py new file mode 100644 index 0000000..47a7025 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/refactoring.py @@ -0,0 +1,1426 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2017-2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2017 Hugo <hugovk@users.noreply.github.com> +# Copyright (c) 2017 Łukasz Sznuk <ls@rdprojekt.pl> +# Copyright (c) 2017 Alex Hearn <alex.d.hearn@gmail.com> +# Copyright (c) 2017 Antonio Ossa <aaossa@uc.cl> +# Copyright (c) 2018 Konstantin Manna <Konstantin@Manna.uno> +# Copyright (c) 2018 Konstantin <Github@pheanex.de> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Matej Marušák <marusak.matej@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Copyright (c) 2018 Mr. Senko <atodorov@mrsenko.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Looks for code which can be refactored.""" +import builtins +from functools import reduce + +import collections +import itertools +import tokenize + +import astroid +from astroid import decorators + +from pylint import interfaces +from pylint import checkers +from pylint import utils as lint_utils +from pylint.checkers import utils + + +KNOWN_INFINITE_ITERATORS = {"itertools.count"} + + +def _all_elements_are_true(gen): + values = list(gen) + return values and all(values) + + +def _if_statement_is_always_returning(if_node): + def _has_return_node(elems, scope): + for node in elems: + if isinstance(node, astroid.If) and node.orelse: + yield _if_statement_is_always_returning(node) + if isinstance(node, astroid.Return): + yield node.scope() is scope + + scope = if_node.scope() + return _all_elements_are_true(_has_return_node(if_node.body, scope=scope)) + + +class RefactoringChecker(checkers.BaseTokenChecker): + """Looks for code which can be refactored + + This checker also mixes the astroid and the token approaches + in order to create knowledge about whether an "else if" node + is a true "else if" node, or an "elif" node. + """ + + __implements__ = (interfaces.ITokenChecker, interfaces.IAstroidChecker) + + name = "refactoring" + + msgs = { + "R1701": ( + "Consider merging these isinstance calls to isinstance(%s, (%s))", + "consider-merging-isinstance", + "Used when multiple consecutive isinstance calls can be merged into one.", + ), + "R1706": ( + "Consider using ternary (%s)", + "consider-using-ternary", + "Used when one of known pre-python 2.5 ternary syntax is used.", + ), + "R1709": ( + "Boolean expression may be simplified to %s", + "simplify-boolean-expression", + "Emitted when redundant pre-python 2.5 ternary syntax is used.", + ), + "R1702": ( + "Too many nested blocks (%s/%s)", + "too-many-nested-blocks", + "Used when a function or a method has too many nested " + "blocks. This makes the code less understandable and " + "maintainable.", + {"old_names": [("R0101", "too-many-nested-blocks")]}, + ), + "R1703": ( + "The if statement can be replaced with %s", + "simplifiable-if-statement", + "Used when an if statement can be replaced with 'bool(test)'. ", + {"old_names": [("R0102", "simplifiable-if-statement")]}, + ), + "R1704": ( + "Redefining argument with the local name %r", + "redefined-argument-from-local", + "Used when a local name is redefining an argument, which might " + "suggest a potential error. This is taken in account only for " + "a handful of name binding operations, such as for iteration, " + "with statement assignment and exception handler assignment.", + ), + "R1705": ( + 'Unnecessary "%s" after "return"', + "no-else-return", + "Used in order to highlight an unnecessary block of " + "code following an if containing a return statement. " + "As such, it will warn when it encounters an else " + "following a chain of ifs, all of them containing a " + "return statement.", + ), + "R1707": ( + "Disallow trailing comma tuple", + "trailing-comma-tuple", + "In Python, a tuple is actually created by the comma symbol, " + "not by the parentheses. Unfortunately, one can actually create a " + "tuple by misplacing a trailing comma, which can lead to potential " + "weird bugs in your code. You should always use parentheses " + "explicitly for creating a tuple.", + ), + "R1708": ( + "Do not raise StopIteration in generator, use return statement instead", + "stop-iteration-return", + "According to PEP479, the raise of StopIteration to end the loop of " + "a generator may lead to hard to find bugs. This PEP specify that " + "raise StopIteration has to be replaced by a simple return statement", + ), + "R1710": ( + "Either all return statements in a function should return an expression, " + "or none of them should.", + "inconsistent-return-statements", + "According to PEP8, if any return statement returns an expression, " + "any return statements where no value is returned should explicitly " + "state this as return None, and an explicit return statement " + "should be present at the end of the function (if reachable)", + ), + "R1711": ( + "Useless return at end of function or method", + "useless-return", + 'Emitted when a single "return" or "return None" statement is found ' + "at the end of function or method definition. This statement can safely be " + "removed because Python will implicitly return None", + ), + "R1712": ( + "Consider using tuple unpacking for swapping variables", + "consider-swap-variables", + "You do not have to use a temporary variable in order to " + 'swap variables. Using "tuple unpacking" to directly swap ' + "variables makes the intention more clear.", + ), + "R1713": ( + "Consider using str.join(sequence) for concatenating " + "strings from an iterable", + "consider-using-join", + "Using str.join(sequence) is faster, uses less memory " + "and increases readability compared to for-loop iteration.", + ), + "R1714": ( + 'Consider merging these comparisons with "in" to %r', + "consider-using-in", + "To check if a variable is equal to one of many values," + 'combine the values into a tuple and check if the variable is contained "in" it ' + "instead of checking for equality against each of the values." + "This is faster and less verbose.", + ), + "R1715": ( + "Consider using dict.get for getting values from a dict " + "if a key is present or a default if not", + "consider-using-get", + "Using the builtin dict.get for getting a value from a dictionary " + "if a key is present or a default if not, is simpler and considered " + "more idiomatic, although sometimes a bit slower", + ), + "R1716": ( + "Simplify chained comparison between the operands", + "chained-comparison", + "This message is emitted when pylint encounters boolean operation like" + '"a < b and b < c", suggesting instead to refactor it to "a < b < c"', + ), + "R1717": ( + "Consider using a dictionary comprehension", + "consider-using-dict-comprehension", + "Although there is nothing syntactically wrong with this code, " + "it is hard to read and can be simplified to a dict comprehension." + "Also it is faster since you don't need to create another " + "transient list", + ), + "R1718": ( + "Consider using a set comprehension", + "consider-using-set-comprehension", + "Although there is nothing syntactically wrong with this code, " + "it is hard to read and can be simplified to a set comprehension." + "Also it is faster since you don't need to create another " + "transient list", + ), + "R1719": ( + "The if expression can be replaced with %s", + "simplifiable-if-expression", + "Used when an if expression can be replaced with 'bool(test)'. ", + ), + } + options = ( + ( + "max-nested-blocks", + { + "default": 5, + "type": "int", + "metavar": "<int>", + "help": "Maximum number of nested blocks for function / method body", + }, + ), + ( + "never-returning-functions", + { + "default": ("sys.exit",), + "type": "csv", + "help": "Complete name of functions that never returns. When checking " + "for inconsistent-return-statements if a never returning function is " + "called then it will be considered as an explicit return statement " + "and no message will be printed.", + }, + ), + ) + + priority = 0 + + def __init__(self, linter=None): + checkers.BaseTokenChecker.__init__(self, linter) + self._return_nodes = {} + self._init() + self._never_returning_functions = None + + def _init(self): + self._nested_blocks = [] + self._elifs = [] + self._nested_blocks_msg = None + self._reported_swap_nodes = set() + + def open(self): + # do this in open since config not fully initialized in __init__ + self._never_returning_functions = set(self.config.never_returning_functions) + + @decorators.cachedproperty + def _dummy_rgx(self): + return lint_utils.get_global_option(self, "dummy-variables-rgx", default=None) + + @staticmethod + def _is_bool_const(node): + return isinstance(node.value, astroid.Const) and isinstance( + node.value.value, bool + ) + + def _is_actual_elif(self, node): + """Check if the given node is an actual elif + + This is a problem we're having with the builtin ast module, + which splits `elif` branches into a separate if statement. + Unfortunately we need to know the exact type in certain + cases. + """ + if isinstance(node.parent, astroid.If): + orelse = node.parent.orelse + # current if node must directly follow an "else" + if orelse and orelse == [node]: + if (node.lineno, node.col_offset) in self._elifs: + return True + return False + + def _check_simplifiable_if(self, node): + """Check if the given if node can be simplified. + + The if statement can be reduced to a boolean expression + in some cases. For instance, if there are two branches + and both of them return a boolean value that depends on + the result of the statement's test, then this can be reduced + to `bool(test)` without losing any functionality. + """ + + if self._is_actual_elif(node): + # Not interested in if statements with multiple branches. + return + if len(node.orelse) != 1 or len(node.body) != 1: + return + + # Check if both branches can be reduced. + first_branch = node.body[0] + else_branch = node.orelse[0] + if isinstance(first_branch, astroid.Return): + if not isinstance(else_branch, astroid.Return): + return + first_branch_is_bool = self._is_bool_const(first_branch) + else_branch_is_bool = self._is_bool_const(else_branch) + reduced_to = "'return bool(test)'" + elif isinstance(first_branch, astroid.Assign): + if not isinstance(else_branch, astroid.Assign): + return + + # Check if we assign to the same value + first_branch_targets = [ + target.name + for target in first_branch.targets + if isinstance(target, astroid.AssignName) + ] + else_branch_targets = [ + target.name + for target in else_branch.targets + if isinstance(target, astroid.AssignName) + ] + if not first_branch_targets or not else_branch_targets: + return + if sorted(first_branch_targets) != sorted(else_branch_targets): + return + + first_branch_is_bool = self._is_bool_const(first_branch) + else_branch_is_bool = self._is_bool_const(else_branch) + reduced_to = "'var = bool(test)'" + else: + return + + if not first_branch_is_bool or not else_branch_is_bool: + return + if not first_branch.value.value: + # This is a case that can't be easily simplified and + # if it can be simplified, it will usually result in a + # code that's harder to understand and comprehend. + # Let's take for instance `arg and arg <= 3`. This could theoretically be + # reduced to `not arg or arg > 3`, but the net result is that now the + # condition is harder to understand, because it requires understanding of + # an extra clause: + # * first, there is the negation of truthness with `not arg` + # * the second clause is `arg > 3`, which occurs when arg has a + # a truth value, but it implies that `arg > 3` is equivalent + # with `arg and arg > 3`, which means that the user must + # think about this assumption when evaluating `arg > 3`. + # The original form is easier to grasp. + return + + self.add_message("simplifiable-if-statement", node=node, args=(reduced_to,)) + + def process_tokens(self, tokens): + # Process tokens and look for 'if' or 'elif' + for index, token in enumerate(tokens): + token_string = token[1] + if token_string == "elif": + # AST exists by the time process_tokens is called, so + # it's safe to assume tokens[index+1] + # exists. tokens[index+1][2] is the elif's position as + # reported by CPython and PyPy, + # tokens[index][2] is the actual position and also is + # reported by IronPython. + self._elifs.extend([tokens[index][2], tokens[index + 1][2]]) + elif is_trailing_comma(tokens, index): + if self.linter.is_message_enabled("trailing-comma-tuple"): + self.add_message("trailing-comma-tuple", line=token.start[0]) + + def leave_module(self, _): + self._init() + + @utils.check_messages("too-many-nested-blocks") + def visit_tryexcept(self, node): + self._check_nested_blocks(node) + + visit_tryfinally = visit_tryexcept + visit_while = visit_tryexcept + + def _check_redefined_argument_from_local(self, name_node): + if self._dummy_rgx and self._dummy_rgx.match(name_node.name): + return + if not name_node.lineno: + # Unknown position, maybe it is a manually built AST? + return + + scope = name_node.scope() + if not isinstance(scope, astroid.FunctionDef): + return + + for defined_argument in scope.args.nodes_of_class( + astroid.AssignName, skip_klass=(astroid.Lambda,) + ): + if defined_argument.name == name_node.name: + self.add_message( + "redefined-argument-from-local", + node=name_node, + args=(name_node.name,), + ) + + @utils.check_messages("redefined-argument-from-local", "too-many-nested-blocks") + def visit_for(self, node): + self._check_nested_blocks(node) + + for name in node.target.nodes_of_class(astroid.AssignName): + self._check_redefined_argument_from_local(name) + + @utils.check_messages("redefined-argument-from-local") + def visit_excepthandler(self, node): + if node.name and isinstance(node.name, astroid.AssignName): + self._check_redefined_argument_from_local(node.name) + + @utils.check_messages("redefined-argument-from-local") + def visit_with(self, node): + for _, names in node.items: + if not names: + continue + for name in names.nodes_of_class(astroid.AssignName): + self._check_redefined_argument_from_local(name) + + def _check_superfluous_else_return(self, node): + if not node.orelse: + # Not interested in if statements without else. + return + + if _if_statement_is_always_returning(node) and not self._is_actual_elif(node): + orelse = node.orelse and node.orelse[0] + followed_by_elif = (orelse.lineno, orelse.col_offset) in self._elifs + self.add_message( + "no-else-return", node=node, args="elif" if followed_by_elif else "else" + ) + + def _check_consider_get(self, node): + def type_and_name_are_equal(node_a, node_b): + for _type in [astroid.Name, astroid.AssignName]: + if all(isinstance(_node, _type) for _node in [node_a, node_b]): + return node_a.name == node_b.name + if all(isinstance(_node, astroid.Const) for _node in [node_a, node_b]): + return node_a.value == node_b.value + return False + + if_block_ok = ( + isinstance(node.test, astroid.Compare) + and len(node.body) == 1 + and isinstance(node.body[0], astroid.Assign) + and isinstance(node.body[0].value, astroid.Subscript) + and type_and_name_are_equal(node.body[0].value.value, node.test.ops[0][1]) + and isinstance(node.body[0].value.slice, astroid.Index) + and type_and_name_are_equal(node.body[0].value.slice.value, node.test.left) + and len(node.body[0].targets) == 1 + and isinstance(node.body[0].targets[0], astroid.AssignName) + and isinstance(utils.safe_infer(node.test.ops[0][1]), astroid.Dict) + ) + + if if_block_ok and not node.orelse: + self.add_message("consider-using-get", node=node) + elif ( + if_block_ok + and len(node.orelse) == 1 + and isinstance(node.orelse[0], astroid.Assign) + and type_and_name_are_equal( + node.orelse[0].targets[0], node.body[0].targets[0] + ) + and len(node.orelse[0].targets) == 1 + ): + self.add_message("consider-using-get", node=node) + + @utils.check_messages( + "too-many-nested-blocks", + "simplifiable-if-statement", + "no-else-return", + "consider-using-get", + ) + def visit_if(self, node): + self._check_simplifiable_if(node) + self._check_nested_blocks(node) + self._check_superfluous_else_return(node) + self._check_consider_get(node) + + @utils.check_messages("simplifiable-if-expression") + def visit_ifexp(self, node): + self._check_simplifiable_ifexp(node) + + def _check_simplifiable_ifexp(self, node): + if not isinstance(node.body, astroid.Const) or not isinstance( + node.orelse, astroid.Const + ): + return + + if not isinstance(node.body.value, bool) or not isinstance( + node.orelse.value, bool + ): + return + + if isinstance(node.test, astroid.Compare): + test_reduced_to = "test" + else: + test_reduced_to = "bool(test)" + + if (node.body.value, node.orelse.value) == (True, False): + reduced_to = "'{}'".format(test_reduced_to) + elif (node.body.value, node.orelse.value) == (False, True): + reduced_to = "'not test'" + else: + return + + self.add_message("simplifiable-if-expression", node=node, args=(reduced_to,)) + + @utils.check_messages( + "too-many-nested-blocks", "inconsistent-return-statements", "useless-return" + ) + def leave_functiondef(self, node): + # check left-over nested blocks stack + self._emit_nested_blocks_message_if_needed(self._nested_blocks) + # new scope = reinitialize the stack of nested blocks + self._nested_blocks = [] + #  check consistent return statements + self._check_consistent_returns(node) + # check for single return or return None at the end + self._check_return_at_the_end(node) + self._return_nodes[node.name] = [] + + @utils.check_messages("stop-iteration-return") + def visit_raise(self, node): + self._check_stop_iteration_inside_generator(node) + + def _check_stop_iteration_inside_generator(self, node): + """Check if an exception of type StopIteration is raised inside a generator""" + frame = node.frame() + if not isinstance(frame, astroid.FunctionDef) or not frame.is_generator(): + return + if utils.node_ignores_exception(node, StopIteration): + return + if not node.exc: + return + exc = utils.safe_infer(node.exc) + if exc is None or exc is astroid.Uninferable: + return + if self._check_exception_inherit_from_stopiteration(exc): + self.add_message("stop-iteration-return", node=node) + + @staticmethod + def _check_exception_inherit_from_stopiteration(exc): + """Return True if the exception node in argument inherit from StopIteration""" + stopiteration_qname = "{}.StopIteration".format(utils.EXCEPTIONS_MODULE) + return any(_class.qname() == stopiteration_qname for _class in exc.mro()) + + def _check_consider_using_comprehension_constructor(self, node): + if ( + isinstance(node.func, astroid.Name) + and node.args + and node.func.name in {"dict", "set"} + and isinstance(node.args[0], astroid.ListComp) + ): + message_name = "consider-using-{}-comprehension".format(node.func.name) + self.add_message(message_name, node=node) + + @utils.check_messages( + "stop-iteration-return", + "consider-using-dict-comprehension", + "consider-using-set-comprehension", + ) + def visit_call(self, node): + self._check_raising_stopiteration_in_generator_next_call(node) + self._check_consider_using_comprehension_constructor(node) + + def _check_raising_stopiteration_in_generator_next_call(self, node): + """Check if a StopIteration exception is raised by the call to next function + + If the next value has a default value, then do not add message. + + :param node: Check to see if this Call node is a next function + :type node: :class:`astroid.node_classes.Call` + """ + + def _looks_like_infinite_iterator(param): + inferred = utils.safe_infer(param) + if inferred: + return inferred.qname() in KNOWN_INFINITE_ITERATORS + return False + + if isinstance(node.func, astroid.Attribute): + # A next() method, which is now what we want. + return + + inferred = utils.safe_infer(node.func) + if getattr(inferred, "name", "") == "next": + frame = node.frame() + # The next builtin can only have up to two + # positional arguments and no keyword arguments + has_sentinel_value = len(node.args) > 1 + if ( + isinstance(frame, astroid.FunctionDef) + and frame.is_generator() + and not has_sentinel_value + and not utils.node_ignores_exception(node, StopIteration) + and not _looks_like_infinite_iterator(node.args[0]) + ): + self.add_message("stop-iteration-return", node=node) + + def _check_nested_blocks(self, node): + """Update and check the number of nested blocks + """ + # only check block levels inside functions or methods + if not isinstance(node.scope(), astroid.FunctionDef): + return + # messages are triggered on leaving the nested block. Here we save the + # stack in case the current node isn't nested in the previous one + nested_blocks = self._nested_blocks[:] + if node.parent == node.scope(): + self._nested_blocks = [node] + else: + # go through ancestors from the most nested to the less + for ancestor_node in reversed(self._nested_blocks): + if ancestor_node == node.parent: + break + self._nested_blocks.pop() + # if the node is an elif, this should not be another nesting level + if isinstance(node, astroid.If) and self._is_actual_elif(node): + if self._nested_blocks: + self._nested_blocks.pop() + self._nested_blocks.append(node) + + # send message only once per group of nested blocks + if len(nested_blocks) > len(self._nested_blocks): + self._emit_nested_blocks_message_if_needed(nested_blocks) + + def _emit_nested_blocks_message_if_needed(self, nested_blocks): + if len(nested_blocks) > self.config.max_nested_blocks: + self.add_message( + "too-many-nested-blocks", + node=nested_blocks[0], + args=(len(nested_blocks), self.config.max_nested_blocks), + ) + + @staticmethod + def _duplicated_isinstance_types(node): + """Get the duplicated types from the underlying isinstance calls. + + :param astroid.BoolOp node: Node which should contain a bunch of isinstance calls. + :returns: Dictionary of the comparison objects from the isinstance calls, + to duplicate values from consecutive calls. + :rtype: dict + """ + duplicated_objects = set() + all_types = collections.defaultdict(set) + + for call in node.values: + if not isinstance(call, astroid.Call) or len(call.args) != 2: + continue + + inferred = utils.safe_infer(call.func) + if not inferred or not utils.is_builtin_object(inferred): + continue + + if inferred.name != "isinstance": + continue + + isinstance_object = call.args[0].as_string() + isinstance_types = call.args[1] + + if isinstance_object in all_types: + duplicated_objects.add(isinstance_object) + + if isinstance(isinstance_types, astroid.Tuple): + elems = [ + class_type.as_string() for class_type in isinstance_types.itered() + ] + else: + elems = [isinstance_types.as_string()] + all_types[isinstance_object].update(elems) + + # Remove all keys which not duplicated + return { + key: value for key, value in all_types.items() if key in duplicated_objects + } + + def _check_consider_merging_isinstance(self, node): + """Check isinstance calls which can be merged together.""" + if node.op != "or": + return + + first_args = self._duplicated_isinstance_types(node) + for duplicated_name, class_names in first_args.items(): + names = sorted(name for name in class_names) + self.add_message( + "consider-merging-isinstance", + node=node, + args=(duplicated_name, ", ".join(names)), + ) + + def _check_consider_using_in(self, node): + allowed_ops = {"or": "==", "and": "!="} + + if node.op not in allowed_ops or len(node.values) < 2: + return + + for value in node.values: + if ( + not isinstance(value, astroid.Compare) + or len(value.ops) != 1 + or value.ops[0][0] not in allowed_ops[node.op] + ): + return + for comparable in value.left, value.ops[0][1]: + if isinstance(comparable, astroid.Call): + return + + # Gather variables and values from comparisons + variables, values = [], [] + for value in node.values: + variable_set = set() + for comparable in value.left, value.ops[0][1]: + if isinstance(comparable, astroid.Name): + variable_set.add(comparable.as_string()) + values.append(comparable.as_string()) + variables.append(variable_set) + + # Look for (common-)variables that occur in all comparisons + common_variables = reduce(lambda a, b: a.intersection(b), variables) + + if not common_variables: + return + + # Gather information for the suggestion + common_variable = sorted(list(common_variables))[0] + comprehension = "in" if node.op == "or" else "not in" + values = list(collections.OrderedDict.fromkeys(values)) + values.remove(common_variable) + values_string = ", ".join(values) if len(values) != 1 else values[0] + "," + suggestion = "%s %s (%s)" % (common_variable, comprehension, values_string) + + self.add_message("consider-using-in", node=node, args=(suggestion,)) + + def _check_chained_comparison(self, node): + """Check if there is any chained comparison in the expression. + + Add a refactoring message if a boolOp contains comparison like a < b and b < c, + which can be chained as a < b < c. + """ + if ( + node.op != "and" + or len(node.values) < 2 + or not all(isinstance(value, astroid.Compare) for value in node.values) + ): + return + + def _find_lower_upper_bounds(comparison_node, lower_bounds, upper_bounds): + operator = comparison_node.ops[0][0] + left_operand, right_operand = ( + comparison_node.left, + comparison_node.ops[0][1], + ) + for operand in (left_operand, right_operand): + value = None + if isinstance(operand, astroid.Name): + value = operand.name + elif isinstance(operand, astroid.Const): + value = operand.value + + if value is None: + continue + + if operator in ("<", "<="): + if operand is left_operand: + lower_bounds.append(value) + else: + upper_bounds.append(value) + elif operator in (">", ">="): + if operand is left_operand: + upper_bounds.append(value) + else: + lower_bounds.append(value) + + lower_bounds = [] + upper_bounds = [] + for comparison_node in node.values: + _find_lower_upper_bounds(comparison_node, lower_bounds, upper_bounds) + + if set(lower_bounds).intersection(upper_bounds): + self.add_message("chained-comparison", node=node) + + @utils.check_messages( + "consider-merging-isinstance", "consider-using-in", "chained-comparison" + ) + def visit_boolop(self, node): + self._check_consider_merging_isinstance(node) + self._check_consider_using_in(node) + self._check_chained_comparison(node) + + @staticmethod + def _is_simple_assignment(node): + return ( + isinstance(node, astroid.Assign) + and len(node.targets) == 1 + and isinstance(node.targets[0], astroid.node_classes.AssignName) + and isinstance(node.value, astroid.node_classes.Name) + ) + + def _check_swap_variables(self, node): + if not node.next_sibling() or not node.next_sibling().next_sibling(): + return + assignments = [node, node.next_sibling(), node.next_sibling().next_sibling()] + if not all(self._is_simple_assignment(node) for node in assignments): + return + if any(node in self._reported_swap_nodes for node in assignments): + return + left = [node.targets[0].name for node in assignments] + right = [node.value.name for node in assignments] + if left[0] == right[-1] and left[1:] == right[:-1]: + self._reported_swap_nodes.update(assignments) + message = "consider-swap-variables" + self.add_message(message, node=node) + + @utils.check_messages( + "simplify-boolean-expression", + "consider-using-ternary", + "consider-swap-variables", + ) + def visit_assign(self, node): + self._check_swap_variables(node) + if self._is_and_or_ternary(node.value): + cond, truth_value, false_value = self._and_or_ternary_arguments(node.value) + else: + return + + if all( + isinstance(value, astroid.Compare) for value in (truth_value, false_value) + ): + return + + inferred_truth_value = utils.safe_infer(truth_value) + if inferred_truth_value in (None, astroid.Uninferable): + truth_boolean_value = True + else: + truth_boolean_value = truth_value.bool_value() + + if truth_boolean_value is False: + message = "simplify-boolean-expression" + suggestion = false_value.as_string() + else: + message = "consider-using-ternary" + suggestion = "{truth} if {cond} else {false}".format( + truth=truth_value.as_string(), + cond=cond.as_string(), + false=false_value.as_string(), + ) + self.add_message(message, node=node, args=(suggestion,)) + + visit_return = visit_assign + + def _check_consider_using_join(self, aug_assign): + """ + We start with the augmented assignment and work our way upwards. + Names of variables for nodes if match successful: + result = '' # assign + for number in ['1', '2', '3'] # for_loop + result += number # aug_assign + """ + for_loop = aug_assign.parent + if not isinstance(for_loop, astroid.For) or len(for_loop.body) > 1: + return + assign = for_loop.previous_sibling() + if not isinstance(assign, astroid.Assign): + return + result_assign_names = { + target.name + for target in assign.targets + if isinstance(target, astroid.AssignName) + } + + is_concat_loop = ( + aug_assign.op == "+=" + and isinstance(aug_assign.target, astroid.AssignName) + and len(for_loop.body) == 1 + and aug_assign.target.name in result_assign_names + and isinstance(assign.value, astroid.Const) + and isinstance(assign.value.value, str) + and isinstance(aug_assign.value, astroid.Name) + and aug_assign.value.name == for_loop.target.name + ) + if is_concat_loop: + self.add_message("consider-using-join", node=aug_assign) + + @utils.check_messages("consider-using-join") + def visit_augassign(self, node): + self._check_consider_using_join(node) + + @staticmethod + def _is_and_or_ternary(node): + """ + Returns true if node is 'condition and true_value or false_value' form. + + All of: condition, true_value and false_value should not be a complex boolean expression + """ + return ( + isinstance(node, astroid.BoolOp) + and node.op == "or" + and len(node.values) == 2 + and isinstance(node.values[0], astroid.BoolOp) + and not isinstance(node.values[1], astroid.BoolOp) + and node.values[0].op == "and" + and not isinstance(node.values[0].values[1], astroid.BoolOp) + and len(node.values[0].values) == 2 + ) + + @staticmethod + def _and_or_ternary_arguments(node): + false_value = node.values[1] + condition, true_value = node.values[0].values + return condition, true_value, false_value + + def visit_functiondef(self, node): + self._return_nodes[node.name] = list( + node.nodes_of_class(astroid.Return, skip_klass=astroid.FunctionDef) + ) + + def _check_consistent_returns(self, node): + """Check that all return statements inside a function are consistent. + + Return statements are consistent if: + - all returns are explicit and if there is no implicit return; + - all returns are empty and if there is, possibly, an implicit return. + + Args: + node (astroid.FunctionDef): the function holding the return statements. + + """ + # explicit return statements are those with a not None value + explicit_returns = [ + _node for _node in self._return_nodes[node.name] if _node.value is not None + ] + if not explicit_returns: + return + if len(explicit_returns) == len( + self._return_nodes[node.name] + ) and self._is_node_return_ended(node): + return + self.add_message("inconsistent-return-statements", node=node) + + def _is_node_return_ended(self, node): + """Check if the node ends with an explicit return statement. + + Args: + node (astroid.NodeNG): node to be checked. + + Returns: + bool: True if the node ends with an explicit statement, False otherwise. + + """ + #  Recursion base case + if isinstance(node, astroid.Return): + return True + if isinstance(node, astroid.Call): + try: + funcdef_node = node.func.inferred()[0] + if self._is_function_def_never_returning(funcdef_node): + return True + except astroid.InferenceError: + pass + # Avoid the check inside while loop as we don't know + #  if they will be completed + if isinstance(node, astroid.While): + return True + if isinstance(node, astroid.Raise): + # a Raise statement doesn't need to end with a return statement + # but if the exception raised is handled, then the handler has to + # ends with a return statement + if not node.exc: + # Ignore bare raises + return True + if not utils.is_node_inside_try_except(node): + # If the raise statement is not inside a try/except statement + #  then the exception is raised and cannot be caught. No need + #  to infer it. + return True + exc = utils.safe_infer(node.exc) + if exc is None or exc is astroid.Uninferable: + return False + exc_name = exc.pytype().split(".")[-1] + handlers = utils.get_exception_handlers(node, exc_name) + handlers = list(handlers) if handlers is not None else [] + if handlers: + # among all the handlers handling the exception at least one + # must end with a return statement + return any( + self._is_node_return_ended(_handler) for _handler in handlers + ) + # if no handlers handle the exception then it's ok + return True + if isinstance(node, astroid.If): + # if statement is returning if there are exactly two return statements in its + #  children : one for the body part, the other for the orelse part + # Do not check if inner function definition are return ended. + is_orelse_returning = any( + self._is_node_return_ended(_ore) + for _ore in node.orelse + if not isinstance(_ore, astroid.FunctionDef) + ) + is_if_returning = any( + self._is_node_return_ended(_ifn) + for _ifn in node.body + if not isinstance(_ifn, astroid.FunctionDef) + ) + return is_if_returning and is_orelse_returning + #  recurses on the children of the node except for those which are except handler + # because one cannot be sure that the handler will really be used + return any( + self._is_node_return_ended(_child) + for _child in node.get_children() + if not isinstance(_child, astroid.ExceptHandler) + ) + + def _is_function_def_never_returning(self, node): + """Return True if the function never returns. False otherwise. + + Args: + node (astroid.FunctionDef): function definition node to be analyzed. + + Returns: + bool: True if the function never returns, False otherwise. + """ + try: + return node.qname() in self._never_returning_functions + except TypeError: + return False + + def _check_return_at_the_end(self, node): + """Check for presence of a *single* return statement at the end of a + function. "return" or "return None" are useless because None is the + default return type if they are missing. + + NOTE: produces a message only if there is a single return statement + in the function body. Otherwise _check_consistent_returns() is called! + Per its implementation and PEP8 we can have a "return None" at the end + of the function body if there are other return statements before that! + """ + if len(self._return_nodes[node.name]) > 1: + return + if len(node.body) <= 1: + return + + last = node.body[-1] + if isinstance(last, astroid.Return): + # e.g. "return" + if last.value is None: + self.add_message("useless-return", node=node) + # return None" + elif isinstance(last.value, astroid.Const) and (last.value.value is None): + self.add_message("useless-return", node=node) + + +class RecommandationChecker(checkers.BaseChecker): + __implements__ = (interfaces.IAstroidChecker,) + name = "refactoring" + msgs = { + "C0200": ( + "Consider using enumerate instead of iterating with range and len", + "consider-using-enumerate", + "Emitted when code that iterates with range and len is " + "encountered. Such code can be simplified by using the " + "enumerate builtin.", + ), + "C0201": ( + "Consider iterating the dictionary directly instead of calling .keys()", + "consider-iterating-dictionary", + "Emitted when the keys of a dictionary are iterated through the .keys() " + "method. It is enough to just iterate through the dictionary itself, as " + 'in "for key in dictionary".', + ), + } + + @staticmethod + def _is_builtin(node, function): + inferred = utils.safe_infer(node) + if not inferred: + return False + return utils.is_builtin_object(inferred) and inferred.name == function + + @utils.check_messages("consider-iterating-dictionary") + def visit_call(self, node): + inferred = utils.safe_infer(node.func) + if not inferred: + return + if not isinstance(inferred, astroid.BoundMethod): + return + if not isinstance(inferred.bound, astroid.Dict) or inferred.name != "keys": + return + + if isinstance(node.parent, (astroid.For, astroid.Comprehension)): + self.add_message("consider-iterating-dictionary", node=node) + + @utils.check_messages("consider-using-enumerate") + def visit_for(self, node): + """Emit a convention whenever range and len are used for indexing.""" + # Verify that we have a `range([start], len(...), [stop])` call and + # that the object which is iterated is used as a subscript in the + # body of the for. + + # Is it a proper range call? + if not isinstance(node.iter, astroid.Call): + return + if not self._is_builtin(node.iter.func, "range"): + return + if len(node.iter.args) == 2 and not _is_constant_zero(node.iter.args[0]): + return + if len(node.iter.args) > 2: + return + + # Is it a proper len call? + if not isinstance(node.iter.args[-1], astroid.Call): + return + second_func = node.iter.args[-1].func + if not self._is_builtin(second_func, "len"): + return + len_args = node.iter.args[-1].args + if not len_args or len(len_args) != 1: + return + iterating_object = len_args[0] + if not isinstance(iterating_object, astroid.Name): + return + # If we're defining __iter__ on self, enumerate won't work + scope = node.scope() + if iterating_object.name == "self" and scope.name == "__iter__": + return + + # Verify that the body of the for loop uses a subscript + # with the object that was iterated. This uses some heuristics + # in order to make sure that the same object is used in the + # for body. + for child in node.body: + for subscript in child.nodes_of_class(astroid.Subscript): + if not isinstance(subscript.value, astroid.Name): + continue + if not isinstance(subscript.slice, astroid.Index): + continue + if not isinstance(subscript.slice.value, astroid.Name): + continue + if subscript.slice.value.name != node.target.name: + continue + if iterating_object.name != subscript.value.name: + continue + if subscript.value.scope() != node.scope(): + # Ignore this subscript if it's not in the same + # scope. This means that in the body of the for + # loop, another scope was created, where the same + # name for the iterating object was used. + continue + self.add_message("consider-using-enumerate", node=node) + return + + +class NotChecker(checkers.BaseChecker): + """checks for too many not in comparison expressions + + - "not not" should trigger a warning + - "not" followed by a comparison should trigger a warning + """ + + __implements__ = (interfaces.IAstroidChecker,) + msgs = { + "C0113": ( + 'Consider changing "%s" to "%s"', + "unneeded-not", + "Used when a boolean expression contains an unneeded negation.", + ) + } + name = "basic" + reverse_op = { + "<": ">=", + "<=": ">", + ">": "<=", + ">=": "<", + "==": "!=", + "!=": "==", + "in": "not in", + "is": "is not", + } + # sets are not ordered, so for example "not set(LEFT_VALS) <= set(RIGHT_VALS)" is + # not equivalent to "set(LEFT_VALS) > set(RIGHT_VALS)" + skipped_nodes = (astroid.Set,) + # 'builtins' py3, '__builtin__' py2 + skipped_classnames = [ + "%s.%s" % (builtins.__name__, qname) for qname in ("set", "frozenset") + ] + + @utils.check_messages("unneeded-not") + def visit_unaryop(self, node): + if node.op != "not": + return + operand = node.operand + + if isinstance(operand, astroid.UnaryOp) and operand.op == "not": + self.add_message( + "unneeded-not", + node=node, + args=(node.as_string(), operand.operand.as_string()), + ) + elif isinstance(operand, astroid.Compare): + left = operand.left + # ignore multiple comparisons + if len(operand.ops) > 1: + return + operator, right = operand.ops[0] + if operator not in self.reverse_op: + return + # Ignore __ne__ as function of __eq__ + frame = node.frame() + if frame.name == "__ne__" and operator == "==": + return + for _type in (utils.node_type(left), utils.node_type(right)): + if not _type: + return + if isinstance(_type, self.skipped_nodes): + return + if ( + isinstance(_type, astroid.Instance) + and _type.qname() in self.skipped_classnames + ): + return + suggestion = "%s %s %s" % ( + left.as_string(), + self.reverse_op[operator], + right.as_string(), + ) + self.add_message( + "unneeded-not", node=node, args=(node.as_string(), suggestion) + ) + + +def _is_len_call(node): + """Checks if node is len(SOMETHING).""" + return ( + isinstance(node, astroid.Call) + and isinstance(node.func, astroid.Name) + and node.func.name == "len" + ) + + +def _is_constant_zero(node): + return isinstance(node, astroid.Const) and node.value == 0 + + +def _has_constant_value(node, value): + return isinstance(node, astroid.Const) and node.value == value + + +def _node_is_test_condition(node): + """ Checks if node is an if, while, assert or if expression statement.""" + return isinstance(node, (astroid.If, astroid.While, astroid.Assert, astroid.IfExp)) + + +class LenChecker(checkers.BaseChecker): + """Checks for incorrect usage of len() inside conditions. + Pep8 states: + For sequences, (strings, lists, tuples), use the fact that empty sequences are false. + + Yes: if not seq: + if seq: + + No: if len(seq): + if not len(seq): + + Problems detected: + * if len(sequence): + * if not len(sequence): + * if len(sequence) == 0: + * if len(sequence) != 0: + * if len(sequence) > 0: + * if len(sequence) < 1: + * if len(sequence) <= 0: + """ + + __implements__ = (interfaces.IAstroidChecker,) + + # configuration section name + name = "len" + msgs = { + "C1801": ( + "Do not use `len(SEQUENCE)` to determine if a sequence is empty", + "len-as-condition", + "Used when Pylint detects that len(sequence) is being used inside " + "a condition to determine if a sequence is empty. Instead of " + "comparing the length to 0, rely on the fact that empty sequences " + "are false.", + ) + } + + priority = -2 + options = () + + @utils.check_messages("len-as-condition") + def visit_call(self, node): + # a len(S) call is used inside a test condition + # could be if, while, assert or if expression statement + # e.g. `if len(S):` + if _is_len_call(node): + # the len() call could also be nested together with other + # boolean operations, e.g. `if z or len(x):` + parent = node.parent + while isinstance(parent, astroid.BoolOp): + parent = parent.parent + + # we're finally out of any nested boolean operations so check if + # this len() call is part of a test condition + if not _node_is_test_condition(parent): + return + if not (node is parent.test or parent.test.parent_of(node)): + return + self.add_message("len-as-condition", node=node) + + @utils.check_messages("len-as-condition") + def visit_unaryop(self, node): + """`not len(S)` must become `not S` regardless if the parent block + is a test condition or something else (boolean expression) + e.g. `if not len(S):`""" + if ( + isinstance(node, astroid.UnaryOp) + and node.op == "not" + and _is_len_call(node.operand) + ): + self.add_message("len-as-condition", node=node) + + @utils.check_messages("len-as-condition") + def visit_compare(self, node): + # compare nodes are trickier because the len(S) expression + # may be somewhere in the middle of the node + + # note: astroid.Compare has the left most operand in node.left + # while the rest are a list of tuples in node.ops + # the format of the tuple is ('compare operator sign', node) + # here we squash everything into `ops` to make it easier for processing later + ops = [("", node.left)] + ops.extend(node.ops) + ops = list(itertools.chain(*ops)) + + for ops_idx in range(len(ops) - 2): + op_1 = ops[ops_idx] + op_2 = ops[ops_idx + 1] + op_3 = ops[ops_idx + 2] + error_detected = False + + # 0 ?? len() + if ( + _is_constant_zero(op_1) + and op_2 in ["==", "!=", "<", ">="] + and _is_len_call(op_3) + ): + error_detected = True + # len() ?? 0 + elif ( + _is_len_call(op_1) + and op_2 in ["==", "!=", ">", "<="] + and _is_constant_zero(op_3) + ): + error_detected = True + elif ( + _has_constant_value(op_1, value=1) + and op_2 == ">" + and _is_len_call(op_3) + ): + error_detected = True + elif ( + _is_len_call(op_1) + and op_2 == "<" + and _has_constant_value(op_3, value=1) + ): + error_detected = True + + if error_detected: + parent = node.parent + # traverse the AST to figure out if this comparison was part of + # a test condition + while parent and not _node_is_test_condition(parent): + parent = parent.parent + + # report only if this len() comparison is part of a test condition + # for example: return len() > 0 should not report anything + if _node_is_test_condition(parent): + self.add_message("len-as-condition", node=node) + + +def is_trailing_comma(tokens, index): + """Check if the given token is a trailing comma + + :param tokens: Sequence of modules tokens + :type tokens: list[tokenize.TokenInfo] + :param int index: Index of token under check in tokens + :returns: True if the token is a comma which trails an expression + :rtype: bool + """ + token = tokens[index] + if token.exact_type != tokenize.COMMA: + return False + # Must have remaining tokens on the same line such as NEWLINE + left_tokens = itertools.islice(tokens, index + 1, None) + same_line_remaining_tokens = list( + itertools.takewhile( + lambda other_token, _token=token: other_token.start[0] == _token.start[0], + left_tokens, + ) + ) + # Note: If the newline is tokenize.NEWLINE and not tokenize.NL + # then the newline denotes the end of expression + is_last_element = all( + other_token.type in (tokenize.NEWLINE, tokenize.COMMENT) + for other_token in same_line_remaining_tokens + ) + if not same_line_remaining_tokens or not is_last_element: + return False + + def get_curline_index_start(): + """Get the index denoting the start of the current line""" + for subindex, token in enumerate(reversed(tokens[:index])): + # See Lib/tokenize.py and Lib/token.py in cpython for more info + if token.type in (tokenize.NEWLINE, tokenize.NL): + return index - subindex + return 0 + + curline_start = get_curline_index_start() + expected_tokens = {"return", "yield"} + for prevtoken in tokens[curline_start:index]: + if "=" in prevtoken.string or prevtoken.string in expected_tokens: + return True + return False + + +def register(linter): + """Required method to auto register this checker.""" + linter.register_checker(RefactoringChecker(linter)) + linter.register_checker(NotChecker(linter)) + linter.register_checker(RecommandationChecker(linter)) + linter.register_checker(LenChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/similar.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/similar.py new file mode 100644 index 0000000..2e45ce9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/similar.py @@ -0,0 +1,449 @@ +# Copyright (c) 2006, 2008-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012 Ry4an Brase <ry4an-hg@ry4an.org> +# Copyright (c) 2012 Google, Inc. +# Copyright (c) 2012 Anthony VEREZ <anthony.verez.external@cassidian.com> +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2017 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2017 Mikhail Fesenko <proggga@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +# pylint: disable=W0622 +"""a similarities / code duplication command line tool and pylint checker +""" + +from __future__ import print_function +import sys +from collections import defaultdict +from itertools import groupby + +import astroid + +from pylint.utils import decoding_stream +from pylint.interfaces import IRawChecker +from pylint.checkers import BaseChecker, table_lines_from_stats +from pylint.reporters.ureports.nodes import Table + + +class Similar: + """finds copy-pasted lines of code in a project""" + + def __init__( + self, + min_lines=4, + ignore_comments=False, + ignore_docstrings=False, + ignore_imports=False, + ): + self.min_lines = min_lines + self.ignore_comments = ignore_comments + self.ignore_docstrings = ignore_docstrings + self.ignore_imports = ignore_imports + self.linesets = [] + + def append_stream(self, streamid, stream, encoding=None): + """append a file to search for similarities""" + if encoding is None: + readlines = stream.readlines + else: + readlines = decoding_stream(stream, encoding).readlines + try: + self.linesets.append( + LineSet( + streamid, + readlines(), + self.ignore_comments, + self.ignore_docstrings, + self.ignore_imports, + ) + ) + except UnicodeDecodeError: + pass + + def run(self): + """start looking for similarities and display results on stdout""" + self._display_sims(self._compute_sims()) + + def _compute_sims(self): + """compute similarities in appended files""" + no_duplicates = defaultdict(list) + for num, lineset1, idx1, lineset2, idx2 in self._iter_sims(): + duplicate = no_duplicates[num] + for couples in duplicate: + if (lineset1, idx1) in couples or (lineset2, idx2) in couples: + couples.add((lineset1, idx1)) + couples.add((lineset2, idx2)) + break + else: + duplicate.append({(lineset1, idx1), (lineset2, idx2)}) + sims = [] + for num, ensembles in no_duplicates.items(): + for couples in ensembles: + sims.append((num, couples)) + sims.sort() + sims.reverse() + return sims + + def _display_sims(self, sims): + """display computed similarities on stdout""" + nb_lignes_dupliquees = 0 + for num, couples in sims: + print() + print(num, "similar lines in", len(couples), "files") + couples = sorted(couples) + for lineset, idx in couples: + print("==%s:%s" % (lineset.name, idx)) + # pylint: disable=W0631 + for line in lineset._real_lines[idx : idx + num]: + print(" ", line.rstrip()) + nb_lignes_dupliquees += num * (len(couples) - 1) + nb_total_lignes = sum([len(lineset) for lineset in self.linesets]) + print( + "TOTAL lines=%s duplicates=%s percent=%.2f" + % ( + nb_total_lignes, + nb_lignes_dupliquees, + nb_lignes_dupliquees * 100. / nb_total_lignes, + ) + ) + + def _find_common(self, lineset1, lineset2): + """find similarities in the two given linesets""" + lines1 = lineset1.enumerate_stripped + lines2 = lineset2.enumerate_stripped + find = lineset2.find + index1 = 0 + min_lines = self.min_lines + while index1 < len(lineset1): + skip = 1 + num = 0 + for index2 in find(lineset1[index1]): + non_blank = 0 + for num, ((_, line1), (_, line2)) in enumerate( + zip(lines1(index1), lines2(index2)) + ): + if line1 != line2: + if non_blank > min_lines: + yield num, lineset1, index1, lineset2, index2 + skip = max(skip, num) + break + if line1: + non_blank += 1 + else: + # we may have reach the end + num += 1 + if non_blank > min_lines: + yield num, lineset1, index1, lineset2, index2 + skip = max(skip, num) + index1 += skip + + def _iter_sims(self): + """iterate on similarities among all files, by making a cartesian + product + """ + for idx, lineset in enumerate(self.linesets[:-1]): + for lineset2 in self.linesets[idx + 1 :]: + for sim in self._find_common(lineset, lineset2): + yield sim + + +def stripped_lines(lines, ignore_comments, ignore_docstrings, ignore_imports): + """return lines with leading/trailing whitespace and any ignored code + features removed + """ + if ignore_imports: + tree = astroid.parse("".join(lines)) + node_is_import_by_lineno = ( + (node.lineno, isinstance(node, (astroid.Import, astroid.ImportFrom))) + for node in tree.body + ) + line_begins_import = { + lineno: all(is_import for _, is_import in node_is_import_group) + for lineno, node_is_import_group in groupby( + node_is_import_by_lineno, key=lambda x: x[0] + ) + } + current_line_is_import = False + + strippedlines = [] + docstring = None + for lineno, line in enumerate(lines, start=1): + line = line.strip() + if ignore_docstrings: + if not docstring and (line.startswith('"""') or line.startswith("'''")): + docstring = line[:3] + line = line[3:] + if docstring: + if line.endswith(docstring): + docstring = None + line = "" + if ignore_imports: + current_line_is_import = line_begins_import.get( + lineno, current_line_is_import + ) + if current_line_is_import: + line = "" + if ignore_comments: + # XXX should use regex in checkers/format to avoid cutting + # at a "#" in a string + line = line.split("#", 1)[0].strip() + strippedlines.append(line) + return strippedlines + + +class LineSet: + """Holds and indexes all the lines of a single source file""" + + def __init__( + self, + name, + lines, + ignore_comments=False, + ignore_docstrings=False, + ignore_imports=False, + ): + self.name = name + self._real_lines = lines + self._stripped_lines = stripped_lines( + lines, ignore_comments, ignore_docstrings, ignore_imports + ) + self._index = self._mk_index() + + def __str__(self): + return "<Lineset for %s>" % self.name + + def __len__(self): + return len(self._real_lines) + + def __getitem__(self, index): + return self._stripped_lines[index] + + def __lt__(self, other): + return self.name < other.name + + def __hash__(self): + return id(self) + + def enumerate_stripped(self, start_at=0): + """return an iterator on stripped lines, starting from a given index + if specified, else 0 + """ + idx = start_at + if start_at: + lines = self._stripped_lines[start_at:] + else: + lines = self._stripped_lines + for line in lines: + # if line: + yield idx, line + idx += 1 + + def find(self, stripped_line): + """return positions of the given stripped line in this set""" + return self._index.get(stripped_line, ()) + + def _mk_index(self): + """create the index for this set""" + index = defaultdict(list) + for line_no, line in enumerate(self._stripped_lines): + if line: + index[line].append(line_no) + return index + + +MSGS = { + "R0801": ( + "Similar lines in %s files\n%s", + "duplicate-code", + "Indicates that a set of similar lines has been detected " + "among multiple file. This usually means that the code should " + "be refactored to avoid this duplication.", + ) +} + + +def report_similarities(sect, stats, old_stats): + """make a layout with some stats about duplication""" + lines = ["", "now", "previous", "difference"] + lines += table_lines_from_stats( + stats, old_stats, ("nb_duplicated_lines", "percent_duplicated_lines") + ) + sect.append(Table(children=lines, cols=4, rheaders=1, cheaders=1)) + + +# wrapper to get a pylint checker from the similar class +class SimilarChecker(BaseChecker, Similar): + """checks for similarities and duplicated code. This computation may be + memory / CPU intensive, so you should disable it if you experiment some + problems. + """ + + __implements__ = (IRawChecker,) + # configuration section name + name = "similarities" + # messages + msgs = MSGS + # configuration options + # for available dict keys/values see the optik parser 'add_option' method + options = ( + ( + "min-similarity-lines", # type: ignore + { + "default": 4, + "type": "int", + "metavar": "<int>", + "help": "Minimum lines number of a similarity.", + }, + ), + ( + "ignore-comments", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Ignore comments when computing similarities.", + }, + ), + ( + "ignore-docstrings", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Ignore docstrings when computing similarities.", + }, + ), + ( + "ignore-imports", + { + "default": False, + "type": "yn", + "metavar": "<y or n>", + "help": "Ignore imports when computing similarities.", + }, + ), + ) + # reports + reports = (("RP0801", "Duplication", report_similarities),) # type: ignore + + def __init__(self, linter=None): + BaseChecker.__init__(self, linter) + Similar.__init__( + self, min_lines=4, ignore_comments=True, ignore_docstrings=True + ) + self.stats = None + + def set_option(self, optname, value, action=None, optdict=None): + """method called to set an option (registered in the options list) + + overridden to report options setting to Similar + """ + BaseChecker.set_option(self, optname, value, action, optdict) + if optname == "min-similarity-lines": + self.min_lines = self.config.min_similarity_lines + elif optname == "ignore-comments": + self.ignore_comments = self.config.ignore_comments + elif optname == "ignore-docstrings": + self.ignore_docstrings = self.config.ignore_docstrings + elif optname == "ignore-imports": + self.ignore_imports = self.config.ignore_imports + + def open(self): + """init the checkers: reset linesets and statistics information""" + self.linesets = [] + self.stats = self.linter.add_stats( + nb_duplicated_lines=0, percent_duplicated_lines=0 + ) + + def process_module(self, node): + """process a module + + the module's content is accessible via the stream object + + stream must implement the readlines method + """ + with node.stream() as stream: + self.append_stream(self.linter.current_name, stream, node.file_encoding) + + def close(self): + """compute and display similarities on closing (i.e. end of parsing)""" + total = sum(len(lineset) for lineset in self.linesets) + duplicated = 0 + stats = self.stats + for num, couples in self._compute_sims(): + msg = [] + for lineset, idx in couples: + msg.append("==%s:%s" % (lineset.name, idx)) + msg.sort() + # pylint: disable=W0631 + for line in lineset._real_lines[idx : idx + num]: + msg.append(line.rstrip()) + self.add_message("R0801", args=(len(couples), "\n".join(msg))) + duplicated += num * (len(couples) - 1) + stats["nb_duplicated_lines"] = duplicated + stats["percent_duplicated_lines"] = total and duplicated * 100. / total + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(SimilarChecker(linter)) + + +def usage(status=0): + """display command line usage information""" + print("finds copy pasted blocks in a set of files") + print() + print( + "Usage: symilar [-d|--duplicates min_duplicated_lines] \ +[-i|--ignore-comments] [--ignore-docstrings] [--ignore-imports] file1..." + ) + sys.exit(status) + + +def Run(argv=None): + """standalone command line access point""" + if argv is None: + argv = sys.argv[1:] + from getopt import getopt + + s_opts = "hdi" + l_opts = ( + "help", + "duplicates=", + "ignore-comments", + "ignore-imports", + "ignore-docstrings", + ) + min_lines = 4 + ignore_comments = False + ignore_docstrings = False + ignore_imports = False + opts, args = getopt(argv, s_opts, l_opts) + for opt, val in opts: + if opt in ("-d", "--duplicates"): + min_lines = int(val) + elif opt in ("-h", "--help"): + usage() + elif opt in ("-i", "--ignore-comments"): + ignore_comments = True + elif opt in ("--ignore-docstrings",): + ignore_docstrings = True + elif opt in ("--ignore-imports",): + ignore_imports = True + if not args: + usage(1) + sim = Similar(min_lines, ignore_comments, ignore_docstrings, ignore_imports) + for filename in args: + with open(filename) as stream: + sim.append_stream(filename, stream) + sim.run() + sys.exit(0) + + +if __name__ == "__main__": + Run() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/spelling.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/spelling.py new file mode 100644 index 0000000..df99f6b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/spelling.py @@ -0,0 +1,403 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2015 Pavel Roskin <proski@gnu.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016-2017 Pedro Algarvio <pedro@algarvio.me> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Mikhail Fesenko <proggga@gmail.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Checker for spelling errors in comments and docstrings. +""" + +import os +import tokenize +import re + +try: + import enchant + from enchant.tokenize import ( # type: ignore + get_tokenizer, + Chunker, + Filter, + EmailFilter, + URLFilter, + WikiWordFilter, + ) +except ImportError: + enchant = None + # pylint: disable=no-init + class Filter: # type: ignore + def _skip(self, word): + raise NotImplementedError + + class Chunker: # type: ignore + pass + + +from pylint.interfaces import ITokenChecker, IAstroidChecker +from pylint.checkers import BaseTokenChecker +from pylint.checkers.utils import check_messages + +if enchant is not None: + br = enchant.Broker() + dicts = br.list_dicts() + dict_choices = [""] + [d[0] for d in dicts] + dicts = ["%s (%s)" % (d[0], d[1].name) for d in dicts] + dicts = ", ".join(dicts) + instr = "" +else: + dicts = "none" + dict_choices = [""] + instr = " To make it working install python-enchant package." + + +class WordsWithDigigtsFilter(Filter): + """Skips words with digits. + """ + + def _skip(self, word): + for char in word: + if char.isdigit(): + return True + return False + + +class WordsWithUnderscores(Filter): + """Skips words with underscores. + + They are probably function parameter names. + """ + + def _skip(self, word): + return "_" in word + + +class CamelCasedWord(Filter): + r"""Filter skipping over camelCasedWords. + This filter skips any words matching the following regular expression: + + ^([a-z]\w+[A-Z]+\w+) + + That is, any words that are camelCasedWords. + """ + _pattern = re.compile(r"^([a-z]+([\d]|[A-Z])(?:\w+)?)") + + def _skip(self, word): + return bool(self._pattern.match(word)) + + +class SphinxDirectives(Filter): + r"""Filter skipping over Sphinx Directives. + This filter skips any words matching the following regular expression: + + ^:([a-z]+):`([^`]+)(`)? + + That is, for example, :class:`BaseQuery` + """ + # The final ` in the pattern is optional because enchant strips it out + _pattern = re.compile(r"^:([a-z]+):`([^`]+)(`)?") + + def _skip(self, word): + return bool(self._pattern.match(word)) + + +class ForwardSlashChunkder(Chunker): + """ + This chunker allows splitting words like 'before/after' into 'before' and 'after' + """ + + def next(self): + while True: + if not self._text: + raise StopIteration() + if "/" not in self._text: + text = self._text + self._offset = 0 + self._text = "" + return (text, 0) + pre_text, post_text = self._text.split("/", 1) + self._text = post_text + self._offset = 0 + if ( + not pre_text + or not post_text + or not pre_text[-1].isalpha() + or not post_text[0].isalpha() + ): + self._text = "" + self._offset = 0 + return (pre_text + "/" + post_text, 0) + return (pre_text, 0) + + def _next(self): + while True: + if "/" not in self._text: + return (self._text, 0) + pre_text, post_text = self._text.split("/", 1) + if not pre_text or not post_text: + break + if not pre_text[-1].isalpha() or not post_text[0].isalpha(): + raise StopIteration() + self._text = pre_text + " " + post_text + raise StopIteration() + + +class SpellingChecker(BaseTokenChecker): + """Check spelling in comments and docstrings""" + + __implements__ = (ITokenChecker, IAstroidChecker) + name = "spelling" + msgs = { + "C0401": ( + "Wrong spelling of a word '%s' in a comment:\n%s\n" + "%s\nDid you mean: '%s'?", + "wrong-spelling-in-comment", + "Used when a word in comment is not spelled correctly.", + ), + "C0402": ( + "Wrong spelling of a word '%s' in a docstring:\n%s\n" + "%s\nDid you mean: '%s'?", + "wrong-spelling-in-docstring", + "Used when a word in docstring is not spelled correctly.", + ), + "C0403": ( + "Invalid characters %r in a docstring", + "invalid-characters-in-docstring", + "Used when a word in docstring cannot be checked by enchant.", + ), + } + options = ( + ( + "spelling-dict", + { + "default": "", + "type": "choice", + "metavar": "<dict name>", + "choices": dict_choices, + "help": "Spelling dictionary name. " + "Available dictionaries: %s.%s." % (dicts, instr), + }, + ), + ( + "spelling-ignore-words", + { + "default": "", + "type": "string", + "metavar": "<comma separated words>", + "help": "List of comma separated words that " "should not be checked.", + }, + ), + ( + "spelling-private-dict-file", + { + "default": "", + "type": "string", + "metavar": "<path to file>", + "help": "A path to a file that contains private " + "dictionary; one word per line.", + }, + ), + ( + "spelling-store-unknown-words", + { + "default": "n", + "type": "yn", + "metavar": "<y_or_n>", + "help": "Tells whether to store unknown words to " + "indicated private dictionary in " + "--spelling-private-dict-file option instead of " + "raising a message.", + }, + ), + ( + "max-spelling-suggestions", + { + "default": 4, + "type": "int", + "metavar": "N", + "help": "Limits count of emitted suggestions for " "spelling mistakes.", + }, + ), + ) + + def open(self): + self.initialized = False + self.private_dict_file = None + + if enchant is None: + return + dict_name = self.config.spelling_dict + if not dict_name: + return + + self.ignore_list = [ + w.strip() for w in self.config.spelling_ignore_words.split(",") + ] + # "param" appears in docstring in param description and + # "pylint" appears in comments in pylint pragmas. + self.ignore_list.extend(["param", "pylint"]) + + # Expand tilde to allow e.g. spelling-private-dict-file = ~/.pylintdict + if self.config.spelling_private_dict_file: + self.config.spelling_private_dict_file = os.path.expanduser( + self.config.spelling_private_dict_file + ) + + if self.config.spelling_private_dict_file: + self.spelling_dict = enchant.DictWithPWL( + dict_name, self.config.spelling_private_dict_file + ) + self.private_dict_file = open(self.config.spelling_private_dict_file, "a") + else: + self.spelling_dict = enchant.Dict(dict_name) + + if self.config.spelling_store_unknown_words: + self.unknown_words = set() + + self.tokenizer = get_tokenizer( + dict_name, + chunkers=[ForwardSlashChunkder], + filters=[ + EmailFilter, + URLFilter, + WikiWordFilter, + WordsWithDigigtsFilter, + WordsWithUnderscores, + CamelCasedWord, + SphinxDirectives, + ], + ) + self.initialized = True + + def close(self): + if self.private_dict_file: + self.private_dict_file.close() + + def _check_spelling(self, msgid, line, line_num): + original_line = line + if line.strip().startswith("#"): + line = line.strip()[1:] + starts_with_comment = True + else: + starts_with_comment = False + for word, _ in self.tokenizer(line.strip()): + lower_cased_word = word.casefold() + + # Skip words from ignore list. + if word in self.ignore_list or lower_cased_word in self.ignore_list: + continue + + # Strip starting u' from unicode literals and r' from raw strings. + if word.startswith(("u'", 'u"', "r'", 'r"')) and len(word) > 2: + word = word[2:] + lower_cased_word = lower_cased_word[2:] + + # If it is a known word, then continue. + try: + if self.spelling_dict.check(lower_cased_word): + # The lower cased version of word passed spell checking + continue + + # If we reached this far, it means there was a spelling mistake. + # Let's retry with the original work because 'unicode' is a + # spelling mistake but 'Unicode' is not + if self.spelling_dict.check(word): + continue + except enchant.errors.Error: + self.add_message( + "invalid-characters-in-docstring", line=line_num, args=(word,) + ) + continue + + # Store word to private dict or raise a message. + if self.config.spelling_store_unknown_words: + if lower_cased_word not in self.unknown_words: + self.private_dict_file.write("%s\n" % lower_cased_word) + self.unknown_words.add(lower_cased_word) + else: + # Present up to N suggestions. + suggestions = self.spelling_dict.suggest(word) + del suggestions[self.config.max_spelling_suggestions :] + + m = re.search(r"(\W|^)(%s)(\W|$)" % word, line) + if m: + # Start position of second group in regex. + col = m.regs[2][0] + else: + col = line.index(word) + + if starts_with_comment: + col += 1 + indicator = (" " * col) + ("^" * len(word)) + + self.add_message( + msgid, + line=line_num, + args=( + word, + original_line, + indicator, + "'{}'".format("' or '".join(suggestions)), + ), + ) + + def process_tokens(self, tokens): + if not self.initialized: + return + + # Process tokens and look for comments. + for (tok_type, token, (start_row, _), _, _) in tokens: + if tok_type == tokenize.COMMENT: + if start_row == 1 and token.startswith("#!/"): + # Skip shebang lines + continue + if token.startswith("# pylint:"): + # Skip pylint enable/disable comments + continue + self._check_spelling("wrong-spelling-in-comment", token, start_row) + + @check_messages("wrong-spelling-in-docstring") + def visit_module(self, node): + if not self.initialized: + return + self._check_docstring(node) + + @check_messages("wrong-spelling-in-docstring") + def visit_classdef(self, node): + if not self.initialized: + return + self._check_docstring(node) + + @check_messages("wrong-spelling-in-docstring") + def visit_functiondef(self, node): + if not self.initialized: + return + self._check_docstring(node) + + visit_asyncfunctiondef = visit_functiondef + + def _check_docstring(self, node): + """check the node has any spelling errors""" + docstring = node.doc + if not docstring: + return + + start_line = node.lineno + 1 + + # Go through lines of docstring + for idx, line in enumerate(docstring.splitlines()): + self._check_spelling("wrong-spelling-in-docstring", line, start_line + idx) + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(SpellingChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/stdlib.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/stdlib.py new file mode 100644 index 0000000..7dad31d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/stdlib.py @@ -0,0 +1,441 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Cosmin Poieana <cmin@ropython.org> +# Copyright (c) 2014 Vlad Temian <vladtemian@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Cezar <celnazli@bitdefender.com> +# Copyright (c) 2015 Chris Rebert <code@rebertia.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Jared Garst <cultofjared@gmail.com> +# Copyright (c) 2017 Renat Galimov <renat2017@gmail.com> +# Copyright (c) 2017 Martin <MartinBasti@users.noreply.github.com> +# Copyright (c) 2017 Christopher Zurcher <zurcher@users.noreply.github.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 Banjamin Freeman <befreeman@users.noreply.github.com> +# Copyright (c) 2018 Ioana Tagirta <ioana.tagirta@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Checkers for various standard library functions.""" + +import sys + +import astroid +from astroid.bases import Instance +from astroid.node_classes import Const +from pylint.interfaces import IAstroidChecker +from pylint.checkers import BaseChecker +from pylint.checkers import utils + + +OPEN_FILES = {"open", "file"} +UNITTEST_CASE = "unittest.case" +THREADING_THREAD = "threading.Thread" +COPY_COPY = "copy.copy" +OS_ENVIRON = "os._Environ" +ENV_GETTERS = {"os.getenv"} +SUBPROCESS_POPEN = "subprocess.Popen" + +if sys.version_info >= (3, 0): + OPEN_MODULE = "_io" +else: + OPEN_MODULE = "__builtin__" + + +def _check_mode_str(mode): + # check type + if not isinstance(mode, str): + return False + # check syntax + modes = set(mode) + _mode = "rwatb+Ux" + creating = "x" in modes + if modes - set(_mode) or len(mode) > len(modes): + return False + # check logic + reading = "r" in modes + writing = "w" in modes + appending = "a" in modes + text = "t" in modes + binary = "b" in modes + if "U" in modes: + if writing or appending or creating: + return False + reading = True + if text and binary: + return False + total = reading + writing + appending + creating + if total > 1: + return False + if not (reading or writing or appending or creating): + return False + return True + + +class StdlibChecker(BaseChecker): + __implements__ = (IAstroidChecker,) + name = "stdlib" + + msgs = { + "W1501": ( + '"%s" is not a valid mode for open.', + "bad-open-mode", + "Python supports: r, w, a[, x] modes with b, +, " + "and U (only with r) options. " + "See http://docs.python.org/2/library/functions.html#open", + ), + "W1502": ( + "Using datetime.time in a boolean context.", + "boolean-datetime", + "Using datetime.time in a boolean context can hide " + "subtle bugs when the time they represent matches " + "midnight UTC. This behaviour was fixed in Python 3.5. " + "See http://bugs.python.org/issue13936 for reference.", + {"maxversion": (3, 5)}, + ), + "W1503": ( + "Redundant use of %s with constant value %r", + "redundant-unittest-assert", + "The first argument of assertTrue and assertFalse is " + "a condition. If a constant is passed as parameter, that " + "condition will be always true. In this case a warning " + "should be emitted.", + ), + "W1505": ( + "Using deprecated method %s()", + "deprecated-method", + "The method is marked as deprecated and will be removed in " + "a future version of Python. Consider looking for an " + "alternative in the documentation.", + ), + "W1506": ( + "threading.Thread needs the target function", + "bad-thread-instantiation", + "The warning is emitted when a threading.Thread class " + "is instantiated without the target function being passed. " + "By default, the first parameter is the group param, not the target param. ", + ), + "W1507": ( + "Using copy.copy(os.environ). Use os.environ.copy() instead. ", + "shallow-copy-environ", + "os.environ is not a dict object but proxy object, so " + "shallow copy has still effects on original object. " + "See https://bugs.python.org/issue15373 for reference. ", + ), + "E1507": ( + "%s does not support %s type argument", + "invalid-envvar-value", + "Env manipulation functions support only string type arguments. " + "See https://docs.python.org/3/library/os.html#os.getenv. ", + ), + "W1508": ( + "%s default type is %s. Expected str or None.", + "invalid-envvar-default", + "Env manipulation functions return None or str values. " + "Supplying anything different as a default may cause bugs. " + "See https://docs.python.org/3/library/os.html#os.getenv. ", + ), + "W1509": ( + "Using preexec_fn keyword which may be unsafe in the presence " + "of threads", + "subprocess-popen-preexec-fn", + "The preexec_fn parameter is not safe to use in the presence " + "of threads in your application. The child process could " + "deadlock before exec is called. If you must use it, keep it " + "trivial! Minimize the number of libraries you call into." + "https://docs.python.org/3/library/subprocess.html#popen-constructor", + ), + } + + deprecated = { + 0: { + "cgi.parse_qs", + "cgi.parse_qsl", + "ctypes.c_buffer", + "distutils.command.register.register.check_metadata", + "distutils.command.sdist.sdist.check_metadata", + "tkinter.Misc.tk_menuBar", + "tkinter.Menu.tk_bindForTraversal", + }, + 2: { + (2, 6, 0): { + "commands.getstatus", + "os.popen2", + "os.popen3", + "os.popen4", + "macostools.touched", + }, + (2, 7, 0): { + "unittest.case.TestCase.assertEquals", + "unittest.case.TestCase.assertNotEquals", + "unittest.case.TestCase.assertAlmostEquals", + "unittest.case.TestCase.assertNotAlmostEquals", + "unittest.case.TestCase.assert_", + "xml.etree.ElementTree.Element.getchildren", + "xml.etree.ElementTree.Element.getiterator", + "xml.etree.ElementTree.XMLParser.getiterator", + "xml.etree.ElementTree.XMLParser.doctype", + }, + }, + 3: { + (3, 0, 0): { + "inspect.getargspec", + "failUnlessEqual", + "assertEquals", + "failIfEqual", + "assertNotEquals", + "failUnlessAlmostEqual", + "assertAlmostEquals", + "failIfAlmostEqual", + "assertNotAlmostEquals", + "failUnless", + "assert_", + "failUnlessRaises", + "failIf", + "assertRaisesRegexp", + "assertRegexpMatches", + "assertNotRegexpMatches", + }, + (3, 1, 0): { + "base64.encodestring", + "base64.decodestring", + "ntpath.splitunc", + }, + (3, 2, 0): { + "cgi.escape", + "configparser.RawConfigParser.readfp", + "xml.etree.ElementTree.Element.getchildren", + "xml.etree.ElementTree.Element.getiterator", + "xml.etree.ElementTree.XMLParser.getiterator", + "xml.etree.ElementTree.XMLParser.doctype", + }, + (3, 3, 0): { + "inspect.getmoduleinfo", + "logging.warn", + "logging.Logger.warn", + "logging.LoggerAdapter.warn", + "nntplib._NNTPBase.xpath", + "platform.popen", + }, + (3, 4, 0): { + "importlib.find_loader", + "plistlib.readPlist", + "plistlib.writePlist", + "plistlib.readPlistFromBytes", + "plistlib.writePlistToBytes", + }, + (3, 4, 4): {"asyncio.tasks.async"}, + (3, 5, 0): { + "fractions.gcd", + "inspect.getargvalues", + "inspect.formatargspec", + "inspect.formatargvalues", + "inspect.getcallargs", + "platform.linux_distribution", + "platform.dist", + }, + (3, 6, 0): {"importlib._bootstrap_external.FileLoader.load_module"}, + }, + } + + def _check_bad_thread_instantiation(self, node): + if not node.kwargs and not node.keywords and len(node.args) <= 1: + self.add_message("bad-thread-instantiation", node=node) + + def _check_for_preexec_fn_in_Popen(self, node): + if node.keywords: + for keyword in node.keywords: + if keyword.arg == "preexec_fn": + self.add_message("subprocess-popen-preexec-fn", node=node) + + def _check_shallow_copy_environ(self, node): + arg = utils.get_argument_from_call(node, position=0) + for inferred in arg.inferred(): + if inferred.qname() == OS_ENVIRON: + self.add_message("shallow-copy-environ", node=node) + break + + @utils.check_messages( + "bad-open-mode", + "redundant-unittest-assert", + "deprecated-method", + "bad-thread-instantiation", + "shallow-copy-environ", + "invalid-envvar-value", + "invalid-envvar-default", + "subprocess-popen-preexec-fn", + ) + def visit_call(self, node): + """Visit a Call node.""" + try: + for inferred in node.func.infer(): + if inferred is astroid.Uninferable: + continue + elif inferred.root().name == OPEN_MODULE: + if getattr(node.func, "name", None) in OPEN_FILES: + self._check_open_mode(node) + elif inferred.root().name == UNITTEST_CASE: + self._check_redundant_assert(node, inferred) + elif isinstance(inferred, astroid.ClassDef): + if inferred.qname() == THREADING_THREAD: + self._check_bad_thread_instantiation(node) + elif inferred.qname() == SUBPROCESS_POPEN: + self._check_for_preexec_fn_in_Popen(node) + elif isinstance(inferred, astroid.FunctionDef): + name = inferred.qname() + if name == COPY_COPY: + self._check_shallow_copy_environ(node) + elif name in ENV_GETTERS: + self._check_env_function(node, inferred) + self._check_deprecated_method(node, inferred) + except astroid.InferenceError: + return + + @utils.check_messages("boolean-datetime") + def visit_unaryop(self, node): + if node.op == "not": + self._check_datetime(node.operand) + + @utils.check_messages("boolean-datetime") + def visit_if(self, node): + self._check_datetime(node.test) + + @utils.check_messages("boolean-datetime") + def visit_ifexp(self, node): + self._check_datetime(node.test) + + @utils.check_messages("boolean-datetime") + def visit_boolop(self, node): + for value in node.values: + self._check_datetime(value) + + def _check_deprecated_method(self, node, inferred): + py_vers = sys.version_info[0] + + if isinstance(node.func, astroid.Attribute): + func_name = node.func.attrname + elif isinstance(node.func, astroid.Name): + func_name = node.func.name + else: + # Not interested in other nodes. + return + + # Reject nodes which aren't of interest to us. + acceptable_nodes = ( + astroid.BoundMethod, + astroid.UnboundMethod, + astroid.FunctionDef, + ) + if not isinstance(inferred, acceptable_nodes): + return + + qname = inferred.qname() + if any(name in self.deprecated[0] for name in (qname, func_name)): + self.add_message("deprecated-method", node=node, args=(func_name,)) + else: + for since_vers, func_list in self.deprecated[py_vers].items(): + if since_vers <= sys.version_info and any( + name in func_list for name in (qname, func_name) + ): + self.add_message("deprecated-method", node=node, args=(func_name,)) + break + + def _check_redundant_assert(self, node, infer): + if ( + isinstance(infer, astroid.BoundMethod) + and node.args + and isinstance(node.args[0], astroid.Const) + and infer.name in ["assertTrue", "assertFalse"] + ): + self.add_message( + "redundant-unittest-assert", + args=(infer.name, node.args[0].value), + node=node, + ) + + def _check_datetime(self, node): + """ Check that a datetime was infered. + If so, emit boolean-datetime warning. + """ + try: + infered = next(node.infer()) + except astroid.InferenceError: + return + if isinstance(infered, Instance) and infered.qname() == "datetime.time": + self.add_message("boolean-datetime", node=node) + + def _check_open_mode(self, node): + """Check that the mode argument of an open or file call is valid.""" + try: + mode_arg = utils.get_argument_from_call(node, position=1, keyword="mode") + except utils.NoSuchArgumentError: + return + if mode_arg: + mode_arg = utils.safe_infer(mode_arg) + if isinstance(mode_arg, astroid.Const) and not _check_mode_str( + mode_arg.value + ): + self.add_message("bad-open-mode", node=node, args=mode_arg.value) + + def _check_env_function(self, node, infer): + env_name_kwarg = "key" + env_value_kwarg = "default" + if node.keywords: + kwargs = {keyword.arg: keyword.value for keyword in node.keywords} + else: + kwargs = None + if node.args: + env_name_arg = node.args[0] + elif kwargs and env_name_kwarg in kwargs: + env_name_arg = kwargs[env_name_kwarg] + else: + env_name_arg = None + + if env_name_arg: + self._check_invalid_envvar_value( + node=node, + message="invalid-envvar-value", + call_arg=utils.safe_infer(env_name_arg), + infer=infer, + allow_none=False, + ) + + if len(node.args) == 2: + env_value_arg = node.args[1] + elif kwargs and env_value_kwarg in kwargs: + env_value_arg = kwargs[env_value_kwarg] + else: + env_value_arg = None + + if env_value_arg: + self._check_invalid_envvar_value( + node=node, + infer=infer, + message="invalid-envvar-default", + call_arg=utils.safe_infer(env_value_arg), + allow_none=True, + ) + + def _check_invalid_envvar_value(self, node, infer, message, call_arg, allow_none): + if call_arg in (astroid.Uninferable, None): + return + + name = infer.qname() + if isinstance(call_arg, Const): + emit = False + if call_arg.value is None: + emit = not allow_none + elif not isinstance(call_arg.value, str): + emit = True + if emit: + self.add_message(message, node=node, args=(name, call_arg.pytype())) + else: + self.add_message(message, node=node, args=(name, call_arg.pytype())) + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(StdlibChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/strings.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/strings.py new file mode 100644 index 0000000..92dcbbe --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/strings.py @@ -0,0 +1,739 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009 Charles Hebert <charles.hebert@logilab.fr> +# Copyright (c) 2010-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2010 Daniel Harding <dharding@gmail.com> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2013-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Rene Zhang <rz99@cornell.edu> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016, 2018 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2016 Peter Dawyndt <Peter.Dawyndt@UGent.be> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Checker for string formatting operations. +""" + +import builtins +import sys +import tokenize +import numbers +from collections import Counter + +import astroid +from astroid.arguments import CallSite +from astroid.node_classes import Const +from pylint.interfaces import ITokenChecker, IAstroidChecker, IRawChecker +from pylint.checkers import BaseChecker, BaseTokenChecker +from pylint.checkers import utils +from pylint.checkers.utils import check_messages + +_AST_NODE_STR_TYPES = ("__builtin__.unicode", "__builtin__.str", "builtins.str") + +_PY3K = sys.version_info[:2] >= (3, 0) +_PY27 = sys.version_info[:2] == (2, 7) + +MSGS = { + "E1300": ( + "Unsupported format character %r (%#02x) at index %d", + "bad-format-character", + "Used when an unsupported format character is used in a format string.", + ), + "E1301": ( + "Format string ends in middle of conversion specifier", + "truncated-format-string", + "Used when a format string terminates before the end of a " + "conversion specifier.", + ), + "E1302": ( + "Mixing named and unnamed conversion specifiers in format string", + "mixed-format-string", + "Used when a format string contains both named (e.g. '%(foo)d') " + "and unnamed (e.g. '%d') conversion specifiers. This is also " + "used when a named conversion specifier contains * for the " + "minimum field width and/or precision.", + ), + "E1303": ( + "Expected mapping for format string, not %s", + "format-needs-mapping", + "Used when a format string that uses named conversion specifiers " + "is used with an argument that is not a mapping.", + ), + "W1300": ( + "Format string dictionary key should be a string, not %s", + "bad-format-string-key", + "Used when a format string that uses named conversion specifiers " + "is used with a dictionary whose keys are not all strings.", + ), + "W1301": ( + "Unused key %r in format string dictionary", + "unused-format-string-key", + "Used when a format string that uses named conversion specifiers " + "is used with a dictionary that contains keys not required by the " + "format string.", + ), + "E1304": ( + "Missing key %r in format string dictionary", + "missing-format-string-key", + "Used when a format string that uses named conversion specifiers " + "is used with a dictionary that doesn't contain all the keys " + "required by the format string.", + ), + "E1305": ( + "Too many arguments for format string", + "too-many-format-args", + "Used when a format string that uses unnamed conversion " + "specifiers is given too many arguments.", + ), + "E1306": ( + "Not enough arguments for format string", + "too-few-format-args", + "Used when a format string that uses unnamed conversion " + "specifiers is given too few arguments", + ), + "E1307": ( + "Argument %r does not match format type %r", + "bad-string-format-type", + "Used when a type required by format string " + "is not suitable for actual argument type", + ), + "E1310": ( + "Suspicious argument in %s.%s call", + "bad-str-strip-call", + "The argument to a str.{l,r,}strip call contains a duplicate character, ", + ), + "W1302": ( + "Invalid format string", + "bad-format-string", + "Used when a PEP 3101 format string is invalid.", + ), + "W1303": ( + "Missing keyword argument %r for format string", + "missing-format-argument-key", + "Used when a PEP 3101 format string that uses named fields " + "doesn't receive one or more required keywords.", + ), + "W1304": ( + "Unused format argument %r", + "unused-format-string-argument", + "Used when a PEP 3101 format string that uses named " + "fields is used with an argument that " + "is not required by the format string.", + ), + "W1305": ( + "Format string contains both automatic field numbering " + "and manual field specification", + "format-combined-specification", + "Used when a PEP 3101 format string contains both automatic " + "field numbering (e.g. '{}') and manual field " + "specification (e.g. '{0}').", + ), + "W1306": ( + "Missing format attribute %r in format specifier %r", + "missing-format-attribute", + "Used when a PEP 3101 format string uses an " + "attribute specifier ({0.length}), but the argument " + "passed for formatting doesn't have that attribute.", + ), + "W1307": ( + "Using invalid lookup key %r in format specifier %r", + "invalid-format-index", + "Used when a PEP 3101 format string uses a lookup specifier " + "({a[1]}), but the argument passed for formatting " + "doesn't contain or doesn't have that key as an attribute.", + ), + "W1308": ( + "Duplicate string formatting argument %r, consider passing as named argument", + "duplicate-string-formatting-argument", + "Used when we detect that a string formatting is " + "repeating an argument instead of using named string arguments", + ), +} + +OTHER_NODES = ( + astroid.Const, + astroid.List, + astroid.Lambda, + astroid.FunctionDef, + astroid.ListComp, + astroid.SetComp, + astroid.GeneratorExp, +) + +BUILTINS_STR = builtins.__name__ + ".str" +BUILTINS_FLOAT = builtins.__name__ + ".float" +BUILTINS_INT = builtins.__name__ + ".int" + + +def get_access_path(key, parts): + """ Given a list of format specifiers, returns + the final access path (e.g. a.b.c[0][1]). + """ + path = [] + for is_attribute, specifier in parts: + if is_attribute: + path.append(".{}".format(specifier)) + else: + path.append("[{!r}]".format(specifier)) + return str(key) + "".join(path) + + +def arg_matches_format_type(arg_type, format_type): + if format_type in "sr": + # All types can be printed with %s and %r + return True + if isinstance(arg_type, astroid.Instance): + arg_type = arg_type.pytype() + if arg_type == BUILTINS_STR: + return format_type == "c" + if arg_type == BUILTINS_FLOAT: + return format_type in "deEfFgGn%" + if arg_type == BUILTINS_INT: + # Integers allow all types + return True + return False + return True + + +class StringFormatChecker(BaseChecker): + """Checks string formatting operations to ensure that the format string + is valid and the arguments match the format string. + """ + + __implements__ = (IAstroidChecker,) + name = "string" + msgs = MSGS + + # pylint: disable=too-many-branches + @check_messages(*MSGS) + def visit_binop(self, node): + if node.op != "%": + return + left = node.left + args = node.right + + if not (isinstance(left, astroid.Const) and isinstance(left.value, str)): + return + format_string = left.value + try: + required_keys, required_num_args, required_key_types, required_arg_types = utils.parse_format_string( + format_string + ) + except utils.UnsupportedFormatCharacter as e: + c = format_string[e.index] + self.add_message( + "bad-format-character", node=node, args=(c, ord(c), e.index) + ) + return + except utils.IncompleteFormatString: + self.add_message("truncated-format-string", node=node) + return + if required_keys and required_num_args: + # The format string uses both named and unnamed format + # specifiers. + self.add_message("mixed-format-string", node=node) + elif required_keys: + # The format string uses only named format specifiers. + # Check that the RHS of the % operator is a mapping object + # that contains precisely the set of keys required by the + # format string. + if isinstance(args, astroid.Dict): + keys = set() + unknown_keys = False + for k, _ in args.items: + if isinstance(k, astroid.Const): + key = k.value + if isinstance(key, str): + keys.add(key) + else: + self.add_message( + "bad-format-string-key", node=node, args=key + ) + else: + # One of the keys was something other than a + # constant. Since we can't tell what it is, + # suppress checks for missing keys in the + # dictionary. + unknown_keys = True + if not unknown_keys: + for key in required_keys: + if key not in keys: + self.add_message( + "missing-format-string-key", node=node, args=key + ) + for key in keys: + if key not in required_keys: + self.add_message( + "unused-format-string-key", node=node, args=key + ) + for key, arg in args.items: + if not isinstance(key, astroid.Const): + continue + format_type = required_key_types.get(key.value, None) + arg_type = utils.safe_infer(arg) + if ( + format_type is not None + and arg_type not in (None, astroid.Uninferable) + and not arg_matches_format_type(arg_type, format_type) + ): + self.add_message( + "bad-string-format-type", + node=node, + args=(arg_type.pytype(), format_type), + ) + elif isinstance(args, (OTHER_NODES, astroid.Tuple)): + type_name = type(args).__name__ + self.add_message("format-needs-mapping", node=node, args=type_name) + # else: + # The RHS of the format specifier is a name or + # expression. It may be a mapping object, so + # there's nothing we can check. + else: + # The format string uses only unnamed format specifiers. + # Check that the number of arguments passed to the RHS of + # the % operator matches the number required by the format + # string. + args_elts = () + if isinstance(args, astroid.Tuple): + rhs_tuple = utils.safe_infer(args) + num_args = None + if hasattr(rhs_tuple, "elts"): + args_elts = rhs_tuple.elts + num_args = len(args_elts) + elif isinstance(args, (OTHER_NODES, (astroid.Dict, astroid.DictComp))): + args_elts = [args] + num_args = 1 + else: + # The RHS of the format specifier is a name or + # expression. It could be a tuple of unknown size, so + # there's nothing we can check. + num_args = None + if num_args is not None: + if num_args > required_num_args: + self.add_message("too-many-format-args", node=node) + elif num_args < required_num_args: + self.add_message("too-few-format-args", node=node) + for arg, format_type in zip(args_elts, required_arg_types): + arg_type = utils.safe_infer(arg) + if arg_type not in ( + None, + astroid.Uninferable, + ) and not arg_matches_format_type(arg_type, format_type): + self.add_message( + "bad-string-format-type", + node=node, + args=(arg_type.pytype(), format_type), + ) + + @check_messages(*MSGS) + def visit_call(self, node): + func = utils.safe_infer(node.func) + if ( + isinstance(func, astroid.BoundMethod) + and isinstance(func.bound, astroid.Instance) + and func.bound.name in ("str", "unicode", "bytes") + ): + if func.name in ("strip", "lstrip", "rstrip") and node.args: + arg = utils.safe_infer(node.args[0]) + if not isinstance(arg, astroid.Const): + return + if len(arg.value) != len(set(arg.value)): + self.add_message( + "bad-str-strip-call", + node=node, + args=(func.bound.name, func.name), + ) + elif func.name == "format": + self._check_new_format(node, func) + + def _detect_vacuous_formatting(self, node, positional_arguments): + counter = Counter( + arg.name for arg in positional_arguments if isinstance(arg, astroid.Name) + ) + for name, count in counter.items(): + if count == 1: + continue + self.add_message( + "duplicate-string-formatting-argument", node=node, args=(name,) + ) + + def _check_new_format(self, node, func): + """ Check the new string formatting. """ + # TODO: skip (for now) format nodes which don't have + # an explicit string on the left side of the format operation. + # We do this because our inference engine can't properly handle + # redefinitions of the original string. + # For more details, see issue 287. + # + # Note that there may not be any left side at all, if the format method + # has been assigned to another variable. See issue 351. For example: + # + # fmt = 'some string {}'.format + # fmt('arg') + if isinstance(node.func, astroid.Attribute) and not isinstance( + node.func.expr, astroid.Const + ): + return + if node.starargs or node.kwargs: + return + try: + strnode = next(func.bound.infer()) + except astroid.InferenceError: + return + if not (isinstance(strnode, astroid.Const) and isinstance(strnode.value, str)): + return + try: + call_site = CallSite.from_call(node) + except astroid.InferenceError: + return + + try: + fields, num_args, manual_pos = utils.parse_format_method_string( + strnode.value + ) + except utils.IncompleteFormatString: + self.add_message("bad-format-string", node=node) + return + + positional_arguments = call_site.positional_arguments + named_arguments = call_site.keyword_arguments + named_fields = {field[0] for field in fields if isinstance(field[0], str)} + if num_args and manual_pos: + self.add_message("format-combined-specification", node=node) + return + + check_args = False + # Consider "{[0]} {[1]}" as num_args. + num_args += sum(1 for field in named_fields if field == "") + if named_fields: + for field in named_fields: + if field and field not in named_arguments: + self.add_message( + "missing-format-argument-key", node=node, args=(field,) + ) + for field in named_arguments: + if field not in named_fields: + self.add_message( + "unused-format-string-argument", node=node, args=(field,) + ) + # num_args can be 0 if manual_pos is not. + num_args = num_args or manual_pos + if positional_arguments or num_args: + empty = any(True for field in named_fields if field == "") + if named_arguments or empty: + # Verify the required number of positional arguments + # only if the .format got at least one keyword argument. + # This means that the format strings accepts both + # positional and named fields and we should warn + # when one of the them is missing or is extra. + check_args = True + else: + check_args = True + if check_args: + # num_args can be 0 if manual_pos is not. + num_args = num_args or manual_pos + if len(positional_arguments) > num_args: + self.add_message("too-many-format-args", node=node) + elif len(positional_arguments) < num_args: + self.add_message("too-few-format-args", node=node) + + self._detect_vacuous_formatting(node, positional_arguments) + self._check_new_format_specifiers(node, fields, named_arguments) + + def _check_new_format_specifiers(self, node, fields, named): + """ + Check attribute and index access in the format + string ("{0.a}" and "{0[a]}"). + """ + for key, specifiers in fields: + # Obtain the argument. If it can't be obtained + # or infered, skip this check. + if key == "": + # {[0]} will have an unnamed argument, defaulting + # to 0. It will not be present in `named`, so use the value + # 0 for it. + key = 0 + if isinstance(key, numbers.Number): + try: + argname = utils.get_argument_from_call(node, key) + except utils.NoSuchArgumentError: + continue + else: + if key not in named: + continue + argname = named[key] + if argname in (astroid.Uninferable, None): + continue + try: + argument = next(argname.infer()) + except astroid.InferenceError: + continue + if not specifiers or argument is astroid.Uninferable: + # No need to check this key if it doesn't + # use attribute / item access + continue + if argument.parent and isinstance(argument.parent, astroid.Arguments): + # Ignore any object coming from an argument, + # because we can't infer its value properly. + continue + previous = argument + parsed = [] + for is_attribute, specifier in specifiers: + if previous is astroid.Uninferable: + break + parsed.append((is_attribute, specifier)) + if is_attribute: + try: + previous = previous.getattr(specifier)[0] + except astroid.NotFoundError: + if ( + hasattr(previous, "has_dynamic_getattr") + and previous.has_dynamic_getattr() + ): + # Don't warn if the object has a custom __getattr__ + break + path = get_access_path(key, parsed) + self.add_message( + "missing-format-attribute", + args=(specifier, path), + node=node, + ) + break + else: + warn_error = False + if hasattr(previous, "getitem"): + try: + previous = previous.getitem(astroid.Const(specifier)) + except ( + astroid.AstroidIndexError, + astroid.AstroidTypeError, + astroid.AttributeInferenceError, + ): + warn_error = True + except astroid.InferenceError: + break + if previous is astroid.Uninferable: + break + else: + try: + # Lookup __getitem__ in the current node, + # but skip further checks, because we can't + # retrieve the looked object + previous.getattr("__getitem__") + break + except astroid.NotFoundError: + warn_error = True + if warn_error: + path = get_access_path(key, parsed) + self.add_message( + "invalid-format-index", args=(specifier, path), node=node + ) + break + + try: + previous = next(previous.infer()) + except astroid.InferenceError: + # can't check further if we can't infer it + break + + +class StringConstantChecker(BaseTokenChecker): + """Check string literals""" + + __implements__ = (IAstroidChecker, ITokenChecker, IRawChecker) + name = "string_constant" + msgs = { + "W1401": ( + "Anomalous backslash in string: '%s'. " + "String constant might be missing an r prefix.", + "anomalous-backslash-in-string", + "Used when a backslash is in a literal string but not as an escape.", + ), + "W1402": ( + "Anomalous Unicode escape in byte string: '%s'. " + "String constant might be missing an r or u prefix.", + "anomalous-unicode-escape-in-string", + "Used when an escape like \\u is encountered in a byte " + "string where it has no effect.", + ), + "W1403": ( + "Implicit string concatenation found in %s", + "implicit-str-concat-in-sequence", + "String literals are implicitly concatenated in a " + "literal iterable definition : " + "maybe a comma is missing ?", + ), + } + + # Characters that have a special meaning after a backslash in either + # Unicode or byte strings. + ESCAPE_CHARACTERS = "abfnrtvx\n\r\t\\'\"01234567" + + # TODO(mbp): Octal characters are quite an edge case today; people may + # prefer a separate warning where they occur. \0 should be allowed. + + # Characters that have a special meaning after a backslash but only in + # Unicode strings. + UNICODE_ESCAPE_CHARACTERS = "uUN" + + def __init__(self, *args, **kwargs): + super(StringConstantChecker, self).__init__(*args, **kwargs) + self.string_tokens = {} # token position -> (token value, next token) + + def process_module(self, module): + self._unicode_literals = "unicode_literals" in module.future_imports + + def process_tokens(self, tokens): + encoding = "ascii" + for i, (tok_type, token, start, _, line) in enumerate(tokens): + if tok_type == tokenize.ENCODING: + # this is always the first token processed + encoding = token + elif tok_type == tokenize.STRING: + # 'token' is the whole un-parsed token; we can look at the start + # of it to see whether it's a raw or unicode string etc. + self.process_string_token(token, start[0]) + next_token = tokens[i + 1] if i + 1 < len(tokens) else None + if encoding != "ascii": + # We convert `tokenize` character count into a byte count, + # to match with astroid `.col_offset` + start = (start[0], len(line[: start[1]].encode(encoding))) + self.string_tokens[start] = (str_eval(token), next_token) + + @check_messages(*(MSGS.keys())) + def visit_list(self, node): + self.check_for_concatenated_strings(node, "list") + + @check_messages(*(MSGS.keys())) + def visit_set(self, node): + self.check_for_concatenated_strings(node, "set") + + @check_messages(*(MSGS.keys())) + def visit_tuple(self, node): + self.check_for_concatenated_strings(node, "tuple") + + def check_for_concatenated_strings(self, iterable_node, iterable_type): + for elt in iterable_node.elts: + if isinstance(elt, Const) and elt.pytype() in _AST_NODE_STR_TYPES: + if elt.col_offset < 0: + # This can happen in case of escaped newlines + continue + if (elt.lineno, elt.col_offset) not in self.string_tokens: + # This may happen with Latin1 encoding + # cf. https://github.com/PyCQA/pylint/issues/2610 + continue + matching_token, next_token = self.string_tokens[ + (elt.lineno, elt.col_offset) + ] + if matching_token != elt.value and next_token is not None: + next_token_type, next_token_pos = next_token[0], next_token[2] + # We do not warn if string concatenation happens over a newline + if ( + next_token_type == tokenize.STRING + and next_token_pos[0] == elt.lineno + ): + self.add_message( + "implicit-str-concat-in-sequence", + line=elt.lineno, + args=(iterable_type,), + ) + + def process_string_token(self, token, start_row): + quote_char = None + index = None + for index, c in enumerate(token): + if c in "'\"": + quote_char = c + break + if quote_char is None: + return + + prefix = token[:index].lower() # markers like u, b, r. + after_prefix = token[index:] + if after_prefix[:3] == after_prefix[-3:] == 3 * quote_char: + string_body = after_prefix[3:-3] + else: + string_body = after_prefix[1:-1] # Chop off quotes + # No special checks on raw strings at the moment. + if "r" not in prefix: + self.process_non_raw_string_token(prefix, string_body, start_row) + + def process_non_raw_string_token(self, prefix, string_body, start_row): + """check for bad escapes in a non-raw string. + + prefix: lowercase string of eg 'ur' string prefix markers. + string_body: the un-parsed body of the string, not including the quote + marks. + start_row: integer line number in the source. + """ + # Walk through the string; if we see a backslash then escape the next + # character, and skip over it. If we see a non-escaped character, + # alert, and continue. + # + # Accept a backslash when it escapes a backslash, or a quote, or + # end-of-line, or one of the letters that introduce a special escape + # sequence <http://docs.python.org/reference/lexical_analysis.html> + # + # TODO(mbp): Maybe give a separate warning about the rarely-used + # \a \b \v \f? + # + # TODO(mbp): We could give the column of the problem character, but + # add_message doesn't seem to have a way to pass it through at present. + i = 0 + while True: + i = string_body.find("\\", i) + if i == -1: + break + # There must be a next character; having a backslash at the end + # of the string would be a SyntaxError. + next_char = string_body[i + 1] + match = string_body[i : i + 2] + if next_char in self.UNICODE_ESCAPE_CHARACTERS: + if "u" in prefix: + pass + elif (_PY3K or self._unicode_literals) and "b" not in prefix: + pass # unicode by default + else: + self.add_message( + "anomalous-unicode-escape-in-string", + line=start_row, + args=(match,), + ) + elif next_char not in self.ESCAPE_CHARACTERS: + self.add_message( + "anomalous-backslash-in-string", line=start_row, args=(match,) + ) + # Whether it was a valid escape or not, backslash followed by + # another character can always be consumed whole: the second + # character can never be the start of a new backslash escape. + i += 2 + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(StringFormatChecker(linter)) + linter.register_checker(StringConstantChecker(linter)) + + +def str_eval(token): + """ + Mostly replicate `ast.literal_eval(token)` manually to avoid any performance hit. + This supports f-strings, contrary to `ast.literal_eval`. + We have to support all string literal notations: + https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals + """ + if token[0:2].lower() in ("fr", "rf"): + token = token[2:] + elif token[0].lower() in ("r", "u", "f"): + token = token[1:] + if token[0:3] in ('"""', "'''"): + return token[3:-3] + return token[1:-1] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/typecheck.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/typecheck.py new file mode 100644 index 0000000..9011618 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/typecheck.py @@ -0,0 +1,1633 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2009 James Lingard <jchl@aristanetworks.com> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 David Shea <dshea@redhat.com> +# Copyright (c) 2014 Steven Myint <hg@stevenmyint.com> +# Copyright (c) 2014 Holger Peters <email@holger-peters.de> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Anentropic <ego@anentropic.com> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Rene Zhang <rz99@cornell.edu> +# Copyright (c) 2015 Radu Ciorba <radu@devrandom.ro> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016 Jürgen Hermann <jh@web.de> +# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2016 Filipe Brandenburger <filbranden@google.com> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 Ben Green <benhgreen@icloud.com> +# Copyright (c) 2018 Konstantin <Github@pheanex.de> +# Copyright (c) 2018 Justin Li <justinnhli@users.noreply.github.com> +# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""try to find more bugs in the code using astroid inference capabilities +""" + +import builtins +import collections +import fnmatch +import heapq +import itertools +import operator +import re +import shlex +import sys +import types + +import astroid +import astroid.context +import astroid.arguments +import astroid.nodes +from astroid import exceptions, decorators +from astroid.interpreter import dunder_lookup +from astroid import objects +from astroid import bases +from astroid import modutils + +from pylint.interfaces import IAstroidChecker, INFERENCE +from pylint.checkers import BaseChecker +from pylint.checkers.utils import ( + is_super, + check_messages, + decorated_with_property, + decorated_with, + node_ignores_exception, + is_iterable, + is_mapping, + supports_membership_test, + is_comprehension, + is_inside_abstract_class, + supports_getitem, + supports_setitem, + supports_delitem, + safe_infer, + has_known_bases, + is_builtin_object, + singledispatch, +) +from pylint.utils import get_global_option + +BUILTINS = builtins.__name__ +STR_FORMAT = {"%s.str.format" % BUILTINS} +ASYNCIO_COROUTINE = "asyncio.coroutines.coroutine" + + +def _unflatten(iterable): + for index, elem in enumerate(iterable): + if isinstance(elem, collections.Sequence) and not isinstance(elem, str): + for single_elem in _unflatten(elem): + yield single_elem + elif elem and not index: + # We're interested only in the first element. + yield elem + + +def _flatten_container(iterable): + # Flatten nested containers into a single iterable + for item in iterable: + if isinstance(item, (list, tuple, types.GeneratorType)): + yield from _flatten_container(item) + else: + yield item + + +def _is_owner_ignored(owner, name, ignored_classes, ignored_modules): + """Check if the given owner should be ignored + + This will verify if the owner's module is in *ignored_modules* + or the owner's module fully qualified name is in *ignored_modules* + or if the *ignored_modules* contains a pattern which catches + the fully qualified name of the module. + + Also, similar checks are done for the owner itself, if its name + matches any name from the *ignored_classes* or if its qualified + name can be found in *ignored_classes*. + """ + ignored_modules = set(ignored_modules) + module_name = owner.root().name + module_qname = owner.root().qname() + if any( + module_name in ignored_modules + or module_qname in ignored_modules + or fnmatch.fnmatch(module_qname, ignore) + for ignore in ignored_modules + ): + return True + + ignored_classes = set(ignored_classes) + if hasattr(owner, "qname"): + qname = owner.qname() + else: + qname = "" + return any(ignore in (name, qname) for ignore in ignored_classes) + + +@singledispatch +def _node_names(node): + # TODO: maybe we need an ABC for checking if an object is a scoped node + # or not? + if not hasattr(node, "locals"): + return [] + return node.locals.keys() + + +@_node_names.register(astroid.ClassDef) +@_node_names.register(astroid.Instance) +def _(node): + values = itertools.chain(node.instance_attrs.keys(), node.locals.keys()) + + try: + mro = node.mro()[1:] + except (NotImplementedError, TypeError): + mro = node.ancestors() + + other_values = [value for cls in mro for value in _node_names(cls)] + return itertools.chain(values, other_values) + + +def _string_distance(seq1, seq2): + seq2_length = len(seq2) + + row = list(range(1, seq2_length + 1)) + [0] + for seq1_index, seq1_char in enumerate(seq1): + last_row = row + row = [0] * seq2_length + [seq1_index + 1] + + for seq2_index, seq2_char in enumerate(seq2): + row[seq2_index] = min( + last_row[seq2_index] + 1, + row[seq2_index - 1] + 1, + last_row[seq2_index - 1] + (seq1_char != seq2_char), + ) + + return row[seq2_length - 1] + + +def _similar_names(owner, attrname, distance_threshold, max_choices): + """Given an owner and a name, try to find similar names + + The similar names are searched given a distance metric and only + a given number of choices will be returned. + """ + possible_names = [] + names = _node_names(owner) + + for name in names: + if name == attrname: + continue + + distance = _string_distance(attrname, name) + if distance <= distance_threshold: + possible_names.append((name, distance)) + + # Now get back the values with a minimum, up to the given + # limit or choices. + picked = [ + name + for (name, _) in heapq.nsmallest( + max_choices, possible_names, key=operator.itemgetter(1) + ) + ] + return sorted(picked) + + +def _missing_member_hint(owner, attrname, distance_threshold, max_choices): + names = _similar_names(owner, attrname, distance_threshold, max_choices) + if not names: + # No similar name. + return "" + + names = list(map(repr, names)) + if len(names) == 1: + names = ", ".join(names) + else: + names = "one of {} or {}".format(", ".join(names[:-1]), names[-1]) + + return "; maybe {}?".format(names) + + +MSGS = { + "E1101": ( + "%s %r has no %r member%s", + "no-member", + "Used when a variable is accessed for an unexistent member.", + {"old_names": [("E1103", "maybe-no-member")]}, + ), + "I1101": ( + "%s %r has no %r member%s, but source is unavailable. Consider " + "adding this module to extension-pkg-whitelist if you want " + "to perform analysis based on run-time introspection of living objects.", + "c-extension-no-member", + "Used when a variable is accessed for non-existent member of C " + "extension. Due to unavailability of source static analysis is impossible, " + "but it may be performed by introspecting living objects in run-time.", + ), + "E1102": ( + "%s is not callable", + "not-callable", + "Used when an object being called has been inferred to a non " + "callable object.", + ), + "E1111": ( + "Assigning result of a function call, where the function has no return", + "assignment-from-no-return", + "Used when an assignment is done on a function call but the " + "inferred function doesn't return anything.", + ), + "E1120": ( + "No value for argument %s in %s call", + "no-value-for-parameter", + "Used when a function call passes too few arguments.", + ), + "E1121": ( + "Too many positional arguments for %s call", + "too-many-function-args", + "Used when a function call passes too many positional arguments.", + ), + "E1123": ( + "Unexpected keyword argument %r in %s call", + "unexpected-keyword-arg", + "Used when a function call passes a keyword argument that " + "doesn't correspond to one of the function's parameter names.", + ), + "E1124": ( + "Argument %r passed by position and keyword in %s call", + "redundant-keyword-arg", + "Used when a function call would result in assigning multiple " + "values to a function parameter, one value from a positional " + "argument and one from a keyword argument.", + ), + "E1125": ( + "Missing mandatory keyword argument %r in %s call", + "missing-kwoa", + ( + "Used when a function call does not pass a mandatory" + " keyword-only argument." + ), + ), + "E1126": ( + "Sequence index is not an int, slice, or instance with __index__", + "invalid-sequence-index", + "Used when a sequence type is indexed with an invalid type. " + "Valid types are ints, slices, and objects with an __index__ " + "method.", + ), + "E1127": ( + "Slice index is not an int, None, or instance with __index__", + "invalid-slice-index", + "Used when a slice index is not an integer, None, or an object " + "with an __index__ method.", + ), + "E1128": ( + "Assigning result of a function call, where the function returns None", + "assignment-from-none", + "Used when an assignment is done on a function call but the " + "inferred function returns nothing but None.", + {"old_names": [("W1111", "assignment-from-none")]}, + ), + "E1129": ( + "Context manager '%s' doesn't implement __enter__ and __exit__.", + "not-context-manager", + "Used when an instance in a with statement doesn't implement " + "the context manager protocol(__enter__/__exit__).", + ), + "E1130": ( + "%s", + "invalid-unary-operand-type", + "Emitted when a unary operand is used on an object which does not " + "support this type of operation.", + ), + "E1131": ( + "%s", + "unsupported-binary-operation", + "Emitted when a binary arithmetic operation between two " + "operands is not supported.", + ), + "E1132": ( + "Got multiple values for keyword argument %r in function call", + "repeated-keyword", + "Emitted when a function call got multiple values for a keyword.", + ), + "E1135": ( + "Value '%s' doesn't support membership test", + "unsupported-membership-test", + "Emitted when an instance in membership test expression doesn't " + "implement membership protocol (__contains__/__iter__/__getitem__).", + ), + "E1136": ( + "Value '%s' is unsubscriptable", + "unsubscriptable-object", + "Emitted when a subscripted value doesn't support subscription " + "(i.e. doesn't define __getitem__ method).", + ), + "E1137": ( + "%r does not support item assignment", + "unsupported-assignment-operation", + "Emitted when an object does not support item assignment " + "(i.e. doesn't define __setitem__ method).", + ), + "E1138": ( + "%r does not support item deletion", + "unsupported-delete-operation", + "Emitted when an object does not support item deletion " + "(i.e. doesn't define __delitem__ method).", + ), + "E1139": ( + "Invalid metaclass %r used", + "invalid-metaclass", + "Emitted whenever we can detect that a class is using, " + "as a metaclass, something which might be invalid for using as " + "a metaclass.", + ), + "E1140": ( + "Dict key is unhashable", + "unhashable-dict-key", + "Emitted when a dict key is not hashable " + "(i.e. doesn't define __hash__ method).", + ), + "W1113": ( + "Keyword argument before variable positional arguments list " + "in the definition of %s function", + "keyword-arg-before-vararg", + "When defining a keyword argument before variable positional arguments, one can " + "end up in having multiple values passed for the aforementioned parameter in " + "case the method is called with keyword arguments.", + ), +} + +# builtin sequence types in Python 2 and 3. +SEQUENCE_TYPES = { + "str", + "unicode", + "list", + "tuple", + "bytearray", + "xrange", + "range", + "bytes", + "memoryview", +} + + +def _emit_no_member(node, owner, owner_name, ignored_mixins=True, ignored_none=True): + """Try to see if no-member should be emitted for the given owner. + + The following cases are ignored: + + * the owner is a function and it has decorators. + * the owner is an instance and it has __getattr__, __getattribute__ implemented + * the module is explicitly ignored from no-member checks + * the owner is a class and the name can be found in its metaclass. + * The access node is protected by an except handler, which handles + AttributeError, Exception or bare except. + """ + # pylint: disable=too-many-return-statements + if node_ignores_exception(node, AttributeError): + return False + if ignored_none and isinstance(owner, astroid.Const) and owner.value is None: + return False + if is_super(owner) or getattr(owner, "type", None) == "metaclass": + return False + if ignored_mixins and owner_name[-5:].lower() == "mixin": + return False + if isinstance(owner, astroid.FunctionDef) and owner.decorators: + return False + if isinstance(owner, (astroid.Instance, astroid.ClassDef)): + if owner.has_dynamic_getattr() or not has_known_bases(owner): + return False + if isinstance(owner, objects.Super): + # Verify if we are dealing with an invalid Super object. + # If it is invalid, then there's no point in checking that + # it has the required attribute. Also, don't fail if the + # MRO is invalid. + try: + owner.super_mro() + except (exceptions.MroError, exceptions.SuperError): + return False + if not all(map(has_known_bases, owner.type.mro())): + return False + if isinstance(owner, astroid.Module): + try: + owner.getattr("__getattr__") + return False + except astroid.NotFoundError: + pass + if node.attrname.startswith("_" + owner_name): + # Test if an attribute has been mangled ('private' attribute) + unmangled_name = node.attrname.split("_" + owner_name)[-1] + try: + if owner.getattr(unmangled_name, context=None) is not None: + return False + except astroid.NotFoundError: + return True + return True + + +def _determine_callable(callable_obj): + # Ordering is important, since BoundMethod is a subclass of UnboundMethod, + # and Function inherits Lambda. + parameters = 0 + if hasattr(callable_obj, "implicit_parameters"): + # TODO: replace with a Callable check + parameters = callable_obj.implicit_parameters() + if isinstance(callable_obj, astroid.BoundMethod): + # Bound methods have an extra implicit 'self' argument. + return callable_obj, parameters, callable_obj.type + if isinstance(callable_obj, astroid.UnboundMethod): + return callable_obj, parameters, "unbound method" + if isinstance(callable_obj, astroid.FunctionDef): + return callable_obj, parameters, callable_obj.type + if isinstance(callable_obj, astroid.Lambda): + return callable_obj, parameters, "lambda" + if isinstance(callable_obj, astroid.ClassDef): + # Class instantiation, lookup __new__ instead. + # If we only find object.__new__, we can safely check __init__ + # instead. If __new__ belongs to builtins, then we look + # again for __init__ in the locals, since we won't have + # argument information for the builtin __new__ function. + try: + # Use the last definition of __new__. + new = callable_obj.local_attr("__new__")[-1] + except exceptions.NotFoundError: + new = None + + from_object = new and new.parent.scope().name == "object" + from_builtins = new and new.root().name in sys.builtin_module_names + + if not new or from_object or from_builtins: + try: + # Use the last definition of __init__. + callable_obj = callable_obj.local_attr("__init__")[-1] + except exceptions.NotFoundError: + # do nothing, covered by no-init. + raise ValueError + else: + callable_obj = new + + if not isinstance(callable_obj, astroid.FunctionDef): + raise ValueError + # both have an extra implicit 'cls'/'self' argument. + return callable_obj, parameters, "constructor" + else: + raise ValueError + + +def _has_parent_of_type(node, node_type, statement): + """Check if the given node has a parent of the given type.""" + parent = node.parent + while not isinstance(parent, node_type) and statement.parent_of(parent): + parent = parent.parent + return isinstance(parent, node_type) + + +def _is_name_used_as_variadic(name, variadics): + """Check if the given name is used as a variadic argument.""" + return any( + variadic.value == name or variadic.value.parent_of(name) + for variadic in variadics + ) + + +def _no_context_variadic_keywords(node): + statement = node.statement() + scope = node.scope() + variadics = () + + if not isinstance(scope, astroid.FunctionDef): + return False + + if isinstance(statement, (astroid.Return, astroid.Expr)) and isinstance( + statement.value, astroid.Call + ): + call = statement.value + variadics = list(call.keywords or []) + call.kwargs + + return _no_context_variadic(node, scope.args.kwarg, astroid.Keyword, variadics) + + +def _no_context_variadic_positional(node): + statement = node.statement() + scope = node.scope() + variadics = () + + if not isinstance(scope, astroid.FunctionDef): + return False + + if isinstance(statement, (astroid.Expr, astroid.Return)) and isinstance( + statement.value, astroid.Call + ): + call = statement.value + variadics = call.starargs + call.kwargs + + return _no_context_variadic(node, scope.args.vararg, astroid.Starred, variadics) + + +def _no_context_variadic(node, variadic_name, variadic_type, variadics): + """Verify if the given call node has variadic nodes without context + + This is a workaround for handling cases of nested call functions + which don't have the specific call context at hand. + Variadic arguments (variable positional arguments and variable + keyword arguments) are inferred, inherently wrong, by astroid + as a Tuple, respectively a Dict with empty elements. + This can lead pylint to believe that a function call receives + too few arguments. + """ + statement = node.statement() + for name in statement.nodes_of_class(astroid.Name): + if name.name != variadic_name: + continue + + inferred = safe_infer(name) + if isinstance(inferred, (astroid.List, astroid.Tuple)): + length = len(inferred.elts) + elif isinstance(inferred, astroid.Dict): + length = len(inferred.items) + else: + continue + + inferred_statement = inferred.statement() + if not length and isinstance(inferred_statement, astroid.FunctionDef): + is_in_starred_context = _has_parent_of_type(node, variadic_type, statement) + used_as_starred_argument = _is_name_used_as_variadic(name, variadics) + if is_in_starred_context or used_as_starred_argument: + return True + return False + + +def _is_invalid_metaclass(metaclass): + try: + mro = metaclass.mro() + except NotImplementedError: + # Cannot have a metaclass which is not a newstyle class. + return True + else: + if not any(is_builtin_object(cls) and cls.name == "type" for cls in mro): + return True + return False + + +def _infer_from_metaclass_constructor(cls, func): + """Try to infer what the given *func* constructor is building + + :param astroid.FunctionDef func: + A metaclass constructor. Metaclass definitions can be + functions, which should accept three arguments, the name of + the class, the bases of the class and the attributes. + The function could return anything, but usually it should + be a proper metaclass. + :param astroid.ClassDef cls: + The class for which the *func* parameter should generate + a metaclass. + :returns: + The class generated by the function or None, + if we couldn't infer it. + :rtype: astroid.ClassDef + """ + context = astroid.context.InferenceContext() + + class_bases = astroid.List() + class_bases.postinit(elts=cls.bases) + + attrs = astroid.Dict() + local_names = [(name, values[-1]) for name, values in cls.locals.items()] + attrs.postinit(local_names) + + builder_args = astroid.Tuple() + builder_args.postinit([cls.name, class_bases, attrs]) + + context.callcontext = astroid.context.CallContext(builder_args) + try: + inferred = next(func.infer_call_result(func, context), None) + except astroid.InferenceError: + return None + return inferred or None + + +def _is_c_extension(module_node): + return ( + not modutils.is_standard_module(module_node.name) + and not module_node.fully_defined() + ) + + +class TypeChecker(BaseChecker): + """try to find bugs in the code using type inference + """ + + __implements__ = (IAstroidChecker,) + + # configuration section name + name = "typecheck" + # messages + msgs = MSGS + priority = -1 + # configuration options + options = ( + ( + "ignore-on-opaque-inference", + { + "default": True, + "type": "yn", + "metavar": "<y_or_n>", + "help": "This flag controls whether pylint should warn about " + "no-member and similar checks whenever an opaque object " + "is returned when inferring. The inference can return " + "multiple potential results while evaluating a Python object, " + "but some branches might not be evaluated, which results in " + "partial inference. In that case, it might be useful to still emit " + "no-member and other checks for the rest of the inferred objects.", + }, + ), + ( + "ignore-mixin-members", + { + "default": True, + "type": "yn", + "metavar": "<y_or_n>", + "help": 'Tells whether missing members accessed in mixin \ +class should be ignored. A mixin class is detected if its name ends with \ +"mixin" (case insensitive).', + }, + ), + ( + "ignore-none", + { + "default": True, + "type": "yn", + "metavar": "<y_or_n>", + "help": "Tells whether to warn about missing members when the owner " + "of the attribute is inferred to be None.", + }, + ), + ( + "ignored-modules", + { + "default": (), + "type": "csv", + "metavar": "<module names>", + "help": "List of module names for which member attributes " + "should not be checked (useful for modules/projects " + "where namespaces are manipulated during runtime and " + "thus existing member attributes cannot be " + "deduced by static analysis. It supports qualified " + "module names, as well as Unix pattern matching.", + }, + ), + # the defaults here are *stdlib* names that (almost) always + # lead to false positives, since their idiomatic use is + # 'too dynamic' for pylint to grok. + ( + "ignored-classes", + { + "default": ("optparse.Values", "thread._local", "_thread._local"), + "type": "csv", + "metavar": "<members names>", + "help": "List of class names for which member attributes " + "should not be checked (useful for classes with " + "dynamically set attributes). This supports " + "the use of qualified names.", + }, + ), + ( + "generated-members", + { + "default": (), + "type": "string", + "metavar": "<members names>", + "help": "List of members which are set dynamically and \ +missed by pylint inference system, and so shouldn't trigger E1101 when \ +accessed. Python regular expressions are accepted.", + }, + ), + ( + "contextmanager-decorators", + { + "default": ["contextlib.contextmanager"], + "type": "csv", + "metavar": "<decorator names>", + "help": "List of decorators that produce context managers, " + "such as contextlib.contextmanager. Add to this list " + "to register other decorators that produce valid " + "context managers.", + }, + ), + ( + "missing-member-hint-distance", + { + "default": 1, + "type": "int", + "metavar": "<member hint edit distance>", + "help": "The minimum edit distance a name should have in order " + "to be considered a similar match for a missing member name.", + }, + ), + ( + "missing-member-max-choices", + { + "default": 1, + "type": "int", + "metavar": "<member hint max choices>", + "help": "The total number of similar names that should be taken in " + "consideration when showing a hint for a missing member.", + }, + ), + ( + "missing-member-hint", + { + "default": True, + "type": "yn", + "metavar": "<missing member hint>", + "help": "Show a hint with possible names when a member name was not " + "found. The aspect of finding the hint is based on edit distance.", + }, + ), + ) + + @decorators.cachedproperty + def _suggestion_mode(self): + return get_global_option(self, "suggestion-mode", default=True) + + def open(self): + # do this in open since config not fully initialized in __init__ + # generated_members may contain regular expressions + # (surrounded by quote `"` and followed by a comma `,`) + # REQUEST,aq_parent,"[a-zA-Z]+_set{1,2}"' => + # ('REQUEST', 'aq_parent', '[a-zA-Z]+_set{1,2}') + if isinstance(self.config.generated_members, str): + gen = shlex.shlex(self.config.generated_members) + gen.whitespace += "," + gen.wordchars += r"[]-+\.*?()|" + self.config.generated_members = tuple(tok.strip('"') for tok in gen) + + @check_messages("keyword-arg-before-vararg") + def visit_functiondef(self, node): + # check for keyword arg before varargs + if node.args.vararg and node.args.defaults: + self.add_message("keyword-arg-before-vararg", node=node, args=(node.name)) + + visit_asyncfunctiondef = visit_functiondef + + @check_messages("invalid-metaclass") + def visit_classdef(self, node): + def _metaclass_name(metaclass): + if isinstance(metaclass, (astroid.ClassDef, astroid.FunctionDef)): + return metaclass.name + return metaclass.as_string() + + metaclass = node.declared_metaclass() + if not metaclass: + return + + if isinstance(metaclass, astroid.FunctionDef): + # Try to infer the result. + metaclass = _infer_from_metaclass_constructor(node, metaclass) + if not metaclass: + # Don't do anything if we cannot infer the result. + return + + if isinstance(metaclass, astroid.ClassDef): + if _is_invalid_metaclass(metaclass): + self.add_message( + "invalid-metaclass", node=node, args=(_metaclass_name(metaclass),) + ) + else: + self.add_message( + "invalid-metaclass", node=node, args=(_metaclass_name(metaclass),) + ) + + def visit_assignattr(self, node): + if isinstance(node.assign_type(), astroid.AugAssign): + self.visit_attribute(node) + + def visit_delattr(self, node): + self.visit_attribute(node) + + @check_messages("no-member", "c-extension-no-member") + def visit_attribute(self, node): + """check that the accessed attribute exists + + to avoid too much false positives for now, we'll consider the code as + correct if a single of the inferred nodes has the accessed attribute. + + function/method, super call and metaclasses are ignored + """ + for pattern in self.config.generated_members: + # attribute is marked as generated, stop here + if re.match(pattern, node.attrname): + return + if re.match(pattern, node.as_string()): + return + + try: + inferred = list(node.expr.infer()) + except exceptions.InferenceError: + return + + # list of (node, nodename) which are missing the attribute + missingattr = set() + + non_opaque_inference_results = [ + owner + for owner in inferred + if owner is not astroid.Uninferable + and not isinstance(owner, astroid.nodes.Unknown) + ] + if ( + len(non_opaque_inference_results) != len(inferred) + and self.config.ignore_on_opaque_inference + ): + # There is an ambiguity in the inference. Since we can't + # make sure that we won't emit a false positive, we just stop + # whenever the inference returns an opaque inference object. + return + + for owner in non_opaque_inference_results: + name = getattr(owner, "name", None) + if _is_owner_ignored( + owner, name, self.config.ignored_classes, self.config.ignored_modules + ): + continue + + try: + if not [ + n + for n in owner.getattr(node.attrname) + if not isinstance(n.statement(), astroid.AugAssign) + ]: + missingattr.add((owner, name)) + continue + except AttributeError: + # XXX method / function + continue + except exceptions.NotFoundError: + # This can't be moved before the actual .getattr call, + # because there can be more values inferred and we are + # stopping after the first one which has the attribute in question. + # The problem is that if the first one has the attribute, + # but we continue to the next values which doesn't have the + # attribute, then we'll have a false positive. + # So call this only after the call has been made. + if not _emit_no_member( + node, + owner, + name, + ignored_mixins=self.config.ignore_mixin_members, + ignored_none=self.config.ignore_none, + ): + + continue + missingattr.add((owner, name)) + continue + # stop on the first found + break + else: + # we have not found any node with the attributes, display the + # message for infered nodes + done = set() + for owner, name in missingattr: + if isinstance(owner, astroid.Instance): + actual = owner._proxied + else: + actual = owner + if actual in done: + continue + done.add(actual) + + msg, hint = self._get_nomember_msgid_hint(node, owner) + self.add_message( + msg, + node=node, + args=(owner.display_type(), name, node.attrname, hint), + confidence=INFERENCE, + ) + + def _get_nomember_msgid_hint(self, node, owner): + suggestions_are_possible = self._suggestion_mode and isinstance( + owner, astroid.Module + ) + if suggestions_are_possible and _is_c_extension(owner): + msg = "c-extension-no-member" + hint = "" + else: + msg = "no-member" + if self.config.missing_member_hint: + hint = _missing_member_hint( + owner, + node.attrname, + self.config.missing_member_hint_distance, + self.config.missing_member_max_choices, + ) + else: + hint = "" + return msg, hint + + @check_messages("assignment-from-no-return", "assignment-from-none") + def visit_assign(self, node): + """check that if assigning to a function call, the function is + possibly returning something valuable + """ + if not isinstance(node.value, astroid.Call): + return + function_node = safe_infer(node.value.func) + # skip class, generator and incomplete function definition + funcs = (astroid.FunctionDef, astroid.UnboundMethod, astroid.BoundMethod) + if not ( + isinstance(function_node, funcs) + and function_node.root().fully_defined() + and not function_node.decorators + ): + return + if ( + function_node.is_generator() + or function_node.is_abstract(pass_is_abstract=False) + or isinstance(function_node, astroid.AsyncFunctionDef) + ): + return + returns = list( + function_node.nodes_of_class(astroid.Return, skip_klass=astroid.FunctionDef) + ) + if not returns: + self.add_message("assignment-from-no-return", node=node) + else: + for rnode in returns: + if not ( + isinstance(rnode.value, astroid.Const) + and rnode.value.value is None + or rnode.value is None + ): + break + else: + self.add_message("assignment-from-none", node=node) + + def _check_uninferable_call(self, node): + """ + Check that the given uninferable Call node does not + call an actual function. + """ + if not isinstance(node.func, astroid.Attribute): + return + + # Look for properties. First, obtain + # the lhs of the Attribute node and search the attribute + # there. If that attribute is a property or a subclass of properties, + # then most likely it's not callable. + + # TODO: since astroid doesn't understand descriptors very well + # we will not handle them here, right now. + + expr = node.func.expr + klass = safe_infer(expr) + if ( + klass is None + or klass is astroid.Uninferable + or not isinstance(klass, astroid.Instance) + ): + return + + try: + attrs = klass._proxied.getattr(node.func.attrname) + except exceptions.NotFoundError: + return + + for attr in attrs: + if attr is astroid.Uninferable: + continue + if not isinstance(attr, astroid.FunctionDef): + continue + + # Decorated, see if it is decorated with a property. + # Also, check the returns and see if they are callable. + if decorated_with_property(attr): + + try: + all_returns_are_callable = all( + return_node.callable() + for return_node in attr.infer_call_result(node) + ) + except astroid.InferenceError: + continue + + if not all_returns_are_callable: + self.add_message( + "not-callable", node=node, args=node.func.as_string() + ) + break + + # pylint: disable=too-many-branches + @check_messages(*(list(MSGS.keys()))) + def visit_call(self, node): + """check that called functions/methods are inferred to callable objects, + and that the arguments passed to the function match the parameters in + the inferred function's definition + """ + called = safe_infer(node.func) + # only function, generator and object defining __call__ are allowed + # Ignore instances of descriptors since astroid cannot properly handle them + # yet + if called and not called.callable(): + if isinstance(called, astroid.Instance) and ( + not has_known_bases(called) + or ( + isinstance(called.scope(), astroid.ClassDef) + and "__get__" in called.locals + ) + ): + # Don't emit if we can't make sure this object is callable. + pass + else: + self.add_message("not-callable", node=node, args=node.func.as_string()) + + self._check_uninferable_call(node) + + try: + called, implicit_args, callable_name = _determine_callable(called) + except ValueError: + # Any error occurred during determining the function type, most of + # those errors are handled by different warnings. + return + + if called.args.args is None: + # Built-in functions have no argument information. + return + + if len(called.argnames()) != len(set(called.argnames())): + # Duplicate parameter name (see duplicate-argument). We can't really + # make sense of the function call in this case, so just return. + return + + # Build the set of keyword arguments, checking for duplicate keywords, + # and count the positional arguments. + call_site = astroid.arguments.CallSite.from_call(node) + + # Warn about duplicated keyword arguments, such as `f=24, **{'f': 24}` + for keyword in call_site.duplicated_keywords: + self.add_message("repeated-keyword", node=node, args=(keyword,)) + + if call_site.has_invalid_arguments() or call_site.has_invalid_keywords(): + # Can't make sense of this. + return + + num_positional_args = len(call_site.positional_arguments) + keyword_args = list(call_site.keyword_arguments.keys()) + + # Determine if we don't have a context for our call and we use variadics. + if isinstance(node.scope(), astroid.FunctionDef): + has_no_context_positional_variadic = _no_context_variadic_positional(node) + has_no_context_keywords_variadic = _no_context_variadic_keywords(node) + else: + has_no_context_positional_variadic = ( + has_no_context_keywords_variadic + ) = False + + # These are coming from the functools.partial implementation in astroid + already_filled_positionals = getattr(called, "filled_positionals", 0) + already_filled_keywords = getattr(called, "filled_keywords", {}) + + keyword_args += list(already_filled_keywords) + num_positional_args += implicit_args + already_filled_positionals + + # Analyze the list of formal parameters. + + num_mandatory_parameters = len(called.args.args) - len(called.args.defaults) + parameters = [] + parameter_name_to_index = {} + for i, arg in enumerate(called.args.args): + if isinstance(arg, astroid.Tuple): + name = None + # Don't store any parameter names within the tuple, since those + # are not assignable from keyword arguments. + else: + assert isinstance(arg, astroid.AssignName) + # This occurs with: + # def f( (a), (b) ): pass + name = arg.name + parameter_name_to_index[name] = i + if i >= num_mandatory_parameters: + defval = called.args.defaults[i - num_mandatory_parameters] + else: + defval = None + parameters.append([(name, defval), False]) + + kwparams = {} + for i, arg in enumerate(called.args.kwonlyargs): + if isinstance(arg, astroid.Keyword): + name = arg.arg + else: + assert isinstance(arg, astroid.AssignName) + name = arg.name + kwparams[name] = [called.args.kw_defaults[i], False] + + # Match the supplied arguments against the function parameters. + + # 1. Match the positional arguments. + for i in range(num_positional_args): + if i < len(parameters): + parameters[i][1] = True + elif called.args.vararg is not None: + # The remaining positional arguments get assigned to the *args + # parameter. + break + else: + # Too many positional arguments. + self.add_message( + "too-many-function-args", node=node, args=(callable_name,) + ) + break + + # 2. Match the keyword arguments. + for keyword in keyword_args: + if keyword in parameter_name_to_index: + i = parameter_name_to_index[keyword] + if parameters[i][1]: + # Duplicate definition of function parameter. + + # Might be too hardcoded, but this can actually + # happen when using str.format and `self` is passed + # by keyword argument, as in `.format(self=self)`. + # It's perfectly valid to so, so we're just skipping + # it if that's the case. + if not (keyword == "self" and called.qname() in STR_FORMAT): + self.add_message( + "redundant-keyword-arg", + node=node, + args=(keyword, callable_name), + ) + else: + parameters[i][1] = True + elif keyword in kwparams: + if kwparams[keyword][1]: # XXX is that even possible? + # Duplicate definition of function parameter. + self.add_message( + "redundant-keyword-arg", + node=node, + args=(keyword, callable_name), + ) + else: + kwparams[keyword][1] = True + elif called.args.kwarg is not None: + # The keyword argument gets assigned to the **kwargs parameter. + pass + else: + # Unexpected keyword argument. + self.add_message( + "unexpected-keyword-arg", node=node, args=(keyword, callable_name) + ) + + # 3. Match the **kwargs, if any. + if node.kwargs: + for i, [(name, defval), assigned] in enumerate(parameters): + # Assume that *kwargs provides values for all remaining + # unassigned named parameters. + if name is not None: + parameters[i][1] = True + else: + # **kwargs can't assign to tuples. + pass + + # Check that any parameters without a default have been assigned + # values. + for [(name, defval), assigned] in parameters: + if (defval is None) and not assigned: + if name is None: + display_name = "<tuple>" + else: + display_name = repr(name) + # TODO(cpopa): this should be removed after PyCQA/astroid/issues/177 + if not has_no_context_positional_variadic: + self.add_message( + "no-value-for-parameter", + node=node, + args=(display_name, callable_name), + ) + + for name in kwparams: + defval, assigned = kwparams[name] + if defval is None and not assigned and not has_no_context_keywords_variadic: + self.add_message("missing-kwoa", node=node, args=(name, callable_name)) + + @check_messages("invalid-sequence-index") + def visit_extslice(self, node): + # Check extended slice objects as if they were used as a sequence + # index to check if the object being sliced can support them + return self.visit_index(node) + + @check_messages("invalid-sequence-index") + def visit_index(self, node): + if not node.parent or not hasattr(node.parent, "value"): + return None + # Look for index operations where the parent is a sequence type. + # If the types can be determined, only allow indices to be int, + # slice or instances with __index__. + parent_type = safe_infer(node.parent.value) + if not isinstance( + parent_type, (astroid.ClassDef, astroid.Instance) + ) or not has_known_bases(parent_type): + return None + + # Determine what method on the parent this index will use + # The parent of this node will be a Subscript, and the parent of that + # node determines if the Subscript is a get, set, or delete operation. + if node.parent.ctx is astroid.Store: + methodname = "__setitem__" + elif node.parent.ctx is astroid.Del: + methodname = "__delitem__" + else: + methodname = "__getitem__" + + # Check if this instance's __getitem__, __setitem__, or __delitem__, as + # appropriate to the statement, is implemented in a builtin sequence + # type. This way we catch subclasses of sequence types but skip classes + # that override __getitem__ and which may allow non-integer indices. + try: + methods = dunder_lookup.lookup(parent_type, methodname) + if methods is astroid.Uninferable: + return None + itemmethod = methods[0] + except ( + exceptions.NotFoundError, + exceptions.AttributeInferenceError, + IndexError, + ): + return None + + if ( + not isinstance(itemmethod, astroid.FunctionDef) + or itemmethod.root().name != BUILTINS + or not itemmethod.parent + or itemmethod.parent.name not in SEQUENCE_TYPES + ): + return None + + # For ExtSlice objects coming from visit_extslice, no further + # inference is necessary, since if we got this far the ExtSlice + # is an error. + if isinstance(node, astroid.ExtSlice): + index_type = node + else: + index_type = safe_infer(node) + if index_type is None or index_type is astroid.Uninferable: + return None + # Constants must be of type int + if isinstance(index_type, astroid.Const): + if isinstance(index_type.value, int): + return None + # Instance values must be int, slice, or have an __index__ method + elif isinstance(index_type, astroid.Instance): + if index_type.pytype() in (BUILTINS + ".int", BUILTINS + ".slice"): + return None + try: + index_type.getattr("__index__") + return None + except exceptions.NotFoundError: + pass + elif isinstance(index_type, astroid.Slice): + # Delegate to visit_slice. A slice can be present + # here after inferring the index node, which could + # be a `slice(...)` call for instance. + return self.visit_slice(index_type) + + # Anything else is an error + self.add_message("invalid-sequence-index", node=node) + return None + + @check_messages("invalid-slice-index") + def visit_slice(self, node): + # Check the type of each part of the slice + invalid_slices = 0 + for index in (node.lower, node.upper, node.step): + if index is None: + continue + + index_type = safe_infer(index) + if index_type is None or index_type is astroid.Uninferable: + continue + + # Constants must of type int or None + if isinstance(index_type, astroid.Const): + if isinstance(index_type.value, (int, type(None))): + continue + # Instance values must be of type int, None or an object + # with __index__ + elif isinstance(index_type, astroid.Instance): + if index_type.pytype() in (BUILTINS + ".int", BUILTINS + ".NoneType"): + continue + + try: + index_type.getattr("__index__") + return + except exceptions.NotFoundError: + pass + invalid_slices += 1 + + if not invalid_slices: + return + + # Anything else is an error, unless the object that is indexed + # is a custom object, which knows how to handle this kind of slices + parent = node.parent + if isinstance(parent, astroid.ExtSlice): + parent = parent.parent + if isinstance(parent, astroid.Subscript): + inferred = safe_infer(parent.value) + if inferred is None or inferred is astroid.Uninferable: + # Don't know what this is + return + known_objects = ( + astroid.List, + astroid.Dict, + astroid.Tuple, + astroid.objects.FrozenSet, + astroid.Set, + ) + if not isinstance(inferred, known_objects): + # Might be an instance that knows how to handle this slice object + return + for _ in range(invalid_slices): + self.add_message("invalid-slice-index", node=node) + + @check_messages("not-context-manager") + def visit_with(self, node): + for ctx_mgr, _ in node.items: + context = astroid.context.InferenceContext() + infered = safe_infer(ctx_mgr, context=context) + if infered is None or infered is astroid.Uninferable: + continue + + if isinstance(infered, bases.Generator): + # Check if we are dealing with a function decorated + # with contextlib.contextmanager. + if decorated_with( + infered.parent, self.config.contextmanager_decorators + ): + continue + # If the parent of the generator is not the context manager itself, + # that means that it could have been returned from another + # function which was the real context manager. + # The following approach is more of a hack rather than a real + # solution: walk all the inferred statements for the + # given *ctx_mgr* and if you find one function scope + # which is decorated, consider it to be the real + # manager and give up, otherwise emit not-context-manager. + # See the test file for not_context_manager for a couple + # of self explaining tests. + + # Retrieve node from all previusly visited nodes in the the inference history + context_path_names = filter(None, _unflatten(context.path)) + inferred_paths = _flatten_container( + path.infer() for path in context_path_names + ) + for inf_path in inferred_paths: + scope = inf_path.scope() + if not isinstance(scope, astroid.FunctionDef): + continue + if decorated_with(scope, self.config.contextmanager_decorators): + break + else: + self.add_message( + "not-context-manager", node=node, args=(infered.name,) + ) + else: + try: + infered.getattr("__enter__") + infered.getattr("__exit__") + except exceptions.NotFoundError: + if isinstance(infered, astroid.Instance): + # If we do not know the bases of this class, + # just skip it. + if not has_known_bases(infered): + continue + # Just ignore mixin classes. + if self.config.ignore_mixin_members: + if infered.name[-5:].lower() == "mixin": + continue + + self.add_message( + "not-context-manager", node=node, args=(infered.name,) + ) + + @check_messages("invalid-unary-operand-type") + def visit_unaryop(self, node): + """Detect TypeErrors for unary operands.""" + + for error in node.type_errors(): + # Let the error customize its output. + self.add_message("invalid-unary-operand-type", args=str(error), node=node) + + @check_messages("unsupported-binary-operation") + def _visit_binop(self, node): + """Detect TypeErrors for binary arithmetic operands.""" + self._check_binop_errors(node) + + @check_messages("unsupported-binary-operation") + def _visit_augassign(self, node): + """Detect TypeErrors for augmented binary arithmetic operands.""" + self._check_binop_errors(node) + + def _check_binop_errors(self, node): + for error in node.type_errors(): + # Let the error customize its output. + if any( + isinstance(obj, astroid.ClassDef) and not has_known_bases(obj) + for obj in (error.left_type, error.right_type) + ): + continue + self.add_message("unsupported-binary-operation", args=str(error), node=node) + + def _check_membership_test(self, node): + if is_inside_abstract_class(node): + return + if is_comprehension(node): + return + infered = safe_infer(node) + if infered is None or infered is astroid.Uninferable: + return + if not supports_membership_test(infered): + self.add_message( + "unsupported-membership-test", args=node.as_string(), node=node + ) + + @check_messages("unsupported-membership-test") + def visit_compare(self, node): + if len(node.ops) != 1: + return + + op, right = node.ops[0] + if op in ["in", "not in"]: + self._check_membership_test(right) + + @check_messages( + "unsubscriptable-object", + "unsupported-assignment-operation", + "unsupported-delete-operation", + "unhashable-dict-key", + ) + def visit_subscript(self, node): + supported_protocol = None + if isinstance(node.value, (astroid.ListComp, astroid.DictComp)): + return + + if isinstance(node.value, astroid.Dict): + # Assert dict key is hashable + inferred = safe_infer(node.slice.value) + if inferred not in (None, astroid.Uninferable): + try: + hash_fn = next(inferred.igetattr("__hash__")) + except astroid.InferenceError: + pass + else: + if getattr(hash_fn, "value", True) is None: + self.add_message("unhashable-dict-key", node=node.value) + + if node.ctx == astroid.Load: + supported_protocol = supports_getitem + msg = "unsubscriptable-object" + elif node.ctx == astroid.Store: + supported_protocol = supports_setitem + msg = "unsupported-assignment-operation" + elif node.ctx == astroid.Del: + supported_protocol = supports_delitem + msg = "unsupported-delete-operation" + + if isinstance(node.value, astroid.SetComp): + self.add_message(msg, args=node.value.as_string(), node=node.value) + return + + if is_inside_abstract_class(node): + return + + inferred = safe_infer(node.value) + if inferred is None or inferred is astroid.Uninferable: + return + + if not supported_protocol(inferred): + self.add_message(msg, args=node.value.as_string(), node=node.value) + + +class IterableChecker(BaseChecker): + """ + Checks for non-iterables used in an iterable context. + Contexts include: + - for-statement + - starargs in function call + - `yield from`-statement + - list, dict and set comprehensions + - generator expressions + Also checks for non-mappings in function call kwargs. + """ + + __implements__ = (IAstroidChecker,) + name = "iterable_check" + + msgs = { + "E1133": ( + "Non-iterable value %s is used in an iterating context", + "not-an-iterable", + "Used when a non-iterable value is used in place where " + "iterable is expected", + ), + "E1134": ( + "Non-mapping value %s is used in a mapping context", + "not-a-mapping", + "Used when a non-mapping value is used in place where " + "mapping is expected", + ), + } + + @staticmethod + def _is_asyncio_coroutine(node): + if not isinstance(node, astroid.Call): + return False + + inferred_func = safe_infer(node.func) + if not isinstance(inferred_func, astroid.FunctionDef): + return False + if not inferred_func.decorators: + return False + for decorator in inferred_func.decorators.nodes: + inferred_decorator = safe_infer(decorator) + if not isinstance(inferred_decorator, astroid.FunctionDef): + continue + if inferred_decorator.qname() != ASYNCIO_COROUTINE: + continue + return True + return False + + def _check_iterable(self, node, check_async=False): + if is_inside_abstract_class(node) or is_comprehension(node): + return + inferred = safe_infer(node) + if not inferred: + return + if not is_iterable(inferred, check_async=check_async): + self.add_message("not-an-iterable", args=node.as_string(), node=node) + + def _check_mapping(self, node): + if is_inside_abstract_class(node): + return + if isinstance(node, astroid.DictComp): + return + infered = safe_infer(node) + if infered is None or infered is astroid.Uninferable: + return + if not is_mapping(infered): + self.add_message("not-a-mapping", args=node.as_string(), node=node) + + @check_messages("not-an-iterable") + def visit_for(self, node): + self._check_iterable(node.iter) + + @check_messages("not-an-iterable") + def visit_asyncfor(self, node): + self._check_iterable(node.iter, check_async=True) + + @check_messages("not-an-iterable") + def visit_yieldfrom(self, node): + # TODO: hack which can be removed once we support decorators inference + if self._is_asyncio_coroutine(node.value): + return + self._check_iterable(node.value) + + @check_messages("not-an-iterable", "not-a-mapping") + def visit_call(self, node): + for stararg in node.starargs: + self._check_iterable(stararg.value) + for kwarg in node.kwargs: + self._check_mapping(kwarg.value) + + @check_messages("not-an-iterable") + def visit_listcomp(self, node): + for gen in node.generators: + self._check_iterable(gen.iter, check_async=gen.is_async) + + @check_messages("not-an-iterable") + def visit_dictcomp(self, node): + for gen in node.generators: + self._check_iterable(gen.iter) + + @check_messages("not-an-iterable") + def visit_setcomp(self, node): + for gen in node.generators: + self._check_iterable(gen.iter) + + @check_messages("not-an-iterable") + def visit_generatorexp(self, node): + for gen in node.generators: + self._check_iterable(gen.iter) + + +def register(linter): + """required method to auto register this checker """ + linter.register_checker(TypeChecker(linter)) + linter.register_checker(IterableChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/utils.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/utils.py new file mode 100644 index 0000000..98a892f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/utils.py @@ -0,0 +1,1215 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2007, 2009-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2009 Mads Kiilerich <mads@kiilerich.com> +# Copyright (c) 2010 Daniel Harding <dharding@gmail.com> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2013-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Ricardo Gemignani <ricardo.gemignani@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Radu Ciorba <radu@devrandom.ro> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016, 2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016-2017 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2016 Brian C. Lane <bcl@redhat.com> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 ttenhoeve-aa <ttenhoeve@appannie.com> +# Copyright (c) 2018 Bryce Guinta <bryce.guinta@protonmail.com> +# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Copyright (c) 2018 Brian Shaginaw <brian.shaginaw@warbyparker.com> +# Copyright (c) 2018 Caio Carrara <ccarrara@redhat.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +# pylint: disable=W0611 +"""some functions that may be useful for various checkers +""" +import builtins +from functools import lru_cache, partial, singledispatch +import itertools +import numbers +import re +import sys +import string +from typing import ( + Optional, + Iterable, + Tuple, + Callable, + Set, + Union, + Match, + Dict, + List, + Type, +) +import _string # pylint: disable=wrong-import-position, wrong-import-order + +import astroid +from astroid import bases as _bases +from astroid import scoped_nodes + + +BUILTINS_NAME = builtins.__name__ +COMP_NODE_TYPES = ( + astroid.ListComp, + astroid.SetComp, + astroid.DictComp, + astroid.GeneratorExp, +) +PY3K = sys.version_info[0] == 3 + +if not PY3K: + EXCEPTIONS_MODULE = "exceptions" +else: + EXCEPTIONS_MODULE = "builtins" +ABC_METHODS = { + "abc.abstractproperty", + "abc.abstractmethod", + "abc.abstractclassmethod", + "abc.abstractstaticmethod", +} +ITER_METHOD = "__iter__" +AITER_METHOD = "__aiter__" +NEXT_METHOD = "__next__" +GETITEM_METHOD = "__getitem__" +SETITEM_METHOD = "__setitem__" +DELITEM_METHOD = "__delitem__" +CONTAINS_METHOD = "__contains__" +KEYS_METHOD = "keys" + +# Dictionary which maps the number of expected parameters a +# special method can have to a set of special methods. +# The following keys are used to denote the parameters restrictions: +# +# * None: variable number of parameters +# * number: exactly that number of parameters +# * tuple: this are the odd ones. Basically it means that the function +# can work with any number of arguments from that tuple, +# although it's best to implement it in order to accept +# all of them. +_SPECIAL_METHODS_PARAMS = { + None: ("__new__", "__init__", "__call__"), + 0: ( + "__del__", + "__repr__", + "__str__", + "__bytes__", + "__hash__", + "__bool__", + "__dir__", + "__len__", + "__length_hint__", + "__iter__", + "__reversed__", + "__neg__", + "__pos__", + "__abs__", + "__invert__", + "__complex__", + "__int__", + "__float__", + "__neg__", + "__pos__", + "__abs__", + "__complex__", + "__int__", + "__float__", + "__index__", + "__enter__", + "__aenter__", + "__getnewargs_ex__", + "__getnewargs__", + "__getstate__", + "__reduce__", + "__copy__", + "__unicode__", + "__nonzero__", + "__await__", + "__aiter__", + "__anext__", + "__fspath__", + ), + 1: ( + "__format__", + "__lt__", + "__le__", + "__eq__", + "__ne__", + "__gt__", + "__ge__", + "__getattr__", + "__getattribute__", + "__delattr__", + "__delete__", + "__instancecheck__", + "__subclasscheck__", + "__getitem__", + "__missing__", + "__delitem__", + "__contains__", + "__add__", + "__sub__", + "__mul__", + "__truediv__", + "__floordiv__", + "__mod__", + "__divmod__", + "__lshift__", + "__rshift__", + "__and__", + "__xor__", + "__or__", + "__radd__", + "__rsub__", + "__rmul__", + "__rtruediv__", + "__rmod__", + "__rdivmod__", + "__rpow__", + "__rlshift__", + "__rrshift__", + "__rand__", + "__rxor__", + "__ror__", + "__iadd__", + "__isub__", + "__imul__", + "__itruediv__", + "__ifloordiv__", + "__imod__", + "__ilshift__", + "__irshift__", + "__iand__", + "__ixor__", + "__ior__", + "__ipow__", + "__setstate__", + "__reduce_ex__", + "__deepcopy__", + "__cmp__", + "__matmul__", + "__rmatmul__", + "__div__", + ), + 2: ("__setattr__", "__get__", "__set__", "__setitem__", "__set_name__"), + 3: ("__exit__", "__aexit__"), + (0, 1): ("__round__",), +} + +SPECIAL_METHODS_PARAMS = { + name: params + for params, methods in _SPECIAL_METHODS_PARAMS.items() + for name in methods # type: ignore +} +PYMETHODS = set(SPECIAL_METHODS_PARAMS) + + +class NoSuchArgumentError(Exception): + pass + + +def is_inside_except(node): + """Returns true if node is inside the name of an except handler.""" + current = node + while current and not isinstance(current.parent, astroid.ExceptHandler): + current = current.parent + + return current and current is current.parent.name + + +def is_inside_lambda(node: astroid.node_classes.NodeNG) -> bool: + """Return true if given node is inside lambda""" + parent = node.parent + while parent is not None: + if isinstance(parent, astroid.Lambda): + return True + parent = parent.parent + return False + + +def get_all_elements( + node: astroid.node_classes.NodeNG +) -> Iterable[astroid.node_classes.NodeNG]: + """Recursively returns all atoms in nested lists and tuples.""" + if isinstance(node, (astroid.Tuple, astroid.List)): + for child in node.elts: + for e in get_all_elements(child): + yield e + else: + yield node + + +def clobber_in_except( + node: astroid.node_classes.NodeNG +) -> Tuple[bool, Tuple[str, str]]: + """Checks if an assignment node in an except handler clobbers an existing + variable. + + Returns (True, args for W0623) if assignment clobbers an existing variable, + (False, None) otherwise. + """ + if isinstance(node, astroid.AssignAttr): + return True, (node.attrname, "object %r" % (node.expr.as_string(),)) + if isinstance(node, astroid.AssignName): + name = node.name + if is_builtin(name): + return (True, (name, "builtins")) + + stmts = node.lookup(name)[1] + if stmts and not isinstance( + stmts[0].assign_type(), + (astroid.Assign, astroid.AugAssign, astroid.ExceptHandler), + ): + return True, (name, "outer scope (line %s)" % stmts[0].fromlineno) + return False, None + + +def is_super(node: astroid.node_classes.NodeNG) -> bool: + """return True if the node is referencing the "super" builtin function + """ + if getattr(node, "name", None) == "super" and node.root().name == BUILTINS_NAME: + return True + return False + + +def is_error(node: astroid.node_classes.NodeNG) -> bool: + """return true if the function does nothing but raising an exception""" + for child_node in node.get_children(): + if isinstance(child_node, astroid.Raise): + return True + return False + + +builtins = builtins.__dict__.copy() # type: ignore +SPECIAL_BUILTINS = ("__builtins__",) # '__path__', '__file__') + + +def is_builtin_object(node: astroid.node_classes.NodeNG) -> bool: + """Returns True if the given node is an object from the __builtin__ module.""" + return node and node.root().name == BUILTINS_NAME + + +def is_builtin(name: str) -> bool: + """return true if <name> could be considered as a builtin defined by python + """ + return name in builtins or name in SPECIAL_BUILTINS # type: ignore + + +def is_defined_in_scope( + var_node: astroid.node_classes.NodeNG, + varname: str, + scope: astroid.node_classes.NodeNG, +) -> bool: + if isinstance(scope, astroid.If): + for node in scope.body: + if ( + isinstance(node, astroid.Assign) + and any( + isinstance(target, astroid.AssignName) and target.name == varname + for target in node.targets + ) + ) or (isinstance(node, astroid.Nonlocal) and varname in node.names): + return True + elif isinstance(scope, (COMP_NODE_TYPES, astroid.For)): + for ass_node in scope.nodes_of_class(astroid.AssignName): + if ass_node.name == varname: + return True + elif isinstance(scope, astroid.With): + for expr, ids in scope.items: + if expr.parent_of(var_node): + break + if ids and isinstance(ids, astroid.AssignName) and ids.name == varname: + return True + elif isinstance(scope, (astroid.Lambda, astroid.FunctionDef)): + if scope.args.is_argument(varname): + # If the name is found inside a default value + # of a function, then let the search continue + # in the parent's tree. + if scope.args.parent_of(var_node): + try: + scope.args.default_value(varname) + scope = scope.parent + is_defined_in_scope(var_node, varname, scope) + except astroid.NoDefault: + pass + return True + if getattr(scope, "name", None) == varname: + return True + elif isinstance(scope, astroid.ExceptHandler): + if isinstance(scope.name, astroid.AssignName): + ass_node = scope.name + if ass_node.name == varname: + return True + return False + + +def is_defined_before(var_node: astroid.node_classes.NodeNG) -> bool: + """return True if the variable node is defined by a parent node (list, + set, dict, or generator comprehension, lambda) or in a previous sibling + node on the same line (statement_defining ; statement_using) + """ + varname = var_node.name + _node = var_node.parent + while _node: + if is_defined_in_scope(var_node, varname, _node): + return True + _node = _node.parent + # possibly multiple statements on the same line using semi colon separator + stmt = var_node.statement() + _node = stmt.previous_sibling() + lineno = stmt.fromlineno + while _node and _node.fromlineno == lineno: + for assign_node in _node.nodes_of_class(astroid.AssignName): + if assign_node.name == varname: + return True + for imp_node in _node.nodes_of_class((astroid.ImportFrom, astroid.Import)): + if varname in [name[1] or name[0] for name in imp_node.names]: + return True + _node = _node.previous_sibling() + return False + + +def is_default_argument(node: astroid.node_classes.NodeNG) -> bool: + """return true if the given Name node is used in function or lambda + default argument's value + """ + parent = node.scope() + if isinstance(parent, (astroid.FunctionDef, astroid.Lambda)): + for default_node in parent.args.defaults: + for default_name_node in default_node.nodes_of_class(astroid.Name): + if default_name_node is node: + return True + return False + + +def is_func_decorator(node: astroid.node_classes.NodeNG) -> bool: + """return true if the name is used in function decorator""" + parent = node.parent + while parent is not None: + if isinstance(parent, astroid.Decorators): + return True + if parent.is_statement or isinstance( + parent, + (astroid.Lambda, scoped_nodes.ComprehensionScope, scoped_nodes.ListComp), + ): + break + parent = parent.parent + return False + + +def is_ancestor_name( + frame: astroid.node_classes.NodeNG, node: astroid.node_classes.NodeNG +) -> bool: + """return True if `frame` is an astroid.Class node with `node` in the + subtree of its bases attribute + """ + try: + bases = frame.bases + except AttributeError: + return False + for base in bases: + if node in base.nodes_of_class(astroid.Name): + return True + return False + + +def assign_parent(node: astroid.node_classes.NodeNG) -> astroid.node_classes.NodeNG: + """return the higher parent which is not an AssignName, Tuple or List node + """ + while node and isinstance(node, (astroid.AssignName, astroid.Tuple, astroid.List)): + node = node.parent + return node + + +def overrides_a_method(class_node: astroid.node_classes.NodeNG, name: str) -> bool: + """return True if <name> is a method overridden from an ancestor""" + for ancestor in class_node.ancestors(): + if name in ancestor and isinstance(ancestor[name], astroid.FunctionDef): + return True + return False + + +def check_messages(*messages: str) -> Callable: + """decorator to store messages that are handled by a checker method""" + + def store_messages(func): + func.checks_msgs = messages + return func + + return store_messages + + +class IncompleteFormatString(Exception): + """A format string ended in the middle of a format specifier.""" + + +class UnsupportedFormatCharacter(Exception): + """A format character in a format string is not one of the supported + format characters.""" + + def __init__(self, index): + Exception.__init__(self, index) + self.index = index + + +def parse_format_string( + format_string: str +) -> Tuple[Set[str], int, Dict[str, str], List[str]]: + """Parses a format string, returning a tuple of (keys, num_args), where keys + is the set of mapping keys in the format string, and num_args is the number + of arguments required by the format string. Raises + IncompleteFormatString or UnsupportedFormatCharacter if a + parse error occurs.""" + keys = set() + key_types = dict() + pos_types = [] + num_args = 0 + + def next_char(i): + i += 1 + if i == len(format_string): + raise IncompleteFormatString + return (i, format_string[i]) + + i = 0 + while i < len(format_string): + char = format_string[i] + if char == "%": + i, char = next_char(i) + # Parse the mapping key (optional). + key = None + if char == "(": + depth = 1 + i, char = next_char(i) + key_start = i + while depth != 0: + if char == "(": + depth += 1 + elif char == ")": + depth -= 1 + i, char = next_char(i) + key_end = i - 1 + key = format_string[key_start:key_end] + + # Parse the conversion flags (optional). + while char in "#0- +": + i, char = next_char(i) + # Parse the minimum field width (optional). + if char == "*": + num_args += 1 + i, char = next_char(i) + else: + while char in string.digits: + i, char = next_char(i) + # Parse the precision (optional). + if char == ".": + i, char = next_char(i) + if char == "*": + num_args += 1 + i, char = next_char(i) + else: + while char in string.digits: + i, char = next_char(i) + # Parse the length modifier (optional). + if char in "hlL": + i, char = next_char(i) + # Parse the conversion type (mandatory). + if PY3K: + flags = "diouxXeEfFgGcrs%a" + else: + flags = "diouxXeEfFgGcrs%" + if char not in flags: + raise UnsupportedFormatCharacter(i) + if key: + keys.add(key) + key_types[key] = char + elif char != "%": + num_args += 1 + pos_types.append(char) + i += 1 + return keys, num_args, key_types, pos_types + + +def split_format_field_names(format_string) -> Tuple[str, Iterable[Tuple[bool, str]]]: + try: + return _string.formatter_field_name_split(format_string) + except ValueError: + raise IncompleteFormatString() + + +def collect_string_fields(format_string) -> Iterable[Optional[str]]: + """ Given a format string, return an iterator + of all the valid format fields. It handles nested fields + as well. + """ + formatter = string.Formatter() + try: + parseiterator = formatter.parse(format_string) + for result in parseiterator: + if all(item is None for item in result[1:]): + # not a replacement format + continue + name = result[1] + nested = result[2] + yield name + if nested: + for field in collect_string_fields(nested): + yield field + except ValueError as exc: + # Probably the format string is invalid. + if exc.args[0].startswith("cannot switch from manual"): + # On Jython, parsing a string with both manual + # and automatic positions will fail with a ValueError, + # while on CPython it will simply return the fields, + # the validation being done in the interpreter (?). + # We're just returning two mixed fields in order + # to trigger the format-combined-specification check. + yield "" + yield "1" + return + raise IncompleteFormatString(format_string) + + +def parse_format_method_string( + format_string: str +) -> Tuple[List[Tuple[str, List[Tuple[bool, str]]]], int, int]: + """ + Parses a PEP 3101 format string, returning a tuple of + (keys, num_args, manual_pos_arg), + where keys is the set of mapping keys in the format string, num_args + is the number of arguments required by the format string and + manual_pos_arg is the number of arguments passed with the position. + """ + keys = [] + num_args = 0 + manual_pos_arg = set() + for name in collect_string_fields(format_string): + if name and str(name).isdigit(): + manual_pos_arg.add(str(name)) + elif name: + keyname, fielditerator = split_format_field_names(name) + if isinstance(keyname, numbers.Number): + # In Python 2 it will return long which will lead + # to different output between 2 and 3 + manual_pos_arg.add(str(keyname)) + keyname = int(keyname) + try: + keys.append((keyname, list(fielditerator))) + except ValueError: + raise IncompleteFormatString() + else: + num_args += 1 + return keys, num_args, len(manual_pos_arg) + + +def is_attr_protected(attrname: str) -> bool: + """return True if attribute name is protected (start with _ and some other + details), False otherwise. + """ + return ( + attrname[0] == "_" + and attrname != "_" + and not (attrname.startswith("__") and attrname.endswith("__")) + ) + + +def node_frame_class( + node: astroid.node_classes.NodeNG +) -> Optional[astroid.node_classes.NodeNG]: + """return klass node for a method node (or a staticmethod or a + classmethod), return null otherwise + """ + klass = node.frame() + + while klass is not None and not isinstance(klass, astroid.ClassDef): + if klass.parent is None: + klass = None + else: + klass = klass.parent.frame() + + return klass + + +def is_attr_private(attrname: str) -> Optional[Match[str]]: + """Check that attribute name is private (at least two leading underscores, + at most one trailing underscore) + """ + regex = re.compile("^_{2,}.*[^_]+_?$") + return regex.match(attrname) + + +def get_argument_from_call( + call_node: astroid.Call, position: int = None, keyword: str = None +) -> astroid.Name: + """Returns the specified argument from a function call. + + :param astroid.Call call_node: Node representing a function call to check. + :param int position: position of the argument. + :param str keyword: the keyword of the argument. + + :returns: The node representing the argument, None if the argument is not found. + :rtype: astroid.Name + :raises ValueError: if both position and keyword are None. + :raises NoSuchArgumentError: if no argument at the provided position or with + the provided keyword. + """ + if position is None and keyword is None: + raise ValueError("Must specify at least one of: position or keyword.") + if position is not None: + try: + return call_node.args[position] + except IndexError: + pass + if keyword and call_node.keywords: + for arg in call_node.keywords: + if arg.arg == keyword: + return arg.value + + raise NoSuchArgumentError + + +def inherit_from_std_ex(node: astroid.node_classes.NodeNG) -> bool: + """ + Return true if the given class node is subclass of + exceptions.Exception. + """ + if ( + node.name in ("Exception", "BaseException") + and node.root().name == EXCEPTIONS_MODULE + ): + return True + if not hasattr(node, "ancestors"): + return False + return any(inherit_from_std_ex(parent) for parent in node.ancestors(recurs=True)) + + +def error_of_type(handler: astroid.ExceptHandler, error_type) -> bool: + """ + Check if the given exception handler catches + the given error_type. + + The *handler* parameter is a node, representing an ExceptHandler node. + The *error_type* can be an exception, such as AttributeError, + the name of an exception, or it can be a tuple of errors. + The function will return True if the handler catches any of the + given errors. + """ + + def stringify_error(error): + if not isinstance(error, str): + return error.__name__ + return error + + if not isinstance(error_type, tuple): + error_type = (error_type,) # type: ignore + expected_errors = {stringify_error(error) for error in error_type} # type: ignore + if not handler.type: + return True + return handler.catch(expected_errors) + + +def decorated_with_property(node: astroid.FunctionDef) -> bool: + """ Detect if the given function node is decorated with a property. """ + if not node.decorators: + return False + for decorator in node.decorators.nodes: + if not isinstance(decorator, astroid.Name): + continue + try: + if _is_property_decorator(decorator): + return True + except astroid.InferenceError: + pass + return False + + +def _is_property_decorator(decorator: astroid.Name) -> bool: + for infered in decorator.infer(): + if isinstance(infered, astroid.ClassDef): + if infered.root().name == BUILTINS_NAME and infered.name == "property": + return True + for ancestor in infered.ancestors(): + if ( + ancestor.name == "property" + and ancestor.root().name == BUILTINS_NAME + ): + return True + return False + + +def decorated_with(func: astroid.FunctionDef, qnames: Iterable[str]) -> bool: + """Determine if the `func` node has a decorator with the qualified name `qname`.""" + decorators = func.decorators.nodes if func.decorators else [] + for decorator_node in decorators: + try: + if any( + i is not None and i.qname() in qnames for i in decorator_node.infer() + ): + return True + except astroid.InferenceError: + continue + return False + + +@lru_cache(maxsize=1024) +def unimplemented_abstract_methods( + node: astroid.node_classes.NodeNG, is_abstract_cb: astroid.FunctionDef = None +) -> Dict[str, astroid.node_classes.NodeNG]: + """ + Get the unimplemented abstract methods for the given *node*. + + A method can be considered abstract if the callback *is_abstract_cb* + returns a ``True`` value. The check defaults to verifying that + a method is decorated with abstract methods. + The function will work only for new-style classes. For old-style + classes, it will simply return an empty dictionary. + For the rest of them, it will return a dictionary of abstract method + names and their inferred objects. + """ + if is_abstract_cb is None: + is_abstract_cb = partial(decorated_with, qnames=ABC_METHODS) + visited = {} # type: Dict[str, astroid.node_classes.NodeNG] + try: + mro = reversed(node.mro()) + except NotImplementedError: + # Old style class, it will not have a mro. + return {} + except astroid.ResolveError: + # Probably inconsistent hierarchy, don'try + # to figure this out here. + return {} + for ancestor in mro: + for obj in ancestor.values(): + infered = obj + if isinstance(obj, astroid.AssignName): + infered = safe_infer(obj) + if not infered: + # Might be an abstract function, + # but since we don't have enough information + # in order to take this decision, we're taking + # the *safe* decision instead. + if obj.name in visited: + del visited[obj.name] + continue + if not isinstance(infered, astroid.FunctionDef): + if obj.name in visited: + del visited[obj.name] + if isinstance(infered, astroid.FunctionDef): + # It's critical to use the original name, + # since after inferring, an object can be something + # else than expected, as in the case of the + # following assignment. + # + # class A: + # def keys(self): pass + # __iter__ = keys + abstract = is_abstract_cb(infered) + if abstract: + visited[obj.name] = infered + elif not abstract and obj.name in visited: + del visited[obj.name] + return visited + + +def find_try_except_wrapper_node( + node: astroid.node_classes.NodeNG +) -> Union[astroid.ExceptHandler, astroid.TryExcept]: + """Return the ExceptHandler or the TryExcept node in which the node is.""" + current = node + ignores = (astroid.ExceptHandler, astroid.TryExcept) + while current and not isinstance(current.parent, ignores): + current = current.parent + + if current and isinstance(current.parent, ignores): + return current.parent + return None + + +def is_from_fallback_block(node: astroid.node_classes.NodeNG) -> bool: + """Check if the given node is from a fallback import block.""" + context = find_try_except_wrapper_node(node) + if not context: + return False + + if isinstance(context, astroid.ExceptHandler): + other_body = context.parent.body + handlers = context.parent.handlers + else: + other_body = itertools.chain.from_iterable( + handler.body for handler in context.handlers + ) + handlers = context.handlers + + has_fallback_imports = any( + isinstance(import_node, (astroid.ImportFrom, astroid.Import)) + for import_node in other_body + ) + ignores_import_error = _except_handlers_ignores_exception(handlers, ImportError) + return ignores_import_error or has_fallback_imports + + +def _except_handlers_ignores_exception( + handlers: astroid.ExceptHandler, exception +) -> bool: + func = partial(error_of_type, error_type=(exception,)) + return any(map(func, handlers)) + + +def get_exception_handlers( + node: astroid.node_classes.NodeNG, exception=Exception +) -> List[astroid.ExceptHandler]: + """Return the collections of handlers handling the exception in arguments. + + Args: + node (astroid.NodeNG): A node that is potentially wrapped in a try except. + exception (builtin.Exception or str): exception or name of the exception. + + Returns: + list: the collection of handlers that are handling the exception or None. + + """ + context = find_try_except_wrapper_node(node) + if isinstance(context, astroid.TryExcept): + return [ + handler for handler in context.handlers if error_of_type(handler, exception) + ] + return None + + +def is_node_inside_try_except(node: astroid.Raise) -> bool: + """Check if the node is directly under a Try/Except statement. + (but not under an ExceptHandler!) + + Args: + node (astroid.Raise): the node raising the exception. + + Returns: + bool: True if the node is inside a try/except statement, False otherwise. + """ + context = find_try_except_wrapper_node(node) + return isinstance(context, astroid.TryExcept) + + +def node_ignores_exception( + node: astroid.node_classes.NodeNG, exception=Exception +) -> bool: + """Check if the node is in a TryExcept which handles the given exception. + + If the exception is not given, the function is going to look for bare + excepts. + """ + managing_handlers = get_exception_handlers(node, exception) + if not managing_handlers: + return False + return any(managing_handlers) + + +def class_is_abstract(node: astroid.ClassDef) -> bool: + """return true if the given class node should be considered as an abstract + class + """ + for method in node.methods(): + if method.parent.frame() is node: + if method.is_abstract(pass_is_abstract=False): + return True + return False + + +def _supports_protocol_method(value: astroid.node_classes.NodeNG, attr: str) -> bool: + try: + attributes = value.getattr(attr) + except astroid.NotFoundError: + return False + + first = attributes[0] + if isinstance(first, astroid.AssignName): + if isinstance(first.parent.value, astroid.Const): + return False + return True + + +def is_comprehension(node: astroid.node_classes.NodeNG) -> bool: + comprehensions = ( + astroid.ListComp, + astroid.SetComp, + astroid.DictComp, + astroid.GeneratorExp, + ) + return isinstance(node, comprehensions) + + +def _supports_mapping_protocol(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol_method( + value, GETITEM_METHOD + ) and _supports_protocol_method(value, KEYS_METHOD) + + +def _supports_membership_test_protocol(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol_method(value, CONTAINS_METHOD) + + +def _supports_iteration_protocol(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol_method(value, ITER_METHOD) or _supports_protocol_method( + value, GETITEM_METHOD + ) + + +def _supports_async_iteration_protocol(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol_method(value, AITER_METHOD) + + +def _supports_getitem_protocol(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol_method(value, GETITEM_METHOD) + + +def _supports_setitem_protocol(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol_method(value, SETITEM_METHOD) + + +def _supports_delitem_protocol(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol_method(value, DELITEM_METHOD) + + +def _is_abstract_class_name(name: str) -> bool: + lname = name.lower() + is_mixin = lname.endswith("mixin") + is_abstract = lname.startswith("abstract") + is_base = lname.startswith("base") or lname.endswith("base") + return is_mixin or is_abstract or is_base + + +def is_inside_abstract_class(node: astroid.node_classes.NodeNG) -> bool: + while node is not None: + if isinstance(node, astroid.ClassDef): + if class_is_abstract(node): + return True + name = getattr(node, "name", None) + if name is not None and _is_abstract_class_name(name): + return True + node = node.parent + return False + + +def _supports_protocol( + value: astroid.node_classes.NodeNG, protocol_callback: astroid.FunctionDef +) -> bool: + if isinstance(value, astroid.ClassDef): + if not has_known_bases(value): + return True + # classobj can only be iterable if it has an iterable metaclass + meta = value.metaclass() + if meta is not None: + if protocol_callback(meta): + return True + if isinstance(value, astroid.BaseInstance): + if not has_known_bases(value): + return True + if value.has_dynamic_getattr(): + return True + if protocol_callback(value): + return True + + # TODO: this is not needed in astroid 2.0, where we can + # check the type using a virtual base class instead. + if ( + isinstance(value, _bases.Proxy) + and isinstance(value._proxied, astroid.BaseInstance) + and has_known_bases(value._proxied) + ): + value = value._proxied + return protocol_callback(value) + + return False + + +def is_iterable(value: astroid.node_classes.NodeNG, check_async: bool = False) -> bool: + if check_async: + protocol_check = _supports_async_iteration_protocol + else: + protocol_check = _supports_iteration_protocol + return _supports_protocol(value, protocol_check) + + +def is_mapping(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol(value, _supports_mapping_protocol) + + +def supports_membership_test(value: astroid.node_classes.NodeNG) -> bool: + supported = _supports_protocol(value, _supports_membership_test_protocol) + return supported or is_iterable(value) + + +def supports_getitem(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol(value, _supports_getitem_protocol) + + +def supports_setitem(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol(value, _supports_setitem_protocol) + + +def supports_delitem(value: astroid.node_classes.NodeNG) -> bool: + return _supports_protocol(value, _supports_delitem_protocol) + + +# TODO(cpopa): deprecate these or leave them as aliases? +@lru_cache(maxsize=1024) +def safe_infer( + node: astroid.node_classes.NodeNG, context=None +) -> Optional[astroid.node_classes.NodeNG]: + """Return the inferred value for the given node. + + Return None if inference failed or if there is some ambiguity (more than + one node has been inferred). + """ + try: + inferit = node.infer(context=context) + value = next(inferit) + except astroid.InferenceError: + return None + try: + next(inferit) + return None # None if there is ambiguity on the inferred node + except astroid.InferenceError: + return None # there is some kind of ambiguity + except StopIteration: + return value + + +def has_known_bases(klass: astroid.ClassDef, context=None) -> bool: + """Return true if all base classes of a class could be inferred.""" + try: + return klass._all_bases_known + except AttributeError: + pass + for base in klass.bases: + result = safe_infer(base, context=context) + # TODO: check for A->B->A->B pattern in class structure too? + if ( + not isinstance(result, astroid.ClassDef) + or result is klass + or not has_known_bases(result, context=context) + ): + klass._all_bases_known = False + return False + klass._all_bases_known = True + return True + + +def is_none(node: astroid.node_classes.NodeNG) -> bool: + return ( + node is None + or (isinstance(node, astroid.Const) and node.value is None) + or (isinstance(node, astroid.Name) and node.name == "None") + ) + + +def node_type(node: astroid.node_classes.NodeNG) -> Optional[type]: + """Return the inferred type for `node` + + If there is more than one possible type, or if inferred type is Uninferable or None, + return None + """ + # check there is only one possible type for the assign node. Else we + # don't handle it for now + types = set() + try: + for var_type in node.infer(): + if var_type == astroid.Uninferable or is_none(var_type): + continue + types.add(var_type) + if len(types) > 1: + return None + except astroid.InferenceError: + return None + return types.pop() if types else None + + +def is_registered_in_singledispatch_function(node: astroid.FunctionDef) -> bool: + """Check if the given function node is a singledispatch function.""" + + singledispatch_qnames = ( + "functools.singledispatch", + "singledispatch.singledispatch", + ) + + if not isinstance(node, astroid.FunctionDef): + return False + + decorators = node.decorators.nodes if node.decorators else [] + for decorator in decorators: + # func.register are function calls + if not isinstance(decorator, astroid.Call): + continue + + func = decorator.func + if not isinstance(func, astroid.Attribute) or func.attrname != "register": + continue + + try: + func_def = next(func.expr.infer()) + except astroid.InferenceError: + continue + + if isinstance(func_def, astroid.FunctionDef): + # pylint: disable=redundant-keyword-arg; some flow inference goes wrong here + return decorated_with(func_def, singledispatch_qnames) + + return False + + +def get_node_last_lineno(node: astroid.node_classes.NodeNG) -> int: + """ + Get the last lineno of the given node. For a simple statement this will just be node.lineno, + but for a node that has child statements (e.g. a method) this will be the lineno of the last + child statement recursively. + """ + # 'finalbody' is always the last clause in a try statement, if present + if getattr(node, "finalbody", False): + return get_node_last_lineno(node.finalbody[-1]) + # For if, while, and for statements 'orelse' is always the last clause. + # For try statements 'orelse' is the last in the absence of a 'finalbody' + if getattr(node, "orelse", False): + return get_node_last_lineno(node.orelse[-1]) + # try statements have the 'handlers' last if there is no 'orelse' or 'finalbody' + if getattr(node, "handlers", False): + return get_node_last_lineno(node.handlers[-1]) + # All compound statements have a 'body' + if getattr(node, "body", False): + return get_node_last_lineno(node.body[-1]) + # Not a compound statement + return node.lineno + + +def is_postponed_evaluation_enabled(node: astroid.node_classes.NodeNG) -> bool: + """Check if the postponed evaluation of annotations is enabled""" + name = "annotations" + module = node.root() + stmt = module.locals.get(name) + return ( + stmt + and isinstance(stmt[0], astroid.ImportFrom) + and stmt[0].modname == "__future__" + ) + + +def is_subclass_of(child: astroid.ClassDef, parent: astroid.ClassDef) -> bool: + """ + Check if first node is a subclass of second node. + :param child: Node to check for subclass. + :param parent: Node to check for superclass. + :returns: True if child is derived from parent. False otherwise. + """ + if not all(isinstance(node, astroid.ClassDef) for node in (child, parent)): + return False + + for ancestor in child.ancestors(): + if astroid.helpers.is_subtype(ancestor, parent): + return True + return False diff --git a/basic python programmes/venv/Lib/site-packages/pylint/checkers/variables.py b/basic python programmes/venv/Lib/site-packages/pylint/checkers/variables.py new file mode 100644 index 0000000..5b1bce9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/checkers/variables.py @@ -0,0 +1,1850 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2009 Mads Kiilerich <mads@kiilerich.com> +# Copyright (c) 2010 Daniel Harding <dharding@gmail.com> +# Copyright (c) 2011-2014, 2017 Google, Inc. +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2013-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Ricardo Gemignani <ricardo.gemignani@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Radu Ciorba <radu@devrandom.ro> +# Copyright (c) 2015 Simu Toni <simutoni@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016, 2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016, 2018 Jakub Wilk <jwilk@jwilk.net> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Grant Welch <gwelch925+github@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Dan Garrette <dhgarrette@gmail.com> +# Copyright (c) 2018 Bryce Guinta <bryce.guinta@protonmail.com> +# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Marianna Polatoglou <mpolatoglou@bloomberg.net> +# Copyright (c) 2018 mar-chi-pan <mar.polatoglou@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""variables checkers for Python code +""" +import copy +from functools import lru_cache +import itertools +import collections +import os +import sys +import re + +import astroid +from astroid import decorators +from astroid import modutils +from astroid import objects + +from pylint.checkers.utils import is_postponed_evaluation_enabled +from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE, HIGH +from pylint.utils import get_global_option +from pylint.checkers import BaseChecker +from pylint.checkers import utils + + +SPECIAL_OBJ = re.compile("^_{2}[a-z]+_{2}$") +FUTURE = "__future__" +# regexp for ignored argument name +IGNORED_ARGUMENT_NAMES = re.compile("_.*|^ignored_|^unused_") +PY3K = sys.version_info >= (3, 0) +# In Python 3.7 abc has a Python implementation which is preferred +# by astroid. Unfortunately this also messes up our explicit checks +# for `abc` +METACLASS_NAME_TRANSFORMS = {"_py_abc": "abc"} +TYPING_TYPE_CHECKS_GUARDS = frozenset({"typing.TYPE_CHECKING", "TYPE_CHECKING"}) +BUILTIN_RANGE = "builtins.range" + + +def _is_from_future_import(stmt, name): + """Check if the name is a future import from another module.""" + try: + module = stmt.do_import_module(stmt.modname) + except astroid.AstroidBuildingException: + return None + + for local_node in module.locals.get(name, []): + if isinstance(local_node, astroid.ImportFrom) and local_node.modname == FUTURE: + return True + return None + + +def in_for_else_branch(parent, stmt): + """Returns True if stmt in inside the else branch for a parent For stmt.""" + return isinstance(parent, astroid.For) and any( + else_stmt.parent_of(stmt) or else_stmt == stmt for else_stmt in parent.orelse + ) + + +@lru_cache(maxsize=1000) +def overridden_method(klass, name): + """get overridden method if any""" + try: + parent = next(klass.local_attr_ancestors(name)) + except (StopIteration, KeyError): + return None + try: + meth_node = parent[name] + except KeyError: + # We have found an ancestor defining <name> but it's not in the local + # dictionary. This may happen with astroid built from living objects. + return None + if isinstance(meth_node, astroid.FunctionDef): + return meth_node + return None + + +def _get_unpacking_extra_info(node, infered): + """return extra information to add to the message for unpacking-non-sequence + and unbalanced-tuple-unpacking errors + """ + more = "" + infered_module = infered.root().name + if node.root().name == infered_module: + if node.lineno == infered.lineno: + more = " %s" % infered.as_string() + elif infered.lineno: + more = " defined at line %s" % infered.lineno + elif infered.lineno: + more = " defined at line %s of %s" % (infered.lineno, infered_module) + return more + + +def _detect_global_scope(node, frame, defframe): + """ Detect that the given frames shares a global + scope. + + Two frames shares a global scope when neither + of them are hidden under a function scope, as well + as any of parent scope of them, until the root scope. + In this case, depending from something defined later on + will not work, because it is still undefined. + + Example: + class A: + # B has the same global scope as `C`, leading to a NameError. + class B(C): ... + class C: ... + + """ + def_scope = scope = None + if frame and frame.parent: + scope = frame.parent.scope() + if defframe and defframe.parent: + def_scope = defframe.parent.scope() + if isinstance(frame, astroid.FunctionDef): + # If the parent of the current node is a + # function, then it can be under its scope + # (defined in, which doesn't concern us) or + # the `->` part of annotations. The same goes + # for annotations of function arguments, they'll have + # their parent the Arguments node. + if not isinstance(node.parent, (astroid.FunctionDef, astroid.Arguments)): + return False + elif any( + not isinstance(f, (astroid.ClassDef, astroid.Module)) for f in (frame, defframe) + ): + # Not interested in other frames, since they are already + # not in a global scope. + return False + + break_scopes = [] + for s in (scope, def_scope): + # Look for parent scopes. If there is anything different + # than a module or a class scope, then they frames don't + # share a global scope. + parent_scope = s + while parent_scope: + if not isinstance(parent_scope, (astroid.ClassDef, astroid.Module)): + break_scopes.append(parent_scope) + break + if parent_scope.parent: + parent_scope = parent_scope.parent.scope() + else: + break + if break_scopes and len(set(break_scopes)) != 1: + # Store different scopes than expected. + # If the stored scopes are, in fact, the very same, then it means + # that the two frames (frame and defframe) shares the same scope, + # and we could apply our lineno analysis over them. + # For instance, this works when they are inside a function, the node + # that uses a definition and the definition itself. + return False + # At this point, we are certain that frame and defframe shares a scope + # and the definition of the first depends on the second. + return frame.lineno < defframe.lineno + + +def _fix_dot_imports(not_consumed): + """ Try to fix imports with multiple dots, by returning a dictionary + with the import names expanded. The function unflattens root imports, + like 'xml' (when we have both 'xml.etree' and 'xml.sax'), to 'xml.etree' + and 'xml.sax' respectively. + """ + # TODO: this should be improved in issue astroid #46 + names = {} + for name, stmts in not_consumed.items(): + if any( + isinstance(stmt, astroid.AssignName) + and isinstance(stmt.assign_type(), astroid.AugAssign) + for stmt in stmts + ): + continue + for stmt in stmts: + if not isinstance(stmt, (astroid.ImportFrom, astroid.Import)): + continue + for imports in stmt.names: + second_name = None + if imports[0] == "*": + # In case of wildcard imports, + # pick the name from inside the imported module. + second_name = name + else: + if imports[0].find(".") > -1 or name in imports: + # Most likely something like 'xml.etree', + # which will appear in the .locals as 'xml'. + # Only pick the name if it wasn't consumed. + second_name = imports[0] + if second_name and second_name not in names: + names[second_name] = stmt + return sorted(names.items(), key=lambda a: a[1].fromlineno) + + +def _find_frame_imports(name, frame): + """ + Detect imports in the frame, with the required + *name*. Such imports can be considered assignments. + Returns True if an import for the given name was found. + """ + imports = frame.nodes_of_class((astroid.Import, astroid.ImportFrom)) + for import_node in imports: + for import_name, import_alias in import_node.names: + # If the import uses an alias, check only that. + # Otherwise, check only the import name. + if import_alias: + if import_alias == name: + return True + elif import_name and import_name == name: + return True + return None + + +def _import_name_is_global(stmt, global_names): + for import_name, import_alias in stmt.names: + # If the import uses an alias, check only that. + # Otherwise, check only the import name. + if import_alias: + if import_alias in global_names: + return True + elif import_name in global_names: + return True + return False + + +def _flattened_scope_names(iterator): + values = (set(stmt.names) for stmt in iterator) + return set(itertools.chain.from_iterable(values)) + + +def _assigned_locally(name_node): + """ + Checks if name_node has corresponding assign statement in same scope + """ + assign_stmts = name_node.scope().nodes_of_class(astroid.AssignName) + return any(a.name == name_node.name for a in assign_stmts) + + +def _has_locals_call_after_node(stmt, scope): + skip_nodes = ( + astroid.FunctionDef, + astroid.ClassDef, + astroid.Import, + astroid.ImportFrom, + ) + for call in scope.nodes_of_class(astroid.Call, skip_klass=skip_nodes): + inferred = utils.safe_infer(call.func) + if ( + utils.is_builtin_object(inferred) + and getattr(inferred, "name", None) == "locals" + ): + if stmt.lineno < call.lineno: + return True + return False + + +MSGS = { + "E0601": ( + "Using variable %r before assignment", + "used-before-assignment", + "Used when a local variable is accessed before its assignment.", + ), + "E0602": ( + "Undefined variable %r", + "undefined-variable", + "Used when an undefined variable is accessed.", + ), + "E0603": ( + "Undefined variable name %r in __all__", + "undefined-all-variable", + "Used when an undefined variable name is referenced in __all__.", + ), + "E0604": ( + "Invalid object %r in __all__, must contain only strings", + "invalid-all-object", + "Used when an invalid (non-string) object occurs in __all__.", + ), + "E0611": ( + "No name %r in module %r", + "no-name-in-module", + "Used when a name cannot be found in a module.", + ), + "W0601": ( + "Global variable %r undefined at the module level", + "global-variable-undefined", + 'Used when a variable is defined through the "global" statement ' + "but the variable is not defined in the module scope.", + ), + "W0602": ( + "Using global for %r but no assignment is done", + "global-variable-not-assigned", + 'Used when a variable is defined through the "global" statement ' + "but no assignment to this variable is done.", + ), + "W0603": ( + "Using the global statement", # W0121 + "global-statement", + 'Used when you use the "global" statement to update a global ' + "variable. Pylint just try to discourage this " + "usage. That doesn't mean you cannot use it !", + ), + "W0604": ( + "Using the global statement at the module level", # W0103 + "global-at-module-level", + 'Used when you use the "global" statement at the module level ' + "since it has no effect", + ), + "W0611": ( + "Unused %s", + "unused-import", + "Used when an imported module or variable is not used.", + ), + "W0612": ( + "Unused variable %r", + "unused-variable", + "Used when a variable is defined but not used.", + ), + "W0613": ( + "Unused argument %r", + "unused-argument", + "Used when a function or method argument is not used.", + ), + "W0614": ( + "Unused import %s from wildcard import", + "unused-wildcard-import", + "Used when an imported module or variable is not used from a " + "`'from X import *'` style import.", + ), + "W0621": ( + "Redefining name %r from outer scope (line %s)", + "redefined-outer-name", + "Used when a variable's name hides a name defined in the outer scope.", + ), + "W0622": ( + "Redefining built-in %r", + "redefined-builtin", + "Used when a variable or function override a built-in.", + ), + "W0623": ( + "Redefining name %r from %s in exception handler", + "redefine-in-handler", + "Used when an exception handler assigns the exception to an existing name", + ), + "W0631": ( + "Using possibly undefined loop variable %r", + "undefined-loop-variable", + "Used when a loop variable (i.e. defined by a for loop or " + "a list comprehension or a generator expression) is used outside " + "the loop.", + ), + "W0632": ( + "Possible unbalanced tuple unpacking with " + "sequence%s: " + "left side has %d label(s), right side has %d value(s)", + "unbalanced-tuple-unpacking", + "Used when there is an unbalanced tuple unpacking in assignment", + {"old_names": [("E0632", "unbalanced-tuple-unpacking")]}, + ), + "E0633": ( + "Attempting to unpack a non-sequence%s", + "unpacking-non-sequence", + "Used when something which is not " + "a sequence is used in an unpack assignment", + {"old_names": [("W0633", "unpacking-non-sequence")]}, + ), + "W0640": ( + "Cell variable %s defined in loop", + "cell-var-from-loop", + "A variable used in a closure is defined in a loop. " + "This will result in all closures using the same value for " + "the closed-over variable.", + ), + "W0641": ( + "Possibly unused variable %r", + "possibly-unused-variable", + "Used when a variable is defined but might not be used. " + "The possibility comes from the fact that locals() might be used, " + "which could consume or not the said variable", + ), + "W0642": ( + "Invalid assignment to %s in method", + "self-cls-assignment", + "Invalid assignment to self or cls in instance or class method " + "respectively.", + ), +} + + +ScopeConsumer = collections.namedtuple( + "ScopeConsumer", "to_consume consumed scope_type" +) + + +class NamesConsumer: + """ + A simple class to handle consumed, to consume and scope type info of node locals + """ + + def __init__(self, node, scope_type): + self._atomic = ScopeConsumer(copy.copy(node.locals), {}, scope_type) + + def __repr__(self): + msg = "\nto_consume : {:s}\n".format( + ", ".join( + [ + "{}->{}".format(key, val) + for key, val in self._atomic.to_consume.items() + ] + ) + ) + msg += "consumed : {:s}\n".format( + ", ".join( + [ + "{}->{}".format(key, val) + for key, val in self._atomic.consumed.items() + ] + ) + ) + msg += "scope_type : {:s}\n".format(self._atomic.scope_type) + return msg + + def __iter__(self): + return iter(self._atomic) + + @property + def to_consume(self): + return self._atomic.to_consume + + @property + def consumed(self): + return self._atomic.consumed + + @property + def scope_type(self): + return self._atomic.scope_type + + def mark_as_consumed(self, name, new_node): + """ + Mark the name as consumed and delete it from + the to_consume dictionary + """ + self.consumed[name] = new_node + del self.to_consume[name] + + def get_next_to_consume(self, node): + # mark the name as consumed if it's defined in this scope + name = node.name + parent_node = node.parent + found_node = self.to_consume.get(name) + if ( + found_node + and isinstance(parent_node, astroid.Assign) + and parent_node == found_node[0].parent + ): + lhs = found_node[0].parent.targets[0] + if lhs.name == name: # this name is defined in this very statement + found_node = None + return found_node + + +class VariablesChecker(BaseChecker): + """checks for + * unused variables / imports + * undefined variables + * redefinition of variable from builtins or from an outer scope + * use of variable before assignment + * __all__ consistency + * self/cls assignment + """ + + __implements__ = IAstroidChecker + + name = "variables" + msgs = MSGS + priority = -1 + options = ( + ( + "init-import", + { + "default": 0, + "type": "yn", + "metavar": "<y_or_n>", + "help": "Tells whether we should check for unused import in " + "__init__ files.", + }, + ), + ( + "dummy-variables-rgx", + { + "default": "_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_", + "type": "regexp", + "metavar": "<regexp>", + "help": "A regular expression matching the name of dummy " + "variables (i.e. expected to not be used).", + }, + ), + ( + "additional-builtins", + { + "default": (), + "type": "csv", + "metavar": "<comma separated list>", + "help": "List of additional names supposed to be defined in " + "builtins. Remember that you should avoid defining new builtins " + "when possible.", + }, + ), + ( + "callbacks", + { + "default": ("cb_", "_cb"), + "type": "csv", + "metavar": "<callbacks>", + "help": "List of strings which can identify a callback " + "function by name. A callback name must start or " + "end with one of those strings.", + }, + ), + ( + "redefining-builtins-modules", + { + "default": ( + "six.moves", + "past.builtins", + "future.builtins", + "builtins", + "io", + ), + "type": "csv", + "metavar": "<comma separated list>", + "help": "List of qualified module names which can have objects " + "that can redefine builtins.", + }, + ), + ( + "ignored-argument-names", + { + "default": IGNORED_ARGUMENT_NAMES, + "type": "regexp", + "metavar": "<regexp>", + "help": "Argument names that match this expression will be " + "ignored. Default to name with leading underscore.", + }, + ), + ( + "allow-global-unused-variables", + { + "default": True, + "type": "yn", + "metavar": "<y_or_n>", + "help": "Tells whether unused global variables should be treated as a violation.", + }, + ), + ) + + def __init__(self, linter=None): + BaseChecker.__init__(self, linter) + self._to_consume = ( + None + ) # list of tuples: (to_consume:dict, consumed:dict, scope_type:str) + self._checking_mod_attr = None + self._loop_variables = [] + self._type_annotation_names = [] + self._postponed_evaluation_enabled = False + + # Relying on other checker's options, which might not have been initialized yet. + @decorators.cachedproperty + def _analyse_fallback_blocks(self): + return get_global_option(self, "analyse-fallback-blocks", default=False) + + @decorators.cachedproperty + def _ignored_modules(self): + return get_global_option(self, "ignored-modules", default=[]) + + @decorators.cachedproperty + def _allow_global_unused_variables(self): + return get_global_option(self, "allow-global-unused-variables", default=True) + + @utils.check_messages("redefined-outer-name") + def visit_for(self, node): + assigned_to = [ + var.name for var in node.target.nodes_of_class(astroid.AssignName) + ] + + # Only check variables that are used + dummy_rgx = self.config.dummy_variables_rgx + assigned_to = [var for var in assigned_to if not dummy_rgx.match(var)] + + for variable in assigned_to: + for outer_for, outer_variables in self._loop_variables: + if variable in outer_variables and not in_for_else_branch( + outer_for, node + ): + self.add_message( + "redefined-outer-name", + args=(variable, outer_for.fromlineno), + node=node, + ) + break + + self._loop_variables.append((node, assigned_to)) + + @utils.check_messages("redefined-outer-name") + def leave_for(self, node): + self._loop_variables.pop() + self._store_type_annotation_names(node) + + def visit_module(self, node): + """visit module : update consumption analysis variable + checks globals doesn't overrides builtins + """ + self._to_consume = [NamesConsumer(node, "module")] + self._postponed_evaluation_enabled = is_postponed_evaluation_enabled(node) + + for name, stmts in node.locals.items(): + if utils.is_builtin(name) and not utils.is_inside_except(stmts[0]): + if self._should_ignore_redefined_builtin(stmts[0]) or name == "__doc__": + continue + self.add_message("redefined-builtin", args=name, node=stmts[0]) + + @utils.check_messages( + "unused-import", + "unused-wildcard-import", + "redefined-builtin", + "undefined-all-variable", + "invalid-all-object", + "unused-variable", + ) + def leave_module(self, node): + """leave module: check globals + """ + assert len(self._to_consume) == 1 + not_consumed = self._to_consume.pop().to_consume + # attempt to check for __all__ if defined + if "__all__" in node.locals: + self._check_all(node, not_consumed) + + # check for unused globals + self._check_globals(not_consumed) + + # don't check unused imports in __init__ files + if not self.config.init_import and node.package: + return + + self._check_imports(not_consumed) + + def _check_all(self, node, not_consumed): + assigned = next(node.igetattr("__all__")) + if assigned is astroid.Uninferable: + return + + for elt in getattr(assigned, "elts", ()): + try: + elt_name = next(elt.infer()) + except astroid.InferenceError: + continue + if elt_name is astroid.Uninferable: + continue + if not elt_name.parent: + continue + + if not isinstance(elt_name, astroid.Const) or not isinstance( + elt_name.value, str + ): + self.add_message("invalid-all-object", args=elt.as_string(), node=elt) + continue + + elt_name = elt_name.value + # If elt is in not_consumed, remove it from not_consumed + if elt_name in not_consumed: + del not_consumed[elt_name] + continue + + if elt_name not in node.locals: + if not node.package: + self.add_message( + "undefined-all-variable", args=(elt_name,), node=elt + ) + else: + basename = os.path.splitext(node.file)[0] + if os.path.basename(basename) == "__init__": + name = node.name + "." + elt_name + try: + modutils.file_from_modpath(name.split(".")) + except ImportError: + self.add_message( + "undefined-all-variable", args=(elt_name,), node=elt + ) + except SyntaxError: + # don't yield a syntax-error warning, + # because it will be later yielded + # when the file will be checked + pass + + @staticmethod + def _is_type_checking_import(node): + parent = node.parent + if not isinstance(parent, astroid.If): + return False + test = parent.test + return test.as_string() in TYPING_TYPE_CHECKS_GUARDS + + def _check_globals(self, not_consumed): + if self._allow_global_unused_variables: + return + for name, nodes in not_consumed.items(): + for node in nodes: + self.add_message("unused-variable", args=(name,), node=node) + + def _check_imports(self, not_consumed): + local_names = _fix_dot_imports(not_consumed) + checked = set() + for name, stmt in local_names: + for imports in stmt.names: + real_name = imported_name = imports[0] + if imported_name == "*": + real_name = name + as_name = imports[1] + if real_name in checked: + continue + if name not in (real_name, as_name): + continue + checked.add(real_name) + + if isinstance(stmt, astroid.Import) or ( + isinstance(stmt, astroid.ImportFrom) and not stmt.modname + ): + if isinstance(stmt, astroid.ImportFrom) and SPECIAL_OBJ.search( + imported_name + ): + # Filter special objects (__doc__, __all__) etc., + # because they can be imported for exporting. + continue + if as_name == "_": + continue + if as_name is None: + msg = "import %s" % imported_name + else: + msg = "%s imported as %s" % (imported_name, as_name) + if not self._is_type_checking_import(stmt): + self.add_message("unused-import", args=msg, node=stmt) + elif isinstance(stmt, astroid.ImportFrom) and stmt.modname != FUTURE: + + if SPECIAL_OBJ.search(imported_name): + # Filter special objects (__doc__, __all__) etc., + # because they can be imported for exporting. + continue + + if _is_from_future_import(stmt, name): + # Check if the name is in fact loaded from a + # __future__ import in another module. + continue + + if imported_name in self._type_annotation_names: + # Most likely a typing import if it wasn't used so far. + continue + + if imported_name == "*": + self.add_message("unused-wildcard-import", args=name, node=stmt) + else: + if as_name is None: + msg = "%s imported from %s" % (imported_name, stmt.modname) + else: + fields = (imported_name, stmt.modname, as_name) + msg = "%s imported from %s as %s" % fields + if not self._is_type_checking_import(stmt): + self.add_message("unused-import", args=msg, node=stmt) + del self._to_consume + + def visit_classdef(self, node): + """visit class: update consumption analysis variable + """ + self._to_consume.append(NamesConsumer(node, "class")) + + def leave_classdef(self, _): + """leave class: update consumption analysis variable + """ + # do not check for not used locals here (no sense) + self._to_consume.pop() + + def visit_lambda(self, node): + """visit lambda: update consumption analysis variable + """ + self._to_consume.append(NamesConsumer(node, "lambda")) + + def leave_lambda(self, _): + """leave lambda: update consumption analysis variable + """ + # do not check for not used locals here + self._to_consume.pop() + + def visit_generatorexp(self, node): + """visit genexpr: update consumption analysis variable + """ + self._to_consume.append(NamesConsumer(node, "comprehension")) + + def leave_generatorexp(self, _): + """leave genexpr: update consumption analysis variable + """ + # do not check for not used locals here + self._to_consume.pop() + + def visit_dictcomp(self, node): + """visit dictcomp: update consumption analysis variable + """ + self._to_consume.append(NamesConsumer(node, "comprehension")) + + def leave_dictcomp(self, _): + """leave dictcomp: update consumption analysis variable + """ + # do not check for not used locals here + self._to_consume.pop() + + def visit_setcomp(self, node): + """visit setcomp: update consumption analysis variable + """ + self._to_consume.append(NamesConsumer(node, "comprehension")) + + def leave_setcomp(self, _): + """leave setcomp: update consumption analysis variable + """ + # do not check for not used locals here + self._to_consume.pop() + + def visit_functiondef(self, node): + """visit function: update consumption analysis variable and check locals + """ + self._to_consume.append(NamesConsumer(node, "function")) + if not ( + self.linter.is_message_enabled("redefined-outer-name") + or self.linter.is_message_enabled("redefined-builtin") + ): + return + globs = node.root().globals + for name, stmt in node.items(): + if utils.is_inside_except(stmt): + continue + if name in globs and not isinstance(stmt, astroid.Global): + definition = globs[name][0] + if ( + isinstance(definition, astroid.ImportFrom) + and definition.modname == FUTURE + ): + # It is a __future__ directive, not a symbol. + continue + + line = definition.fromlineno + if not self._is_name_ignored(stmt, name): + self.add_message( + "redefined-outer-name", args=(name, line), node=stmt + ) + + elif utils.is_builtin(name) and not self._should_ignore_redefined_builtin( + stmt + ): + # do not print Redefining builtin for additional builtins + self.add_message("redefined-builtin", args=name, node=stmt) + + def _is_name_ignored(self, stmt, name): + authorized_rgx = self.config.dummy_variables_rgx + if ( + isinstance(stmt, astroid.AssignName) + and isinstance(stmt.parent, astroid.Arguments) + or isinstance(stmt, astroid.Arguments) + ): + regex = self.config.ignored_argument_names + else: + regex = authorized_rgx + return regex and regex.match(name) + + def _check_is_unused(self, name, node, stmt, global_names, nonlocal_names): + # Ignore some special names specified by user configuration. + if self._is_name_ignored(stmt, name): + return + # Ignore names that were added dynamically to the Function scope + if ( + isinstance(node, astroid.FunctionDef) + and name == "__class__" + and len(node.locals["__class__"]) == 1 + and isinstance(node.locals["__class__"][0], astroid.ClassDef) + ): + return + + # Ignore names imported by the global statement. + # FIXME: should only ignore them if it's assigned latter + if isinstance(stmt, (astroid.Global, astroid.Import, astroid.ImportFrom)): + # Detect imports, assigned to global statements. + if global_names and _import_name_is_global(stmt, global_names): + return + + argnames = list( + itertools.chain(node.argnames(), [arg.name for arg in node.args.kwonlyargs]) + ) + is_method = node.is_method() + klass = node.parent.frame() + if is_method and isinstance(klass, astroid.ClassDef): + confidence = ( + INFERENCE if utils.has_known_bases(klass) else INFERENCE_FAILURE + ) + else: + confidence = HIGH + + # Care about functions with unknown argument (builtins) + if name in argnames: + if is_method: + # Don't warn for the first argument of a (non static) method + if node.type != "staticmethod" and name == argnames[0]: + return + # Don't warn for argument of an overridden method + overridden = overridden_method(klass, node.name) + if overridden is not None and name in overridden.argnames(): + return + if node.name in utils.PYMETHODS and node.name not in ( + "__init__", + "__new__", + ): + return + # Don't check callback arguments + if any( + node.name.startswith(cb) or node.name.endswith(cb) + for cb in self.config.callbacks + ): + return + # Don't check arguments of singledispatch.register function. + if utils.is_registered_in_singledispatch_function(node): + return + self.add_message( + "unused-argument", args=name, node=stmt, confidence=confidence + ) + else: + if stmt.parent and isinstance(stmt.parent, astroid.Assign): + if name in nonlocal_names: + return + + if isinstance(stmt, (astroid.Import, astroid.ImportFrom)): + # Need the complete name, which we don't have in .locals. + qname, asname = stmt.names[0] + name = asname or qname + + if _has_locals_call_after_node(stmt, node.scope()): + message_name = "possibly-unused-variable" + else: + if isinstance(stmt, astroid.Import): + if asname is not None: + msg = "%s imported as %s" % (qname, asname) + else: + msg = "import %s" % name + self.add_message("unused-import", args=msg, node=stmt) + return + elif isinstance(stmt, astroid.ImportFrom): + if asname is not None: + msg = "%s imported from %s as %s" % ( + qname, + stmt.modname, + asname, + ) + else: + msg = "%s imported from %s" % (name, stmt.modname) + self.add_message("unused-import", args=msg, node=stmt) + return + else: + message_name = "unused-variable" + self.add_message(message_name, args=name, node=stmt) + + def leave_functiondef(self, node): + """leave function: check function's locals are consumed""" + if node.type_comment_returns: + self._store_type_annotation_node(node.type_comment_returns) + if node.type_comment_args: + for argument_annotation in node.type_comment_args: + self._store_type_annotation_node(argument_annotation) + + not_consumed = self._to_consume.pop().to_consume + if not ( + self.linter.is_message_enabled("unused-variable") + or self.linter.is_message_enabled("possibly-unused-variable") + or self.linter.is_message_enabled("unused-argument") + ): + return + + # Don't check arguments of function which are only raising an exception. + if utils.is_error(node): + return + + # Don't check arguments of abstract methods or within an interface. + is_method = node.is_method() + if is_method and node.is_abstract(): + return + + global_names = _flattened_scope_names(node.nodes_of_class(astroid.Global)) + nonlocal_names = _flattened_scope_names(node.nodes_of_class(astroid.Nonlocal)) + for name, stmts in not_consumed.items(): + self._check_is_unused(name, node, stmts[0], global_names, nonlocal_names) + + visit_asyncfunctiondef = visit_functiondef + leave_asyncfunctiondef = leave_functiondef + + @utils.check_messages( + "global-variable-undefined", + "global-variable-not-assigned", + "global-statement", + "global-at-module-level", + "redefined-builtin", + ) + def visit_global(self, node): + """check names imported exists in the global scope""" + frame = node.frame() + if isinstance(frame, astroid.Module): + self.add_message("global-at-module-level", node=node) + return + + module = frame.root() + default_message = True + locals_ = node.scope().locals + for name in node.names: + try: + assign_nodes = module.getattr(name) + except astroid.NotFoundError: + # unassigned global, skip + assign_nodes = [] + + not_defined_locally_by_import = not any( + isinstance(local, astroid.node_classes.Import) + for local in locals_.get(name, ()) + ) + if not assign_nodes and not_defined_locally_by_import: + self.add_message("global-variable-not-assigned", args=name, node=node) + default_message = False + continue + + for anode in assign_nodes: + if ( + isinstance(anode, astroid.AssignName) + and anode.name in module.special_attributes + ): + self.add_message("redefined-builtin", args=name, node=node) + break + if anode.frame() is module: + # module level assignment + break + else: + if not_defined_locally_by_import: + # global undefined at the module scope + self.add_message("global-variable-undefined", args=name, node=node) + default_message = False + + if default_message: + self.add_message("global-statement", node=node) + + def _check_late_binding_closure(self, node, assignment_node): + def _is_direct_lambda_call(): + return ( + isinstance(node_scope.parent, astroid.Call) + and node_scope.parent.func is node_scope + ) + + node_scope = node.scope() + if not isinstance(node_scope, (astroid.Lambda, astroid.FunctionDef)): + return + if isinstance(node.parent, astroid.Arguments): + return + + if isinstance(assignment_node, astroid.Comprehension): + if assignment_node.parent.parent_of(node.scope()): + self.add_message("cell-var-from-loop", node=node, args=node.name) + else: + assign_scope = assignment_node.scope() + maybe_for = assignment_node + while not isinstance(maybe_for, astroid.For): + if maybe_for is assign_scope: + break + maybe_for = maybe_for.parent + else: + if ( + maybe_for.parent_of(node_scope) + and not _is_direct_lambda_call() + and not isinstance(node_scope.statement(), astroid.Return) + ): + self.add_message("cell-var-from-loop", node=node, args=node.name) + + def _loopvar_name(self, node, name): + # filter variables according to node's scope + if not self.linter.is_message_enabled("undefined-loop-variable"): + return + astmts = [stmt for stmt in node.lookup(name)[1] if hasattr(stmt, "assign_type")] + # filter variables according their respective scope test is_statement + # and parent to avoid #74747. This is not a total fix, which would + # introduce a mechanism similar to special attribute lookup in + # modules. Also, in order to get correct inference in this case, the + # scope lookup rules would need to be changed to return the initial + # assignment (which does not exist in code per se) as well as any later + # modifications. + if ( + not astmts + or (astmts[0].is_statement or astmts[0].parent) + and astmts[0].statement().parent_of(node) + ): + _astmts = [] + else: + _astmts = astmts[:1] + for i, stmt in enumerate(astmts[1:]): + if astmts[i].statement().parent_of(stmt) and not in_for_else_branch( + astmts[i].statement(), stmt + ): + continue + _astmts.append(stmt) + astmts = _astmts + if len(astmts) != 1: + return + + assign = astmts[0].assign_type() + if not ( + isinstance( + assign, (astroid.For, astroid.Comprehension, astroid.GeneratorExp) + ) + and assign.statement() is not node.statement() + ): + return + + # For functions we can do more by inferring the length of the itered object + if not isinstance(assign, astroid.For): + self.add_message("undefined-loop-variable", args=name, node=node) + return + + try: + inferred = next(assign.iter.infer()) + except astroid.InferenceError: + self.add_message("undefined-loop-variable", args=name, node=node) + else: + if ( + isinstance(inferred, astroid.Instance) + and inferred.qname() == BUILTIN_RANGE + ): + # Consider range() objects safe, even if they might not yield any results. + return + + # Consider sequences. + sequences = ( + astroid.List, + astroid.Tuple, + astroid.Dict, + astroid.Set, + objects.FrozenSet, + ) + if not isinstance(inferred, sequences): + self.add_message("undefined-loop-variable", args=name, node=node) + return + + elements = getattr(inferred, "elts", getattr(inferred, "items", [])) + if not elements: + self.add_message("undefined-loop-variable", args=name, node=node) + + def _should_ignore_redefined_builtin(self, stmt): + if not isinstance(stmt, astroid.ImportFrom): + return False + return stmt.modname in self.config.redefining_builtins_modules + + @utils.check_messages("redefine-in-handler") + def visit_excepthandler(self, node): + for name in utils.get_all_elements(node.name): + clobbering, args = utils.clobber_in_except(name) + if clobbering: + self.add_message("redefine-in-handler", args=args, node=name) + + def visit_assignname(self, node): + if isinstance(node.assign_type(), astroid.AugAssign): + self.visit_name(node) + + def visit_delname(self, node): + self.visit_name(node) + + @staticmethod + def _defined_in_function_definition(node, frame): + in_annotation_or_default = False + if isinstance(frame, astroid.FunctionDef) and node.statement() is frame: + in_annotation_or_default = ( + PY3K + and ( + node in frame.args.annotations + or node in frame.args.kwonlyargs_annotations + or node is frame.args.varargannotation + or node is frame.args.kwargannotation + ) + ) or frame.args.parent_of(node) + return in_annotation_or_default + + @staticmethod + def _is_variable_violation( + node, + name, + defnode, + stmt, + defstmt, + frame, + defframe, + base_scope_type, + recursive_klass, + ): + # node: Node to check for violation + # name: name of node to check violation for + # frame: Scope of statement of node + # base_scope_type: local scope type + maybee0601 = True + annotation_return = False + use_outer_definition = False + if frame is not defframe: + maybee0601 = _detect_global_scope(node, frame, defframe) + elif defframe.parent is None: + # we are at the module level, check the name is not + # defined in builtins + if name in defframe.scope_attrs or astroid.builtin_lookup(name)[1]: + maybee0601 = False + else: + # we are in a local scope, check the name is not + # defined in global or builtin scope + # skip this lookup if name is assigned later in function scope/lambda + # Note: the node.frame() is not the same as the `frame` argument which is + # equivalent to frame.statement().scope() + forbid_lookup = ( + isinstance(frame, astroid.FunctionDef) + or isinstance(node.frame(), astroid.Lambda) + ) and _assigned_locally(node) + if not forbid_lookup and defframe.root().lookup(name)[1]: + maybee0601 = False + use_outer_definition = stmt == defstmt and not isinstance( + defnode, astroid.node_classes.Comprehension + ) + else: + # check if we have a nonlocal + if name in defframe.locals: + maybee0601 = not any( + isinstance(child, astroid.Nonlocal) and name in child.names + for child in defframe.get_children() + ) + + if ( + base_scope_type == "lambda" + and isinstance(frame, astroid.ClassDef) + and name in frame.locals + ): + + # This rule verifies that if the definition node of the + # checked name is an Arguments node and if the name + # is used a default value in the arguments defaults + # and the actual definition of the variable label + # is happening before the Arguments definition. + # + # bar = None + # foo = lambda bar=bar: bar + # + # In this case, maybee0601 should be False, otherwise + # it should be True. + maybee0601 = not ( + isinstance(defnode, astroid.Arguments) + and node in defnode.defaults + and frame.locals[name][0].fromlineno < defstmt.fromlineno + ) + elif isinstance(defframe, astroid.ClassDef) and isinstance( + frame, astroid.FunctionDef + ): + # Special rule for function return annotations, + # which uses the same name as the class where + # the function lives. + if PY3K and node is frame.returns and defframe.parent_of(frame.returns): + maybee0601 = annotation_return = True + + if ( + maybee0601 + and defframe.name in defframe.locals + and defframe.locals[name][0].lineno < frame.lineno + ): + # Detect class assignments with the same + # name as the class. In this case, no warning + # should be raised. + maybee0601 = False + if isinstance(node.parent, astroid.Arguments): + maybee0601 = stmt.fromlineno <= defstmt.fromlineno + elif recursive_klass: + maybee0601 = True + else: + maybee0601 = maybee0601 and stmt.fromlineno <= defstmt.fromlineno + if maybee0601 and stmt.fromlineno == defstmt.fromlineno: + if ( + isinstance(defframe, astroid.FunctionDef) + and frame is defframe + and defframe.parent_of(node) + and stmt is not defstmt + ): + # Single statement function, with the statement on the + # same line as the function definition + maybee0601 = False + + return maybee0601, annotation_return, use_outer_definition + + def _ignore_class_scope(self, node): + """ + Return True if the node is in a local class scope, as an assignment. + + :param node: Node considered + :type node: astroid.Node + :return: True if the node is in a local class scope, as an assignment. False otherwise. + :rtype: bool + """ + # Detect if we are in a local class scope, as an assignment. + # For example, the following is fair game. + # + # class A: + # b = 1 + # c = lambda b=b: b * b + # + # class B: + # tp = 1 + # def func(self, arg: tp): + # ... + # class C: + # tp = 2 + # def func(self, arg=tp): + # ... + + name = node.name + frame = node.statement().scope() + in_annotation_or_default = self._defined_in_function_definition(node, frame) + if in_annotation_or_default: + frame_locals = frame.parent.scope().locals + else: + frame_locals = frame.locals + return not ( + (isinstance(frame, astroid.ClassDef) or in_annotation_or_default) + and name in frame_locals + ) + + @utils.check_messages(*MSGS) + def visit_name(self, node): + """check that a name is defined if the current scope and doesn't + redefine a built-in + """ + stmt = node.statement() + if stmt.fromlineno is None: + # name node from an astroid built from live code, skip + assert not stmt.root().file.endswith(".py") + return + + name = node.name + frame = stmt.scope() + # if the name node is used as a function default argument's value or as + # a decorator, then start from the parent frame of the function instead + # of the function frame - and thus open an inner class scope + if ( + utils.is_default_argument(node) + or utils.is_func_decorator(node) + or utils.is_ancestor_name(frame, node) + ): + start_index = len(self._to_consume) - 2 + else: + start_index = len(self._to_consume) - 1 + # iterates through parent scopes, from the inner to the outer + base_scope_type = self._to_consume[start_index].scope_type + # pylint: disable=too-many-nested-blocks; refactoring this block is a pain. + for i in range(start_index, -1, -1): + current_consumer = self._to_consume[i] + # if the current scope is a class scope but it's not the inner + # scope, ignore it. This prevents to access this scope instead of + # the globals one in function members when there are some common + # names. The only exception is when the starting scope is a + # comprehension and its direct outer scope is a class + if ( + current_consumer.scope_type == "class" + and i != start_index + and not (base_scope_type == "comprehension" and i == start_index - 1) + ): + if self._ignore_class_scope(node): + continue + + # the name has already been consumed, only check it's not a loop + # variable used outside the loop + # avoid the case where there are homonyms inside function scope and + #  comprehension current scope (avoid bug #1731) + if name in current_consumer.consumed and not ( + current_consumer.scope_type == "comprehension" + and self._has_homonym_in_upper_function_scope(node, i) + ): + defnode = utils.assign_parent(current_consumer.consumed[name][0]) + self._check_late_binding_closure(node, defnode) + self._loopvar_name(node, name) + break + + found_node = current_consumer.get_next_to_consume(node) + if found_node is None: + continue + + # checks for use before assignment + defnode = utils.assign_parent(current_consumer.to_consume[name][0]) + + if defnode is not None: + self._check_late_binding_closure(node, defnode) + defstmt = defnode.statement() + defframe = defstmt.frame() + # The class reuses itself in the class scope. + recursive_klass = ( + frame is defframe + and defframe.parent_of(node) + and isinstance(defframe, astroid.ClassDef) + and node.name == defframe.name + ) + + if ( + recursive_klass + and utils.is_inside_lambda(node) + and ( + not utils.is_default_argument(node) + or node.scope().parent.scope() is not defframe + ) + ): + # Self-referential class references are fine in lambda's -- + # As long as they are not part of the default argument directly + # under the scope of the parent self-referring class. + # Example of valid default argument: + # class MyName3: + # myattr = 1 + # mylambda3 = lambda: lambda a=MyName3: a + # Example of invalid default argument: + # class MyName4: + # myattr = 1 + # mylambda4 = lambda a=MyName4: lambda: a + + # If the above conditional is True, + # there is no possibility of undefined-variable + # Also do not consume class name + # (since consuming blocks subsequent checks) + # -- quit + break + + maybee0601, annotation_return, use_outer_definition = self._is_variable_violation( + node, + name, + defnode, + stmt, + defstmt, + frame, + defframe, + base_scope_type, + recursive_klass, + ) + + if use_outer_definition: + continue + + if ( + maybee0601 + and not utils.is_defined_before(node) + and not astroid.are_exclusive(stmt, defstmt, ("NameError",)) + ): + + # Used and defined in the same place, e.g `x += 1` and `del x` + defined_by_stmt = defstmt is stmt and isinstance( + node, (astroid.DelName, astroid.AssignName) + ) + if ( + recursive_klass + or defined_by_stmt + or annotation_return + or isinstance(defstmt, astroid.Delete) + ): + if not utils.node_ignores_exception(node, NameError): + + # Handle postponed evaluation of annotations + if not ( + self._postponed_evaluation_enabled + and annotation_return + and name in node.root().locals + ): + self.add_message( + "undefined-variable", args=name, node=node + ) + elif base_scope_type != "lambda": + # E0601 may *not* occurs in lambda scope. + + # Handle postponed evaluation of annotations + if not ( + self._postponed_evaluation_enabled + and isinstance(stmt, astroid.FunctionDef) + ): + self.add_message( + "used-before-assignment", args=name, node=node + ) + elif base_scope_type == "lambda": + # E0601 can occur in class-level scope in lambdas, as in + # the following example: + # class A: + # x = lambda attr: f + attr + # f = 42 + if isinstance(frame, astroid.ClassDef) and name in frame.locals: + if isinstance(node.parent, astroid.Arguments): + if stmt.fromlineno <= defstmt.fromlineno: + # Doing the following is fine: + # class A: + # x = 42 + # y = lambda attr=x: attr + self.add_message( + "used-before-assignment", args=name, node=node + ) + else: + self.add_message( + "undefined-variable", args=name, node=node + ) + elif current_consumer.scope_type == "lambda": + self.add_message("undefined-variable", node=node, args=name) + + current_consumer.mark_as_consumed(name, found_node) + # check it's not a loop variable used outside the loop + self._loopvar_name(node, name) + break + else: + # we have not found the name, if it isn't a builtin, that's an + # undefined name ! + if not ( + name in astroid.Module.scope_attrs + or utils.is_builtin(name) + or name in self.config.additional_builtins + ): + if not utils.node_ignores_exception(node, NameError): + self.add_message("undefined-variable", args=name, node=node) + + def _has_homonym_in_upper_function_scope(self, node, index): + """ + Return True if there is a node with the same name in the to_consume dict of an upper scope + and if that scope is a function + + :param node: node to check for + :type node: astroid.Node + :param index: index of the current consumer inside self._to_consume + :type index: int + :return: True if there is a node with the same name in the to_consume dict of an upper scope + and if that scope is a function + :rtype: bool + """ + for _consumer in self._to_consume[index - 1 :: -1]: + if _consumer.scope_type == "function" and node.name in _consumer.to_consume: + return True + return False + + @utils.check_messages("no-name-in-module") + def visit_import(self, node): + """check modules attribute accesses""" + if not self._analyse_fallback_blocks and utils.is_from_fallback_block(node): + # No need to verify this, since ImportError is already + # handled by the client code. + return + + for name, _ in node.names: + parts = name.split(".") + try: + module = next(node.infer_name_module(parts[0])) + except astroid.ResolveError: + continue + self._check_module_attrs(node, module, parts[1:]) + + @utils.check_messages("no-name-in-module") + def visit_importfrom(self, node): + """check modules attribute accesses""" + if not self._analyse_fallback_blocks and utils.is_from_fallback_block(node): + # No need to verify this, since ImportError is already + # handled by the client code. + return + + name_parts = node.modname.split(".") + try: + module = node.do_import_module(name_parts[0]) + except astroid.AstroidBuildingException: + return + module = self._check_module_attrs(node, module, name_parts[1:]) + if not module: + return + for name, _ in node.names: + if name == "*": + continue + self._check_module_attrs(node, module, name.split(".")) + + @utils.check_messages( + "unbalanced-tuple-unpacking", "unpacking-non-sequence", "self-cls-assignment" + ) + def visit_assign(self, node): + """Check unbalanced tuple unpacking for assignments + and unpacking non-sequences as well as in case self/cls + get assigned. + """ + self._check_self_cls_assign(node) + if not isinstance(node.targets[0], (astroid.Tuple, astroid.List)): + return + + targets = node.targets[0].itered() + try: + infered = utils.safe_infer(node.value) + if infered is not None: + self._check_unpacking(infered, node, targets) + except astroid.InferenceError: + return + + def _store_type_annotation_node(self, type_annotation): + + if isinstance(type_annotation, astroid.Name): + self._type_annotation_names.append(type_annotation.name) + else: + self._type_annotation_names.extend( + list( + ( + annotation.name + for annotation in type_annotation.nodes_of_class(astroid.Name) + ) + ) + ) + + def _store_type_annotation_names(self, node): + type_annotation = node.type_annotation + if not type_annotation: + return + self._store_type_annotation_node(node.type_annotation) + + leave_assign = _store_type_annotation_names + leave_with = _store_type_annotation_names + + def _check_self_cls_assign(self, node): + """Check that self/cls don't get assigned""" + assign_names = { + target.name + for target in node.targets + if isinstance(target, astroid.AssignName) + } + scope = node.scope() + nonlocals_with_same_name = any( + child + for child in scope.body + if isinstance(child, astroid.Nonlocal) and assign_names & set(child.names) + ) + if nonlocals_with_same_name: + scope = node.scope().parent.scope() + + if not ( + isinstance(scope, astroid.scoped_nodes.FunctionDef) + and scope.is_method() + and "builtins.staticmethod" not in scope.decoratornames() + ): + return + argument_names = scope.argnames() + if not argument_names: + return + self_cls_name = argument_names[0] + target_assign_names = ( + target.name + for target in node.targets + if isinstance(target, astroid.node_classes.AssignName) + ) + if self_cls_name in target_assign_names: + self.add_message("self-cls-assignment", node=node, args=(self_cls_name)) + + def _check_unpacking(self, infered, node, targets): + """ Check for unbalanced tuple unpacking + and unpacking non sequences. + """ + if utils.is_inside_abstract_class(node): + return + if utils.is_comprehension(node): + return + if infered is astroid.Uninferable: + return + if ( + isinstance(infered.parent, astroid.Arguments) + and isinstance(node.value, astroid.Name) + and node.value.name == infered.parent.vararg + ): + # Variable-length argument, we can't determine the length. + return + if isinstance(infered, (astroid.Tuple, astroid.List)): + # attempt to check unpacking is properly balanced + values = infered.itered() + if len(targets) != len(values): + # Check if we have starred nodes. + if any(isinstance(target, astroid.Starred) for target in targets): + return + self.add_message( + "unbalanced-tuple-unpacking", + node=node, + args=( + _get_unpacking_extra_info(node, infered), + len(targets), + len(values), + ), + ) + # attempt to check unpacking may be possible (ie RHS is iterable) + else: + if not utils.is_iterable(infered): + self.add_message( + "unpacking-non-sequence", + node=node, + args=(_get_unpacking_extra_info(node, infered),), + ) + + def _check_module_attrs(self, node, module, module_names): + """check that module_names (list of string) are accessible through the + given module + if the latest access name corresponds to a module, return it + """ + assert isinstance(module, astroid.Module), module + while module_names: + name = module_names.pop(0) + if name == "__dict__": + module = None + break + try: + module = next(module.getattr(name)[0].infer()) + if module is astroid.Uninferable: + return None + except astroid.NotFoundError: + if module.name in self._ignored_modules: + return None + self.add_message( + "no-name-in-module", args=(name, module.name), node=node + ) + return None + except astroid.InferenceError: + return None + if module_names: + # FIXME: other message if name is not the latest part of + # module_names ? + modname = module.name if module else "__dict__" + self.add_message( + "no-name-in-module", node=node, args=(".".join(module_names), modname) + ) + return None + if isinstance(module, astroid.Module): + return module + return None + + +class VariablesChecker3k(VariablesChecker): + """Modified variables checker for 3k""" + + # listcomp have now also their scope + + def visit_listcomp(self, node): + """visit dictcomp: update consumption analysis variable + """ + self._to_consume.append(NamesConsumer(node, "comprehension")) + + def leave_listcomp(self, _): + """leave dictcomp: update consumption analysis variable + """ + # do not check for not used locals here + self._to_consume.pop() + + def leave_functiondef(self, node): + self._check_metaclasses(node) + super(VariablesChecker3k, self).leave_functiondef(node) + + def leave_module(self, node): + self._check_metaclasses(node) + super(VariablesChecker3k, self).leave_module(node) + + def _check_metaclasses(self, node): + """ Update consumption analysis for metaclasses. """ + consumed = [] # [(scope_locals, consumed_key)] + + for child_node in node.get_children(): + if isinstance(child_node, astroid.ClassDef): + consumed.extend(self._check_classdef_metaclasses(child_node, node)) + + # Pop the consumed items, in order to avoid having + # unused-import and unused-variable false positives + for scope_locals, name in consumed: + scope_locals.pop(name, None) + + def _check_classdef_metaclasses(self, klass, parent_node): + if not klass._metaclass: + # Skip if this class doesn't use explicitly a metaclass, but inherits it from ancestors + return [] + + consumed = [] # [(scope_locals, consumed_key)] + metaclass = klass.metaclass() + + name = None + if isinstance(klass._metaclass, astroid.Name): + name = klass._metaclass.name + elif metaclass: + name = metaclass.root().name + + found = None + name = METACLASS_NAME_TRANSFORMS.get(name, name) + if name: + # check enclosing scopes starting from most local + for scope_locals, _, _ in self._to_consume[::-1]: + found = scope_locals.get(name) + if found: + consumed.append((scope_locals, name)) + break + + if found is None and not metaclass: + name = None + if isinstance(klass._metaclass, astroid.Name): + name = klass._metaclass.name + elif isinstance(klass._metaclass, astroid.Attribute): + name = klass._metaclass.as_string() + + if name is not None: + if not ( + name in astroid.Module.scope_attrs + or utils.is_builtin(name) + or name in self.config.additional_builtins + or name in parent_node.locals + ): + self.add_message("undefined-variable", node=klass, args=(name,)) + + return consumed + + +if sys.version_info >= (3, 0): + VariablesChecker = VariablesChecker3k # type: ignore + + +def register(linter): + """required method to auto register this checker""" + linter.register_checker(VariablesChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/config.py b/basic python programmes/venv/Lib/site-packages/pylint/config.py new file mode 100644 index 0000000..43c67b3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/config.py @@ -0,0 +1,931 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2010, 2012-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2008 pyves@crater.logilab.fr <pyves@crater.logilab.fr> +# Copyright (c) 2010 Julien Jehannet <julien.jehannet@logilab.fr> +# Copyright (c) 2013 Google, Inc. +# Copyright (c) 2013 John McGehee <jmcgehee@altera.com> +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Aru Sahni <arusahni@gmail.com> +# Copyright (c) 2015 John Kirkham <jakirkham@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Erik <erik.eriksson@yahoo.com> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2017-2018 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 ahirnish <ahirnish@gmail.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Gary Tyler McLeod <mail@garytyler.com> +# Copyright (c) 2018 Konstantin <Github@pheanex.de> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""utilities for Pylint configuration : + +* pylintrc +* pylint.d (PYLINTHOME) +""" +from __future__ import print_function + +# TODO(cpopa): this module contains the logic for the +# configuration parser and for the command line parser, +# but it's really coupled to optparse's internals. +# The code was copied almost verbatim from logilab.common, +# in order to not depend on it anymore and it will definitely +# need a cleanup. It could be completely reengineered as well. + +import contextlib +import collections +import copy +import io +import optparse +import os +import pickle +import re +import sys +import time + +import configparser + +from pylint import utils + + +USER_HOME = os.path.expanduser("~") +if "PYLINTHOME" in os.environ: + PYLINT_HOME = os.environ["PYLINTHOME"] + if USER_HOME == "~": + USER_HOME = os.path.dirname(PYLINT_HOME) +elif USER_HOME == "~": + PYLINT_HOME = ".pylint.d" +else: + PYLINT_HOME = os.path.join(USER_HOME, ".pylint.d") + + +def _get_pdata_path(base_name, recurs): + base_name = base_name.replace(os.sep, "_") + return os.path.join(PYLINT_HOME, "%s%s%s" % (base_name, recurs, ".stats")) + + +def load_results(base): + data_file = _get_pdata_path(base, 1) + try: + with open(data_file, _PICK_LOAD) as stream: + return pickle.load(stream) + except Exception: # pylint: disable=broad-except + return {} + + +if sys.version_info < (3, 0): + _PICK_DUMP, _PICK_LOAD = "w", "r" +else: + _PICK_DUMP, _PICK_LOAD = "wb", "rb" + + +def save_results(results, base): + if not os.path.exists(PYLINT_HOME): + try: + os.mkdir(PYLINT_HOME) + except OSError: + print("Unable to create directory %s" % PYLINT_HOME, file=sys.stderr) + data_file = _get_pdata_path(base, 1) + try: + with open(data_file, _PICK_DUMP) as stream: + pickle.dump(results, stream) + except (IOError, OSError) as ex: + print("Unable to create file %s: %s" % (data_file, ex), file=sys.stderr) + + +def find_pylintrc(): + """search the pylint rc file and return its path if it find it, else None + """ + # is there a pylint rc file in the current directory ? + if os.path.exists("pylintrc"): + return os.path.abspath("pylintrc") + if os.path.exists(".pylintrc"): + return os.path.abspath(".pylintrc") + if os.path.isfile("__init__.py"): + curdir = os.path.abspath(os.getcwd()) + while os.path.isfile(os.path.join(curdir, "__init__.py")): + curdir = os.path.abspath(os.path.join(curdir, "..")) + if os.path.isfile(os.path.join(curdir, "pylintrc")): + return os.path.join(curdir, "pylintrc") + if os.path.isfile(os.path.join(curdir, ".pylintrc")): + return os.path.join(curdir, ".pylintrc") + if "PYLINTRC" in os.environ and os.path.exists(os.environ["PYLINTRC"]): + pylintrc = os.environ["PYLINTRC"] + else: + user_home = os.path.expanduser("~") + if user_home in ("~", "/root"): + pylintrc = ".pylintrc" + else: + pylintrc = os.path.join(user_home, ".pylintrc") + if not os.path.isfile(pylintrc): + pylintrc = os.path.join(user_home, ".config", "pylintrc") + if not os.path.isfile(pylintrc): + if os.path.isfile("/etc/pylintrc"): + pylintrc = "/etc/pylintrc" + else: + pylintrc = None + return pylintrc + + +PYLINTRC = find_pylintrc() + +ENV_HELP = ( + """ +The following environment variables are used: + * PYLINTHOME + Path to the directory where persistent data for the run will be stored. If +not found, it defaults to ~/.pylint.d/ or .pylint.d (in the current working +directory). + * PYLINTRC + Path to the configuration file. See the documentation for the method used +to search for configuration file. +""" + % globals() # type: ignore +) + + +class UnsupportedAction(Exception): + """raised by set_option when it doesn't know what to do for an action""" + + +def _multiple_choice_validator(choices, name, value): + values = utils._check_csv(value) + for csv_value in values: + if csv_value not in choices: + msg = "option %s: invalid value: %r, should be in %s" + raise optparse.OptionValueError(msg % (name, csv_value, choices)) + return values + + +def _choice_validator(choices, name, value): + if value not in choices: + msg = "option %s: invalid value: %r, should be in %s" + raise optparse.OptionValueError(msg % (name, value, choices)) + return value + + +# pylint: disable=unused-argument +def _csv_validator(_, name, value): + return utils._check_csv(value) + + +# pylint: disable=unused-argument +def _regexp_validator(_, name, value): + if hasattr(value, "pattern"): + return value + return re.compile(value) + + +# pylint: disable=unused-argument +def _regexp_csv_validator(_, name, value): + return [_regexp_validator(_, name, val) for val in _csv_validator(_, name, value)] + + +def _yn_validator(opt, _, value): + if isinstance(value, int): + return bool(value) + if value in ("y", "yes"): + return True + if value in ("n", "no"): + return False + msg = "option %s: invalid yn value %r, should be in (y, yes, n, no)" + raise optparse.OptionValueError(msg % (opt, value)) + + +def _non_empty_string_validator(opt, _, value): + if not value: + msg = "indent string can't be empty." + raise optparse.OptionValueError(msg) + return utils._unquote(value) + + +VALIDATORS = { + "string": utils._unquote, + "int": int, + "regexp": re.compile, + "regexp_csv": _regexp_csv_validator, + "csv": _csv_validator, + "yn": _yn_validator, + "choice": lambda opt, name, value: _choice_validator(opt["choices"], name, value), + "multiple_choice": lambda opt, name, value: _multiple_choice_validator( + opt["choices"], name, value + ), + "non_empty_string": _non_empty_string_validator, +} + + +def _call_validator(opttype, optdict, option, value): + if opttype not in VALIDATORS: + raise Exception('Unsupported type "%s"' % opttype) + try: + return VALIDATORS[opttype](optdict, option, value) + except TypeError: + try: + return VALIDATORS[opttype](value) + except Exception: + raise optparse.OptionValueError( + "%s value (%r) should be of type %s" % (option, value, opttype) + ) + + +def _validate(value, optdict, name=""): + """return a validated value for an option according to its type + + optional argument name is only used for error message formatting + """ + try: + _type = optdict["type"] + except KeyError: + # FIXME + return value + return _call_validator(_type, optdict, name, value) + + +def _level_options(group, outputlevel): + return [ + option + for option in group.option_list + if (getattr(option, "level", 0) or 0) <= outputlevel + and option.help is not optparse.SUPPRESS_HELP + ] + + +def _expand_default(self, option): + """Patch OptionParser.expand_default with custom behaviour + + This will handle defaults to avoid overriding values in the + configuration file. + """ + if self.parser is None or not self.default_tag: + return option.help + optname = option._long_opts[0][2:] + try: + provider = self.parser.options_manager._all_options[optname] + except KeyError: + value = None + else: + optdict = provider.get_option_def(optname) + optname = provider.option_attrname(optname, optdict) + value = getattr(provider.config, optname, optdict) + value = utils._format_option_value(optdict, value) + if value is optparse.NO_DEFAULT or not value: + value = self.NO_DEFAULT_VALUE + return option.help.replace(self.default_tag, str(value)) + + +@contextlib.contextmanager +def _patch_optparse(): + orig_default = optparse.HelpFormatter + try: + optparse.HelpFormatter.expand_default = _expand_default + yield + finally: + optparse.HelpFormatter.expand_default = orig_default + + +def _multiple_choices_validating_option(opt, name, value): + return _multiple_choice_validator(opt.choices, name, value) + + +# pylint: disable=no-member +class Option(optparse.Option): + TYPES = optparse.Option.TYPES + ( + "regexp", + "regexp_csv", + "csv", + "yn", + "multiple_choice", + "non_empty_string", + ) + ATTRS = optparse.Option.ATTRS + ["hide", "level"] + TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER) + TYPE_CHECKER["regexp"] = _regexp_validator + TYPE_CHECKER["regexp_csv"] = _regexp_csv_validator + TYPE_CHECKER["csv"] = _csv_validator + TYPE_CHECKER["yn"] = _yn_validator + TYPE_CHECKER["multiple_choice"] = _multiple_choices_validating_option + TYPE_CHECKER["non_empty_string"] = _non_empty_string_validator + + def __init__(self, *opts, **attrs): + optparse.Option.__init__(self, *opts, **attrs) + if hasattr(self, "hide") and self.hide: + self.help = optparse.SUPPRESS_HELP + + def _check_choice(self): + if self.type in ("choice", "multiple_choice"): + if self.choices is None: + raise optparse.OptionError( + "must supply a list of choices for type 'choice'", self + ) + elif not isinstance(self.choices, (tuple, list)): + raise optparse.OptionError( + "choices must be a list of strings ('%s' supplied)" + % str(type(self.choices)).split("'")[1], + self, + ) + elif self.choices is not None: + raise optparse.OptionError( + "must not supply choices for type %r" % self.type, self + ) + + # pylint: disable=unsupported-assignment-operation + optparse.Option.CHECK_METHODS[2] = _check_choice # type: ignore + + def process(self, opt, value, values, parser): + # First, convert the value(s) to the right type. Howl if any + # value(s) are bogus. + value = self.convert_value(opt, value) + if self.type == "named": + existent = getattr(values, self.dest) + if existent: + existent.update(value) + value = existent + # And then take whatever action is expected of us. + # This is a separate method to make life easier for + # subclasses to add new actions. + return self.take_action(self.action, self.dest, opt, value, values, parser) + + +class OptionParser(optparse.OptionParser): + def __init__(self, option_class, *args, **kwargs): + optparse.OptionParser.__init__(self, option_class=Option, *args, **kwargs) + + def format_option_help(self, formatter=None): + if formatter is None: + formatter = self.formatter + outputlevel = getattr(formatter, "output_level", 0) + formatter.store_option_strings(self) + result = [] + result.append(formatter.format_heading("Options")) + formatter.indent() + if self.option_list: + result.append(optparse.OptionContainer.format_option_help(self, formatter)) + result.append("\n") + for group in self.option_groups: + if group.level <= outputlevel and ( + group.description or _level_options(group, outputlevel) + ): + result.append(group.format_help(formatter)) + result.append("\n") + formatter.dedent() + # Drop the last "\n", or the header if no options or option groups: + return "".join(result[:-1]) + + def _match_long_opt(self, opt): + """Disable abbreviations.""" + if opt not in self._long_opt: + raise optparse.BadOptionError(opt) + return opt + + +# pylint: disable=abstract-method; by design? +class _ManHelpFormatter(optparse.HelpFormatter): + def __init__( + self, indent_increment=0, max_help_position=24, width=79, short_first=0 + ): + optparse.HelpFormatter.__init__( + self, indent_increment, max_help_position, width, short_first + ) + + def format_heading(self, heading): + return ".SH %s\n" % heading.upper() + + def format_description(self, description): + return description + + def format_option(self, option): + try: + optstring = option.option_strings + except AttributeError: + optstring = self.format_option_strings(option) + if option.help: + help_text = self.expand_default(option) + help_string = " ".join([l.strip() for l in help_text.splitlines()]) + help_string = help_string.replace("\\", "\\\\") + help_string = help_string.replace("[current:", "[default:") + else: + help_string = "" + return """.IP "%s" +%s +""" % ( + optstring, + help_string, + ) + + def format_head(self, optparser, pkginfo, section=1): + long_desc = "" + try: + pgm = optparser._get_prog_name() + except AttributeError: + # py >= 2.4.X (dunno which X exactly, at least 2) + pgm = optparser.get_prog_name() + short_desc = self.format_short_description(pgm, pkginfo.description) + if hasattr(pkginfo, "long_desc"): + long_desc = self.format_long_description(pgm, pkginfo.long_desc) + return "%s\n%s\n%s\n%s" % ( + self.format_title(pgm, section), + short_desc, + self.format_synopsis(pgm), + long_desc, + ) + + @staticmethod + def format_title(pgm, section): + date = "%d-%02d-%02d" % time.localtime()[:3] + return '.TH %s %s "%s" %s' % (pgm, section, date, pgm) + + @staticmethod + def format_short_description(pgm, short_desc): + return """.SH NAME +.B %s +\\- %s +""" % ( + pgm, + short_desc.strip(), + ) + + @staticmethod + def format_synopsis(pgm): + return ( + """.SH SYNOPSIS +.B %s +[ +.I OPTIONS +] [ +.I <arguments> +] +""" + % pgm + ) + + @staticmethod + def format_long_description(pgm, long_desc): + long_desc = "\n".join(line.lstrip() for line in long_desc.splitlines()) + long_desc = long_desc.replace("\n.\n", "\n\n") + if long_desc.lower().startswith(pgm): + long_desc = long_desc[len(pgm) :] + return """.SH DESCRIPTION +.B %s +%s +""" % ( + pgm, + long_desc.strip(), + ) + + @staticmethod + def format_tail(pkginfo): + tail = """.SH SEE ALSO +/usr/share/doc/pythonX.Y-%s/ + +.SH BUGS +Please report bugs on the project\'s mailing list: +%s + +.SH AUTHOR +%s <%s> +""" % ( + getattr(pkginfo, "debian_name", pkginfo.modname), + pkginfo.mailinglist, + pkginfo.author, + pkginfo.author_email, + ) + + if hasattr(pkginfo, "copyright"): + tail += ( + """ +.SH COPYRIGHT +%s +""" + % pkginfo.copyright + ) + + return tail + + +class OptionsManagerMixIn: + """Handle configuration from both a configuration file and command line options""" + + def __init__(self, usage, config_file=None, version=None): + self.config_file = config_file + self.reset_parsers(usage, version=version) + # list of registered options providers + self.options_providers = [] + # dictionary associating option name to checker + self._all_options = collections.OrderedDict() + self._short_options = {} + self._nocallback_options = {} + self._mygroups = {} + # verbosity + self._maxlevel = 0 + + def reset_parsers(self, usage="", version=None): + # configuration file parser + self.cfgfile_parser = configparser.ConfigParser( + inline_comment_prefixes=("#", ";") + ) + # command line parser + self.cmdline_parser = OptionParser(Option, usage=usage, version=version) + self.cmdline_parser.options_manager = self + self._optik_option_attrs = set(self.cmdline_parser.option_class.ATTRS) + + def register_options_provider(self, provider, own_group=True): + """register an options provider""" + assert provider.priority <= 0, "provider's priority can't be >= 0" + for i in range(len(self.options_providers)): + if provider.priority > self.options_providers[i].priority: + self.options_providers.insert(i, provider) + break + else: + self.options_providers.append(provider) + non_group_spec_options = [ + option for option in provider.options if "group" not in option[1] + ] + groups = getattr(provider, "option_groups", ()) + if own_group and non_group_spec_options: + self.add_option_group( + provider.name.upper(), + provider.__doc__, + non_group_spec_options, + provider, + ) + else: + for opt, optdict in non_group_spec_options: + self.add_optik_option(provider, self.cmdline_parser, opt, optdict) + for gname, gdoc in groups: + gname = gname.upper() + goptions = [ + option + for option in provider.options + if option[1].get("group", "").upper() == gname + ] + self.add_option_group(gname, gdoc, goptions, provider) + + def add_option_group(self, group_name, _, options, provider): + # add option group to the command line parser + if group_name in self._mygroups: + group = self._mygroups[group_name] + else: + group = optparse.OptionGroup( + self.cmdline_parser, title=group_name.capitalize() + ) + self.cmdline_parser.add_option_group(group) + group.level = provider.level + self._mygroups[group_name] = group + # add section to the config file + if ( + group_name != "DEFAULT" + and group_name not in self.cfgfile_parser._sections + ): + self.cfgfile_parser.add_section(group_name) + # add provider's specific options + for opt, optdict in options: + self.add_optik_option(provider, group, opt, optdict) + + def add_optik_option(self, provider, optikcontainer, opt, optdict): + args, optdict = self.optik_option(provider, opt, optdict) + option = optikcontainer.add_option(*args, **optdict) + self._all_options[opt] = provider + self._maxlevel = max(self._maxlevel, option.level or 0) + + def optik_option(self, provider, opt, optdict): + """get our personal option definition and return a suitable form for + use with optik/optparse + """ + optdict = copy.copy(optdict) + if "action" in optdict: + self._nocallback_options[provider] = opt + else: + optdict["action"] = "callback" + optdict["callback"] = self.cb_set_provider_option + # default is handled here and *must not* be given to optik if you + # want the whole machinery to work + if "default" in optdict: + if ( + "help" in optdict + and optdict.get("default") is not None + and optdict["action"] not in ("store_true", "store_false") + ): + optdict["help"] += " [current: %default]" + del optdict["default"] + args = ["--" + str(opt)] + if "short" in optdict: + self._short_options[optdict["short"]] = opt + args.append("-" + optdict["short"]) + del optdict["short"] + # cleanup option definition dict before giving it to optik + for key in list(optdict.keys()): + if key not in self._optik_option_attrs: + optdict.pop(key) + return args, optdict + + def cb_set_provider_option(self, option, opt, value, parser): + """optik callback for option setting""" + if opt.startswith("--"): + # remove -- on long option + opt = opt[2:] + else: + # short option, get its long equivalent + opt = self._short_options[opt[1:]] + # trick since we can't set action='store_true' on options + if value is None: + value = 1 + self.global_set_option(opt, value) + + def global_set_option(self, opt, value): + """set option on the correct option provider""" + self._all_options[opt].set_option(opt, value) + + def generate_config(self, stream=None, skipsections=(), encoding=None): + """write a configuration file according to the current configuration + into the given stream or stdout + """ + options_by_section = {} + sections = [] + for provider in self.options_providers: + for section, options in provider.options_by_section(): + if section is None: + section = provider.name + if section in skipsections: + continue + options = [ + (n, d, v) + for (n, d, v) in options + if d.get("type") is not None and not d.get("deprecated") + ] + if not options: + continue + if section not in sections: + sections.append(section) + alloptions = options_by_section.setdefault(section, []) + alloptions += options + stream = stream or sys.stdout + printed = False + for section in sections: + if printed: + print("\n", file=stream) + utils.format_section( + stream, section.upper(), sorted(options_by_section[section]) + ) + printed = True + + def generate_manpage(self, pkginfo, section=1, stream=None): + with _patch_optparse(): + _generate_manpage( + self.cmdline_parser, + pkginfo, + section, + stream=stream or sys.stdout, + level=self._maxlevel, + ) + + def load_provider_defaults(self): + """initialize configuration using default values""" + for provider in self.options_providers: + provider.load_defaults() + + def read_config_file(self, config_file=None, verbose=None): + """read the configuration file but do not load it (i.e. dispatching + values to each options provider) + """ + helplevel = 1 + while helplevel <= self._maxlevel: + opt = "-".join(["long"] * helplevel) + "-help" + if opt in self._all_options: + break # already processed + # pylint: disable=unused-argument + def helpfunc(option, opt, val, p, level=helplevel): + print(self.help(level)) + sys.exit(0) + + helpmsg = "%s verbose help." % " ".join(["more"] * helplevel) + optdict = {"action": "callback", "callback": helpfunc, "help": helpmsg} + provider = self.options_providers[0] + self.add_optik_option(provider, self.cmdline_parser, opt, optdict) + provider.options += ((opt, optdict),) + helplevel += 1 + if config_file is None: + config_file = self.config_file + if config_file is not None: + config_file = os.path.expanduser(config_file) + if not os.path.exists(config_file): + raise IOError("The config file {:s} doesn't exist!".format(config_file)) + + use_config_file = config_file and os.path.exists(config_file) + if use_config_file: + parser = self.cfgfile_parser + + # Use this encoding in order to strip the BOM marker, if any. + with io.open(config_file, "r", encoding="utf_8_sig") as fp: + parser.read_file(fp) + + # normalize sections'title + for sect, values in list(parser._sections.items()): + if not sect.isupper() and values: + parser._sections[sect.upper()] = values + + if not verbose: + return + + if use_config_file: + msg = "Using config file {}".format(os.path.abspath(config_file)) + else: + msg = "No config file found, using default configuration" + print(msg, file=sys.stderr) + + def load_config_file(self): + """dispatch values previously read from a configuration file to each + options provider) + """ + parser = self.cfgfile_parser + for section in parser.sections(): + for option, value in parser.items(section): + try: + self.global_set_option(option, value) + except (KeyError, optparse.OptionError): + # TODO handle here undeclared options appearing in the config file + continue + + def load_configuration(self, **kwargs): + """override configuration according to given parameters""" + return self.load_configuration_from_config(kwargs) + + def load_configuration_from_config(self, config): + for opt, opt_value in config.items(): + opt = opt.replace("_", "-") + provider = self._all_options[opt] + provider.set_option(opt, opt_value) + + def load_command_line_configuration(self, args=None): + """Override configuration according to command line parameters + + return additional arguments + """ + with _patch_optparse(): + if args is None: + args = sys.argv[1:] + else: + args = list(args) + (options, args) = self.cmdline_parser.parse_args(args=args) + for provider in self._nocallback_options: + config = provider.config + for attr in config.__dict__.keys(): + value = getattr(options, attr, None) + if value is None: + continue + setattr(config, attr, value) + return args + + def add_help_section(self, title, description, level=0): + """add a dummy option section for help purpose """ + group = optparse.OptionGroup( + self.cmdline_parser, title=title.capitalize(), description=description + ) + group.level = level + self._maxlevel = max(self._maxlevel, level) + self.cmdline_parser.add_option_group(group) + + def help(self, level=0): + """return the usage string for available options """ + self.cmdline_parser.formatter.output_level = level + with _patch_optparse(): + return self.cmdline_parser.format_help() + + +class OptionsProviderMixIn: + """Mixin to provide options to an OptionsManager""" + + # those attributes should be overridden + priority = -1 + name = "default" + options = () + level = 0 + + def __init__(self): + self.config = optparse.Values() + self.load_defaults() + + def load_defaults(self): + """initialize the provider using default values""" + for opt, optdict in self.options: + action = optdict.get("action") + if action != "callback": + # callback action have no default + if optdict is None: + optdict = self.get_option_def(opt) + default = optdict.get("default") + self.set_option(opt, default, action, optdict) + + def option_attrname(self, opt, optdict=None): + """get the config attribute corresponding to opt""" + if optdict is None: + optdict = self.get_option_def(opt) + return optdict.get("dest", opt.replace("-", "_")) + + def option_value(self, opt): + """get the current value for the given option""" + return getattr(self.config, self.option_attrname(opt), None) + + def set_option(self, optname, value, action=None, optdict=None): + """method called to set an option (registered in the options list)""" + if optdict is None: + optdict = self.get_option_def(optname) + if value is not None: + value = _validate(value, optdict, optname) + if action is None: + action = optdict.get("action", "store") + if action == "store": + setattr(self.config, self.option_attrname(optname, optdict), value) + elif action in ("store_true", "count"): + setattr(self.config, self.option_attrname(optname, optdict), 0) + elif action == "store_false": + setattr(self.config, self.option_attrname(optname, optdict), 1) + elif action == "append": + optname = self.option_attrname(optname, optdict) + _list = getattr(self.config, optname, None) + if _list is None: + if isinstance(value, (list, tuple)): + _list = value + elif value is not None: + _list = [] + _list.append(value) + setattr(self.config, optname, _list) + elif isinstance(_list, tuple): + setattr(self.config, optname, _list + (value,)) + else: + _list.append(value) + elif action == "callback": + optdict["callback"](None, optname, value, None) + else: + raise UnsupportedAction(action) + + def get_option_def(self, opt): + """return the dictionary defining an option given its name""" + assert self.options + for option in self.options: + if option[0] == opt: + return option[1] + raise optparse.OptionError( + "no such option %s in section %r" % (opt, self.name), opt + ) + + def options_by_section(self): + """return an iterator on options grouped by section + + (section, [list of (optname, optdict, optvalue)]) + """ + sections = {} + for optname, optdict in self.options: + sections.setdefault(optdict.get("group"), []).append( + (optname, optdict, self.option_value(optname)) + ) + if None in sections: + yield None, sections.pop(None) + for section, options in sorted(sections.items()): + yield section.upper(), options + + def options_and_values(self, options=None): + if options is None: + options = self.options + for optname, optdict in options: + yield (optname, optdict, self.option_value(optname)) + + +class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn): + """basic mixin for simple configurations which don't need the + manager / providers model + """ + + def __init__(self, *args, **kwargs): + if not args: + kwargs.setdefault("usage", "") + OptionsManagerMixIn.__init__(self, *args, **kwargs) + OptionsProviderMixIn.__init__(self) + if not getattr(self, "option_groups", None): + self.option_groups = [] + for _, optdict in self.options: + try: + gdef = (optdict["group"].upper(), "") + except KeyError: + continue + if gdef not in self.option_groups: + self.option_groups.append(gdef) + self.register_options_provider(self, own_group=False) + + +def _generate_manpage(optparser, pkginfo, section=1, stream=sys.stdout, level=0): + formatter = _ManHelpFormatter() + formatter.output_level = level + formatter.parser = optparser + print(formatter.format_head(optparser, pkginfo, section), file=stream) + print(optparser.format_option_help(formatter), file=stream) + print(formatter.format_tail(pkginfo), file=stream) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/epylint.py b/basic python programmes/venv/Lib/site-packages/pylint/epylint.py new file mode 100644 index 0000000..50c3a99 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/epylint.py @@ -0,0 +1,196 @@ +# -*- coding: utf-8; +# mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 +# -*- vim:fenc=utf-8:ft=python:et:sw=4:ts=4:sts=4 + +# Copyright (c) 2008-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Jakob Normark <jakobnormark@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Manuel Vázquez Acosta <mva.led@gmail.com> +# Copyright (c) 2014 Derek Harland <derek.harland@finq.co.nz> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Mihai Balint <balint.mihai@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Daniela Plascencia <daplascen@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Ryan McGuire <ryan@enigmacurry.com> +# Copyright (c) 2018 thernstig <30827238+thernstig@users.noreply.github.com> +# Copyright (c) 2018 Radostin Stoyanov <rst0git@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Emacs and Flymake compatible Pylint. + +This script is for integration with emacs and is compatible with flymake mode. + +epylint walks out of python packages before invoking pylint. This avoids +reporting import errors that occur when a module within a package uses the +absolute import path to get another module within this package. + +For example: + - Suppose a package is structured as + + a/__init__.py + a/b/x.py + a/c/y.py + + - Then if y.py imports x as "from a.b import x" the following produces pylint + errors + + cd a/c; pylint y.py + + - The following obviously doesn't + + pylint a/c/y.py + + - As this script will be invoked by emacs within the directory of the file + we are checking we need to go out of it to avoid these false positives. + + +You may also use py_run to run pylint with desired options and get back (or not) +its output. +""" +from __future__ import print_function + +import os +import os.path as osp +import sys +import shlex +from subprocess import Popen, PIPE +from io import StringIO + + +def _get_env(): + """Extracts the environment PYTHONPATH and appends the current sys.path to + those.""" + env = dict(os.environ) + env["PYTHONPATH"] = os.pathsep.join(sys.path) + return env + + +def lint(filename, options=()): + """Pylint the given file. + + When run from emacs we will be in the directory of a file, and passed its + filename. If this file is part of a package and is trying to import other + modules from within its own package or another package rooted in a directory + below it, pylint will classify it as a failed import. + + To get around this, we traverse down the directory tree to find the root of + the package this module is in. We then invoke pylint from this directory. + + Finally, we must correct the filenames in the output generated by pylint so + Emacs doesn't become confused (it will expect just the original filename, + while pylint may extend it with extra directories if we've traversed down + the tree) + """ + # traverse downwards until we are out of a python package + full_path = osp.abspath(filename) + parent_path = osp.dirname(full_path) + child_path = osp.basename(full_path) + + while parent_path != "/" and osp.exists(osp.join(parent_path, "__init__.py")): + child_path = osp.join(osp.basename(parent_path), child_path) + parent_path = osp.dirname(parent_path) + + # Start pylint + # Ensure we use the python and pylint associated with the running epylint + run_cmd = "import sys; from pylint.lint import Run; Run(sys.argv[1:])" + cmd = ( + [sys.executable, "-c", run_cmd] + + [ + "--msg-template", + "{path}:{line}: {category} ({msg_id}, {symbol}, {obj}) {msg}", + "-r", + "n", + child_path, + ] + + list(options) + ) + process = Popen( + cmd, stdout=PIPE, cwd=parent_path, env=_get_env(), universal_newlines=True + ) + + for line in process.stdout: + # remove pylintrc warning + if line.startswith("No config file found"): + continue + + # modify the file name thats output to reverse the path traversal we made + parts = line.split(":") + if parts and parts[0] == child_path: + line = ":".join([filename] + parts[1:]) + print(line, end=" ") + + process.wait() + return process.returncode + + +def py_run(command_options="", return_std=False, stdout=None, stderr=None): + """Run pylint from python + + ``command_options`` is a string containing ``pylint`` command line options; + ``return_std`` (boolean) indicates return of created standard output + and error (see below); + ``stdout`` and ``stderr`` are 'file-like' objects in which standard output + could be written. + + Calling agent is responsible for stdout/err management (creation, close). + Default standard output and error are those from sys, + or standalone ones (``subprocess.PIPE``) are used + if they are not set and ``return_std``. + + If ``return_std`` is set to ``True``, this function returns a 2-uple + containing standard output and error related to created process, + as follows: ``(stdout, stderr)``. + + To silently run Pylint on a module, and get its standard output and error: + >>> (pylint_stdout, pylint_stderr) = py_run( 'module_name.py', True) + """ + # Create command line to call pylint + epylint_part = [sys.executable, "-c", "from pylint import epylint;epylint.Run()"] + options = shlex.split(command_options, posix=not sys.platform.startswith("win")) + cli = epylint_part + options + + # Providing standard output and/or error if not set + if stdout is None: + if return_std: + stdout = PIPE + else: + stdout = sys.stdout + if stderr is None: + if return_std: + stderr = PIPE + else: + stderr = sys.stderr + # Call pylint in a subprocess + process = Popen( + cli, + shell=False, + stdout=stdout, + stderr=stderr, + env=_get_env(), + universal_newlines=True, + ) + proc_stdout, proc_stderr = process.communicate() + # Return standard output and error + if return_std: + return StringIO(proc_stdout), StringIO(proc_stderr) + return None + + +def Run(): + if len(sys.argv) == 1: + print("Usage: %s <filename> [options]" % sys.argv[0]) + sys.exit(1) + elif not osp.exists(sys.argv[1]): + print("%s does not exist" % sys.argv[1]) + sys.exit(1) + else: + sys.exit(lint(sys.argv[1], sys.argv[2:])) + + +if __name__ == "__main__": + Run() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/exceptions.py b/basic python programmes/venv/Lib/site-packages/pylint/exceptions.py new file mode 100644 index 0000000..57353a4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/exceptions.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Exception classes raised by various operations within pylint.""" + + +class InvalidMessageError(Exception): + """raised when a message creation, registration or addition is rejected""" + + +class UnknownMessageError(Exception): + """raised when an unregistered message id is encountered""" + + +class EmptyReportError(Exception): + """raised when a report is empty and so should not be displayed""" + + +class InvalidReporterError(Exception): + """raised when selected reporter is invalid (e.g. not found)""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..cc1686d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc new file mode 100644 index 0000000..47950f2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/_check_docs_utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc new file mode 100644 index 0000000..47a5588 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/bad_builtin.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pyc new file mode 100644 index 0000000..fc4d5cc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/check_docs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pyc new file mode 100644 index 0000000..5bff949 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/check_elif.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pyc new file mode 100644 index 0000000..82e2d07 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/comparetozero.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pyc new file mode 100644 index 0000000..20f9485 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/docparams.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pyc new file mode 100644 index 0000000..be93fda Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/docstyle.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pyc new file mode 100644 index 0000000..c02388f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/emptystring.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pyc new file mode 100644 index 0000000..7e06bda Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/mccabe.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc new file mode 100644 index 0000000..2543b68 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/overlapping_exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc new file mode 100644 index 0000000..fe2d766 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/extensions/__pycache__/redefined_variable_type.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/_check_docs_utils.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/_check_docs_utils.py new file mode 100644 index 0000000..2aaa709 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/_check_docs_utils.py @@ -0,0 +1,789 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016-2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Yuri Bochkarev <baltazar.bz@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Mitar <mitar.github@tnode.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Mitchell T.H. Young <mitchelly@gmail.com> +# Copyright (c) 2018 Adrian Chirieac <chirieacam@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Utility methods for docstring checking.""" + +from __future__ import absolute_import, print_function + +import re + +import astroid + +from pylint.checkers import utils + + +def space_indentation(s): + """The number of leading spaces in a string + + :param str s: input string + + :rtype: int + :return: number of leading spaces + """ + return len(s) - len(s.lstrip(" ")) + + +def get_setters_property_name(node): + """Get the name of the property that the given node is a setter for. + + :param node: The node to get the property name for. + :type node: str + + :rtype: str or None + :returns: The name of the property that the node is a setter for, + or None if one could not be found. + """ + decorators = node.decorators.nodes if node.decorators else [] + for decorator in decorators: + if ( + isinstance(decorator, astroid.Attribute) + and decorator.attrname == "setter" + and isinstance(decorator.expr, astroid.Name) + ): + return decorator.expr.name + return None + + +def get_setters_property(node): + """Get the property node for the given setter node. + + :param node: The node to get the property for. + :type node: astroid.FunctionDef + + :rtype: astroid.FunctionDef or None + :returns: The node relating to the property of the given setter node, + or None if one could not be found. + """ + property_ = None + + property_name = get_setters_property_name(node) + class_node = utils.node_frame_class(node) + if property_name and class_node: + class_attrs = class_node.getattr(node.name) + for attr in class_attrs: + if utils.decorated_with_property(attr): + property_ = attr + break + + return property_ + + +def returns_something(return_node): + """Check if a return node returns a value other than None. + + :param return_node: The return node to check. + :type return_node: astroid.Return + + :rtype: bool + :return: True if the return node returns a value other than None, + False otherwise. + """ + returns = return_node.value + + if returns is None: + return False + + return not (isinstance(returns, astroid.Const) and returns.value is None) + + +def possible_exc_types(node): + """ + Gets all of the possible raised exception types for the given raise node. + + .. note:: + + Caught exception types are ignored. + + + :param node: The raise node to find exception types for. + :type node: astroid.node_classes.NodeNG + + :returns: A list of exception types possibly raised by :param:`node`. + :rtype: set(str) + """ + excs = [] + if isinstance(node.exc, astroid.Name): + inferred = utils.safe_infer(node.exc) + if inferred: + excs = [inferred.name] + elif isinstance(node.exc, astroid.Call) and isinstance(node.exc.func, astroid.Name): + target = utils.safe_infer(node.exc.func) + if isinstance(target, astroid.ClassDef): + excs = [target.name] + elif isinstance(target, astroid.FunctionDef): + for ret in target.nodes_of_class(astroid.Return): + if ret.frame() != target: + # return from inner function - ignore it + continue + + val = utils.safe_infer(ret.value) + if ( + val + and isinstance(val, (astroid.Instance, astroid.ClassDef)) + and utils.inherit_from_std_ex(val) + ): + excs.append(val.name) + elif node.exc is None: + handler = node.parent + while handler and not isinstance(handler, astroid.ExceptHandler): + handler = handler.parent + + if handler and handler.type: + inferred_excs = astroid.unpack_infer(handler.type) + excs = (exc.name for exc in inferred_excs if exc is not astroid.Uninferable) + + try: + return {exc for exc in excs if not utils.node_ignores_exception(node, exc)} + except astroid.InferenceError: + return set() + + +def docstringify(docstring, default_type="default"): + for docstring_type in [ + SphinxDocstring, + EpytextDocstring, + GoogleDocstring, + NumpyDocstring, + ]: + instance = docstring_type(docstring) + if instance.is_valid(): + return instance + + docstring_type = DOCSTRING_TYPES.get(default_type, Docstring) + return docstring_type(docstring) + + +class Docstring: + re_for_parameters_see = re.compile( + r""" + For\s+the\s+(other)?\s*parameters\s*,\s+see + """, + re.X | re.S, + ) + + supports_yields = None + """True if the docstring supports a "yield" section. + + False if the docstring uses the returns section to document generators. + """ + + # These methods are designed to be overridden + # pylint: disable=no-self-use + def __init__(self, doc): + doc = doc or "" + self.doc = doc.expandtabs() + + def is_valid(self): + return False + + def exceptions(self): + return set() + + def has_params(self): + return False + + def has_returns(self): + return False + + def has_rtype(self): + return False + + def has_property_returns(self): + return False + + def has_property_type(self): + return False + + def has_yields(self): + return False + + def has_yields_type(self): + return False + + def match_param_docs(self): + return set(), set() + + def params_documented_elsewhere(self): + return self.re_for_parameters_see.search(self.doc) is not None + + +class SphinxDocstring(Docstring): + re_type = r"[\w\.]+" + + re_simple_container_type = r""" + {type} # a container type + [\(\[] [^\n\s]+ [\)\]] # with the contents of the container + """.format( + type=re_type + ) + + re_xref = r""" + (?::\w+:)? # optional tag + `{}` # what to reference + """.format( + re_type + ) + + re_param_raw = r""" + : # initial colon + (?: # Sphinx keywords + param|parameter| + arg|argument| + key|keyword + ) + \s+ # whitespace + + (?: # optional type declaration + ({type}|{container_type}) + \s+ + )? + + (\w+) # Parameter name + \s* # whitespace + : # final colon + """.format( + type=re_type, container_type=re_simple_container_type + ) + re_param_in_docstring = re.compile(re_param_raw, re.X | re.S) + + re_type_raw = r""" + :type # Sphinx keyword + \s+ # whitespace + ({type}) # Parameter name + \s* # whitespace + : # final colon + """.format( + type=re_type + ) + re_type_in_docstring = re.compile(re_type_raw, re.X | re.S) + + re_property_type_raw = r""" + :type: # Sphinx keyword + \s+ # whitespace + {type} # type declaration + """.format( + type=re_type + ) + re_property_type_in_docstring = re.compile(re_property_type_raw, re.X | re.S) + + re_raise_raw = r""" + : # initial colon + (?: # Sphinx keyword + raises?| + except|exception + ) + \s+ # whitespace + + (?: # type declaration + ({type}) + \s+ + )? + + (\w+) # Parameter name + \s* # whitespace + : # final colon + """.format( + type=re_type + ) + re_raise_in_docstring = re.compile(re_raise_raw, re.X | re.S) + + re_rtype_in_docstring = re.compile(r":rtype:") + + re_returns_in_docstring = re.compile(r":returns?:") + + supports_yields = False + + def is_valid(self): + return bool( + self.re_param_in_docstring.search(self.doc) + or self.re_raise_in_docstring.search(self.doc) + or self.re_rtype_in_docstring.search(self.doc) + or self.re_returns_in_docstring.search(self.doc) + or self.re_property_type_in_docstring.search(self.doc) + ) + + def exceptions(self): + types = set() + + for match in re.finditer(self.re_raise_in_docstring, self.doc): + raise_type = match.group(2) + types.add(raise_type) + + return types + + def has_params(self): + if not self.doc: + return False + + return self.re_param_in_docstring.search(self.doc) is not None + + def has_returns(self): + if not self.doc: + return False + + return bool(self.re_returns_in_docstring.search(self.doc)) + + def has_rtype(self): + if not self.doc: + return False + + return bool(self.re_rtype_in_docstring.search(self.doc)) + + def has_property_returns(self): + if not self.doc: + return False + + # The summary line is the return doc, + # so the first line must not be a known directive. + return not self.doc.lstrip().startswith(":") + + def has_property_type(self): + if not self.doc: + return False + + return bool(self.re_property_type_in_docstring.search(self.doc)) + + def match_param_docs(self): + params_with_doc = set() + params_with_type = set() + + for match in re.finditer(self.re_param_in_docstring, self.doc): + name = match.group(2) + params_with_doc.add(name) + param_type = match.group(1) + if param_type is not None: + params_with_type.add(name) + + params_with_type.update(re.findall(self.re_type_in_docstring, self.doc)) + return params_with_doc, params_with_type + + +class EpytextDocstring(SphinxDocstring): + """ + Epytext is similar to Sphinx. See the docs: + http://epydoc.sourceforge.net/epytext.html + http://epydoc.sourceforge.net/fields.html#fields + + It's used in PyCharm: + https://www.jetbrains.com/help/pycharm/2016.1/creating-documentation-comments.html#d848203e314 + https://www.jetbrains.com/help/pycharm/2016.1/using-docstrings-to-specify-types.html + """ + + re_param_in_docstring = re.compile( + SphinxDocstring.re_param_raw.replace(":", "@", 1), re.X | re.S + ) + + re_type_in_docstring = re.compile( + SphinxDocstring.re_type_raw.replace(":", "@", 1), re.X | re.S + ) + + re_property_type_in_docstring = re.compile( + SphinxDocstring.re_property_type_raw.replace(":", "@", 1), re.X | re.S + ) + + re_raise_in_docstring = re.compile( + SphinxDocstring.re_raise_raw.replace(":", "@", 1), re.X | re.S + ) + + re_rtype_in_docstring = re.compile( + r""" + @ # initial "at" symbol + (?: # Epytext keyword + rtype|returntype + ) + : # final colon + """, + re.X | re.S, + ) + + re_returns_in_docstring = re.compile(r"@returns?:") + + def has_property_returns(self): + if not self.doc: + return False + + # If this is a property docstring, the summary is the return doc. + if self.has_property_type(): + # The summary line is the return doc, + # so the first line must not be a known directive. + return not self.doc.lstrip().startswith("@") + + return False + + +class GoogleDocstring(Docstring): + re_type = SphinxDocstring.re_type + + re_xref = SphinxDocstring.re_xref + + re_container_type = r""" + (?:{type}|{xref}) # a container type + [\(\[] [^\n]+ [\)\]] # with the contents of the container + """.format( + type=re_type, xref=re_xref + ) + + re_multiple_type = r""" + (?:{container_type}|{type}|{xref}) + (?:\s+or\s+(?:{container_type}|{type}|{xref}))* + """.format( + type=re_type, xref=re_xref, container_type=re_container_type + ) + + _re_section_template = r""" + ^([ ]*) {0} \s*: \s*$ # Google parameter header + ( .* ) # section + """ + + re_param_section = re.compile( + _re_section_template.format(r"(?:Args|Arguments|Parameters)"), + re.X | re.S | re.M, + ) + + re_keyword_param_section = re.compile( + _re_section_template.format(r"Keyword\s(?:Args|Arguments|Parameters)"), + re.X | re.S | re.M, + ) + + re_param_line = re.compile( + r""" + \s* \*{{0,2}}(\w+) # identifier potentially with asterisks + \s* ( [(] + {type} + (?:,\s+optional)? + [)] )? \s* : # optional type declaration + \s* (.*) # beginning of optional description + """.format( + type=re_multiple_type + ), + re.X | re.S | re.M, + ) + + re_raise_section = re.compile( + _re_section_template.format(r"Raises"), re.X | re.S | re.M + ) + + re_raise_line = re.compile( + r""" + \s* ({type}) \s* : # identifier + \s* (.*) # beginning of optional description + """.format( + type=re_type + ), + re.X | re.S | re.M, + ) + + re_returns_section = re.compile( + _re_section_template.format(r"Returns?"), re.X | re.S | re.M + ) + + re_returns_line = re.compile( + r""" + \s* ({type}:)? # identifier + \s* (.*) # beginning of description + """.format( + type=re_multiple_type + ), + re.X | re.S | re.M, + ) + + re_property_returns_line = re.compile( + r""" + ^{type}: # indentifier + \s* (.*) # Summary line / description + """.format( + type=re_multiple_type + ), + re.X | re.S | re.M, + ) + + re_yields_section = re.compile( + _re_section_template.format(r"Yields?"), re.X | re.S | re.M + ) + + re_yields_line = re_returns_line + + supports_yields = True + + def is_valid(self): + return bool( + self.re_param_section.search(self.doc) + or self.re_raise_section.search(self.doc) + or self.re_returns_section.search(self.doc) + or self.re_yields_section.search(self.doc) + or self.re_property_returns_line.search(self._first_line()) + ) + + def has_params(self): + if not self.doc: + return False + + return self.re_param_section.search(self.doc) is not None + + def has_returns(self): + if not self.doc: + return False + + entries = self._parse_section(self.re_returns_section) + for entry in entries: + match = self.re_returns_line.match(entry) + if not match: + continue + + return_desc = match.group(2) + if return_desc: + return True + + return False + + def has_rtype(self): + if not self.doc: + return False + + entries = self._parse_section(self.re_returns_section) + for entry in entries: + match = self.re_returns_line.match(entry) + if not match: + continue + + return_type = match.group(1) + if return_type: + return True + + return False + + def has_property_returns(self): + # The summary line is the return doc, + # so the first line must not be a known directive. + first_line = self._first_line() + return not bool( + self.re_param_section.search(first_line) + or self.re_raise_section.search(first_line) + or self.re_returns_section.search(first_line) + or self.re_yields_section.search(first_line) + ) + + def has_property_type(self): + if not self.doc: + return False + + return bool(self.re_property_returns_line.match(self._first_line())) + + def has_yields(self): + if not self.doc: + return False + + entries = self._parse_section(self.re_yields_section) + for entry in entries: + match = self.re_yields_line.match(entry) + if not match: + continue + + yield_desc = match.group(2) + if yield_desc: + return True + + return False + + def has_yields_type(self): + if not self.doc: + return False + + entries = self._parse_section(self.re_yields_section) + for entry in entries: + match = self.re_yields_line.match(entry) + if not match: + continue + + yield_type = match.group(1) + if yield_type: + return True + + return False + + def exceptions(self): + types = set() + + entries = self._parse_section(self.re_raise_section) + for entry in entries: + match = self.re_raise_line.match(entry) + if not match: + continue + + exc_type = match.group(1) + exc_desc = match.group(2) + if exc_desc: + types.add(exc_type) + + return types + + def match_param_docs(self): + params_with_doc = set() + params_with_type = set() + + entries = self._parse_section(self.re_param_section) + entries.extend(self._parse_section(self.re_keyword_param_section)) + for entry in entries: + match = self.re_param_line.match(entry) + if not match: + continue + + param_name = match.group(1) + param_type = match.group(2) + param_desc = match.group(3) + if param_type: + params_with_type.add(param_name) + + if param_desc: + params_with_doc.add(param_name) + + return params_with_doc, params_with_type + + def _first_line(self): + return self.doc.lstrip().split("\n", 1)[0] + + @staticmethod + def min_section_indent(section_match): + return len(section_match.group(1)) + 1 + + @staticmethod + def _is_section_header(_): + # Google parsing does not need to detect section headers, + # because it works off of indentation level only + return False + + def _parse_section(self, section_re): + section_match = section_re.search(self.doc) + if section_match is None: + return [] + + min_indentation = self.min_section_indent(section_match) + + entries = [] + entry = [] + is_first = True + for line in section_match.group(2).splitlines(): + if not line.strip(): + continue + indentation = space_indentation(line) + if indentation < min_indentation: + break + + # The first line after the header defines the minimum + # indentation. + if is_first: + min_indentation = indentation + is_first = False + + if indentation == min_indentation: + if self._is_section_header(line): + break + # Lines with minimum indentation must contain the beginning + # of a new parameter documentation. + if entry: + entries.append("\n".join(entry)) + entry = [] + + entry.append(line) + + if entry: + entries.append("\n".join(entry)) + + return entries + + +class NumpyDocstring(GoogleDocstring): + _re_section_template = r""" + ^([ ]*) {0} \s*?$ # Numpy parameters header + \s* [-=]+ \s*?$ # underline + ( .* ) # section + """ + + re_param_section = re.compile( + _re_section_template.format(r"(?:Args|Arguments|Parameters)"), + re.X | re.S | re.M, + ) + + re_param_line = re.compile( + r""" + \s* (\w+) # identifier + \s* : + \s* (?:({type})(?:,\s+optional)?)? # optional type declaration + \n # description starts on a new line + \s* (.*) # description + """.format( + type=GoogleDocstring.re_multiple_type + ), + re.X | re.S, + ) + + re_raise_section = re.compile( + _re_section_template.format(r"Raises"), re.X | re.S | re.M + ) + + re_raise_line = re.compile( + r""" + \s* ({type})$ # type declaration + \s* (.*) # optional description + """.format( + type=GoogleDocstring.re_type + ), + re.X | re.S | re.M, + ) + + re_returns_section = re.compile( + _re_section_template.format(r"Returns?"), re.X | re.S | re.M + ) + + re_returns_line = re.compile( + r""" + \s* (?:\w+\s+:\s+)? # optional name + ({type})$ # type declaration + \s* (.*) # optional description + """.format( + type=GoogleDocstring.re_multiple_type + ), + re.X | re.S | re.M, + ) + + re_yields_section = re.compile( + _re_section_template.format(r"Yields?"), re.X | re.S | re.M + ) + + re_yields_line = re_returns_line + + supports_yields = True + + @staticmethod + def min_section_indent(section_match): + return len(section_match.group(1)) + + @staticmethod + def _is_section_header(line): + return bool(re.match(r"\s*-+$", line)) + + +DOCSTRING_TYPES = { + "sphinx": SphinxDocstring, + "epytext": EpytextDocstring, + "google": GoogleDocstring, + "numpy": NumpyDocstring, + "default": Docstring, +} +"""A map of the name of the docstring type to its class. + +:type: dict(str, type) +""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/bad_builtin.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/bad_builtin.py new file mode 100644 index 0000000..2609d31 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/bad_builtin.py @@ -0,0 +1,73 @@ +# Copyright (c) 2016 Claudiu Popa <pcmanticore@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Checker for deprecated builtins.""" +import sys + +import astroid +from pylint.checkers import BaseChecker +from pylint.checkers.utils import check_messages +from pylint.interfaces import IAstroidChecker + + +BAD_FUNCTIONS = ["map", "filter"] +if sys.version_info < (3, 0): + BAD_FUNCTIONS.append("input") +# Some hints regarding the use of bad builtins. +BUILTIN_HINTS = {"map": "Using a list comprehension can be clearer."} +BUILTIN_HINTS["filter"] = BUILTIN_HINTS["map"] + + +class BadBuiltinChecker(BaseChecker): + + __implements__ = (IAstroidChecker,) + name = "deprecated_builtins" + msgs = { + "W0141": ( + "Used builtin function %s", + "bad-builtin", + "Used when a black listed builtin function is used (see the " + "bad-function option). Usual black listed functions are the ones " + "like map, or filter , where Python offers now some cleaner " + "alternative like list comprehension.", + ) + } + + options = ( + ( + "bad-functions", + { + "default": BAD_FUNCTIONS, + "type": "csv", + "metavar": "<builtin function names>", + "help": "List of builtins function names that should not be " + "used, separated by a comma", + }, + ), + ) + + @check_messages("bad-builtin") + def visit_call(self, node): + if isinstance(node.func, astroid.Name): + name = node.func.name + # ignore the name if it's not a builtin (i.e. not defined in the + # locals nor globals scope) + if not (name in node.frame() or name in node.root()): + if name in self.config.bad_functions: + hint = BUILTIN_HINTS.get(name) + if hint: + args = "%r. %s" % (name, hint) + else: + args = repr(name) + self.add_message("bad-builtin", node=node, args=args) + + +def register(linter): + """Required method to auto register this checker. + + :param linter: Main interface object for Pylint plugins + :type linter: Pylint object + """ + linter.register_checker(BadBuiltinChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/check_docs.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/check_docs.py new file mode 100644 index 0000000..7f7f643 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/check_docs.py @@ -0,0 +1,23 @@ +# Copyright (c) 2014-2015 Bruno Daniel <bruno.daniel@blue-yonder.com> +# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import warnings + +from pylint.extensions import docparams + + +def register(linter): + """Required method to auto register this checker. + + :param linter: Main interface object for Pylint plugins + :type linter: Pylint object + """ + warnings.warn( + "This plugin is deprecated, use pylint.extensions.docparams instead.", + DeprecationWarning, + ) + linter.register_checker(docparams.DocstringParameterChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/check_elif.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/check_elif.py new file mode 100644 index 0000000..a259361 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/check_elif.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import astroid +from pylint.checkers import BaseTokenChecker +from pylint.checkers.utils import check_messages +from pylint.interfaces import ITokenChecker, IAstroidChecker + + +class ElseifUsedChecker(BaseTokenChecker): + """Checks for use of "else if" when an "elif" could be used + """ + + __implements__ = (ITokenChecker, IAstroidChecker) + name = "else_if_used" + msgs = { + "R5501": ( + 'Consider using "elif" instead of "else if"', + "else-if-used", + "Used when an else statement is immediately followed by " + "an if statement and does not contain statements that " + "would be unrelated to it.", + ) + } + + def __init__(self, linter=None): + BaseTokenChecker.__init__(self, linter) + self._init() + + def _init(self): + self._elifs = [] + self._if_counter = 0 + + def process_tokens(self, tokens): + # Process tokens and look for 'if' or 'elif' + for _, token, _, _, _ in tokens: + if token == "elif": + self._elifs.append(True) + elif token == "if": + self._elifs.append(False) + + def leave_module(self, _): + self._init() + + def visit_ifexp(self, _): + self._if_counter += 1 + + def visit_comprehension(self, node): + self._if_counter += len(node.ifs) + + @check_messages("else-if-used") + def visit_if(self, node): + if isinstance(node.parent, astroid.If): + orelse = node.parent.orelse + # current if node must directly follow an "else" + if orelse and orelse == [node]: + if not self._elifs[self._if_counter]: + self.add_message("else-if-used", node=node) + self._if_counter += 1 + + +def register(linter): + """Required method to auto register this checker. + + :param linter: Main interface object for Pylint plugins + :type linter: Pylint object + """ + linter.register_checker(ElseifUsedChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/comparetozero.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/comparetozero.py new file mode 100644 index 0000000..16c9428 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/comparetozero.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Looks for comparisons to empty string.""" + +import itertools + +import astroid + +from pylint import interfaces +from pylint import checkers +from pylint.checkers import utils + + +def _is_constant_zero(node): + return isinstance(node, astroid.Const) and node.value == 0 + + +class CompareToZeroChecker(checkers.BaseChecker): + """Checks for comparisons to zero. + Most of the times you should use the fact that integers with a value of 0 are false. + An exception to this rule is when 0 is allowed in the program and has a + different meaning than None! + """ + + __implements__ = (interfaces.IAstroidChecker,) + + # configuration section name + name = "compare-to-zero" + msgs = { + "C2001": ( + "Avoid comparisons to zero", + "compare-to-zero", + "Used when Pylint detects comparison to a 0 constant.", + ) + } + + priority = -2 + options = () + + @utils.check_messages("compare-to-zero") + def visit_compare(self, node): + _operators = ["!=", "==", "is not", "is"] + # note: astroid.Compare has the left most operand in node.left + # while the rest are a list of tuples in node.ops + # the format of the tuple is ('compare operator sign', node) + # here we squash everything into `ops` to make it easier for processing later + ops = [("", node.left)] + ops.extend(node.ops) + ops = list(itertools.chain(*ops)) + + for ops_idx in range(len(ops) - 2): + op_1 = ops[ops_idx] + op_2 = ops[ops_idx + 1] + op_3 = ops[ops_idx + 2] + error_detected = False + + # 0 ?? X + if _is_constant_zero(op_1) and op_2 in _operators + ["<"]: + error_detected = True + # X ?? 0 + elif op_2 in _operators + [">"] and _is_constant_zero(op_3): + error_detected = True + + if error_detected: + self.add_message("compare-to-zero", node=node) + + +def register(linter): + """Required method to auto register this checker.""" + linter.register_checker(CompareToZeroChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/docparams.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/docparams.py new file mode 100644 index 0000000..d55515a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/docparams.py @@ -0,0 +1,494 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2015 Bruno Daniel <bruno.daniel@blue-yonder.com> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2017 John Paraskevopoulos <io.paraskev@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Adam Dangoor <adamdangoor@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Pylint plugin for checking in Sphinx, Google, or Numpy style docstrings +""" +from __future__ import print_function, division, absolute_import + +import astroid + +from pylint.interfaces import IAstroidChecker +from pylint.checkers import BaseChecker +from pylint.checkers import utils as checker_utils +import pylint.extensions._check_docs_utils as utils + + +class DocstringParameterChecker(BaseChecker): + """Checker for Sphinx, Google, or Numpy style docstrings + + * Check that all function, method and constructor parameters are mentioned + in the params and types part of the docstring. Constructor parameters + can be documented in either the class docstring or ``__init__`` docstring, + but not both. + * Check that there are no naming inconsistencies between the signature and + the documentation, i.e. also report documented parameters that are missing + in the signature. This is important to find cases where parameters are + renamed only in the code, not in the documentation. + * Check that all explicitly raised exceptions in a function are documented + in the function docstring. Caught exceptions are ignored. + + Activate this checker by adding the line:: + + load-plugins=pylint.extensions.docparams + + to the ``MASTER`` section of your ``.pylintrc``. + + :param linter: linter object + :type linter: :class:`pylint.lint.PyLinter` + """ + + __implements__ = IAstroidChecker + + name = "parameter_documentation" + msgs = { + "W9005": ( + '"%s" has constructor parameters documented in class and __init__', + "multiple-constructor-doc", + "Please remove parameter declarations in the class or constructor.", + ), + "W9006": ( + '"%s" not documented as being raised', + "missing-raises-doc", + "Please document exceptions for all raised exception types.", + ), + "W9008": ( + "Redundant returns documentation", + "redundant-returns-doc", + "Please remove the return/rtype documentation from this method.", + ), + "W9010": ( + "Redundant yields documentation", + "redundant-yields-doc", + "Please remove the yields documentation from this method.", + ), + "W9011": ( + "Missing return documentation", + "missing-return-doc", + "Please add documentation about what this method returns.", + {"old_names": [("W9007", "missing-returns-doc")]}, + ), + "W9012": ( + "Missing return type documentation", + "missing-return-type-doc", + "Please document the type returned by this method.", + # we can't use the same old_name for two different warnings + # {'old_names': [('W9007', 'missing-returns-doc')]}, + ), + "W9013": ( + "Missing yield documentation", + "missing-yield-doc", + "Please add documentation about what this generator yields.", + {"old_names": [("W9009", "missing-yields-doc")]}, + ), + "W9014": ( + "Missing yield type documentation", + "missing-yield-type-doc", + "Please document the type yielded by this method.", + # we can't use the same old_name for two different warnings + # {'old_names': [('W9009', 'missing-yields-doc')]}, + ), + "W9015": ( + '"%s" missing in parameter documentation', + "missing-param-doc", + "Please add parameter declarations for all parameters.", + {"old_names": [("W9003", "missing-param-doc")]}, + ), + "W9016": ( + '"%s" missing in parameter type documentation', + "missing-type-doc", + "Please add parameter type declarations for all parameters.", + {"old_names": [("W9004", "missing-type-doc")]}, + ), + "W9017": ( + '"%s" differing in parameter documentation', + "differing-param-doc", + "Please check parameter names in declarations.", + ), + "W9018": ( + '"%s" differing in parameter type documentation', + "differing-type-doc", + "Please check parameter names in type declarations.", + ), + } + + options = ( + ( + "accept-no-param-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing parameter " + "documentation in the docstring of a function that has " + "parameters.", + }, + ), + ( + "accept-no-raise-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing raises " + "documentation in the docstring of a function that " + "raises an exception.", + }, + ), + ( + "accept-no-return-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing return " + "documentation in the docstring of a function that " + "returns a statement.", + }, + ), + ( + "accept-no-yields-doc", + { + "default": True, + "type": "yn", + "metavar": "<y or n>", + "help": "Whether to accept totally missing yields " + "documentation in the docstring of a generator.", + }, + ), + ( + "default-docstring-type", + { + "type": "choice", + "default": "default", + "choices": list(utils.DOCSTRING_TYPES), + "help": "If the docstring type cannot be guessed " + "the specified docstring type will be used.", + }, + ), + ) + + priority = -2 + + constructor_names = {"__init__", "__new__"} + not_needed_param_in_docstring = {"self", "cls"} + + def visit_functiondef(self, node): + """Called for function and method definitions (def). + + :param node: Node for a function or method definition in the AST + :type node: :class:`astroid.scoped_nodes.Function` + """ + node_doc = utils.docstringify(node.doc, self.config.default_docstring_type) + self.check_functiondef_params(node, node_doc) + self.check_functiondef_returns(node, node_doc) + self.check_functiondef_yields(node, node_doc) + + def check_functiondef_params(self, node, node_doc): + node_allow_no_param = None + if node.name in self.constructor_names: + class_node = checker_utils.node_frame_class(node) + if class_node is not None: + class_doc = utils.docstringify( + class_node.doc, self.config.default_docstring_type + ) + self.check_single_constructor_params(class_doc, node_doc, class_node) + + # __init__ or class docstrings can have no parameters documented + # as long as the other documents them. + node_allow_no_param = ( + class_doc.has_params() + or class_doc.params_documented_elsewhere() + or None + ) + class_allow_no_param = ( + node_doc.has_params() + or node_doc.params_documented_elsewhere() + or None + ) + + self.check_arguments_in_docstring( + class_doc, node.args, class_node, class_allow_no_param + ) + + self.check_arguments_in_docstring( + node_doc, node.args, node, node_allow_no_param + ) + + def check_functiondef_returns(self, node, node_doc): + if (not node_doc.supports_yields and node.is_generator()) or node.is_abstract(): + return + + return_nodes = node.nodes_of_class(astroid.Return) + if (node_doc.has_returns() or node_doc.has_rtype()) and not any( + utils.returns_something(ret_node) for ret_node in return_nodes + ): + self.add_message("redundant-returns-doc", node=node) + + def check_functiondef_yields(self, node, node_doc): + if not node_doc.supports_yields or node.is_abstract(): + return + + if ( + node_doc.has_yields() or node_doc.has_yields_type() + ) and not node.is_generator(): + self.add_message("redundant-yields-doc", node=node) + + def visit_raise(self, node): + func_node = node.frame() + if not isinstance(func_node, astroid.FunctionDef): + return + + expected_excs = utils.possible_exc_types(node) + if not expected_excs: + return + + if not func_node.doc: + # If this is a property setter, + # the property should have the docstring instead. + property_ = utils.get_setters_property(func_node) + if property_: + func_node = property_ + + doc = utils.docstringify(func_node.doc, self.config.default_docstring_type) + if not doc.is_valid(): + if doc.doc: + self._handle_no_raise_doc(expected_excs, func_node) + return + + found_excs = doc.exceptions() + missing_excs = expected_excs - found_excs + self._add_raise_message(missing_excs, func_node) + + def visit_return(self, node): + if not utils.returns_something(node): + return + + func_node = node.frame() + if not isinstance(func_node, astroid.FunctionDef): + return + + doc = utils.docstringify(func_node.doc, self.config.default_docstring_type) + if not doc.is_valid() and self.config.accept_no_return_doc: + return + + is_property = checker_utils.decorated_with_property(func_node) + + if not (doc.has_returns() or (doc.has_property_returns() and is_property)): + self.add_message("missing-return-doc", node=func_node) + + if func_node.returns: + return + + if not (doc.has_rtype() or (doc.has_property_type() and is_property)): + self.add_message("missing-return-type-doc", node=func_node) + + def visit_yield(self, node): + func_node = node.frame() + if not isinstance(func_node, astroid.FunctionDef): + return + + doc = utils.docstringify(func_node.doc, self.config.default_docstring_type) + if not doc.is_valid() and self.config.accept_no_yields_doc: + return + + if doc.supports_yields: + doc_has_yields = doc.has_yields() + doc_has_yields_type = doc.has_yields_type() + else: + doc_has_yields = doc.has_returns() + doc_has_yields_type = doc.has_rtype() + + if not doc_has_yields: + self.add_message("missing-yield-doc", node=func_node) + + if not doc_has_yields_type: + self.add_message("missing-yield-type-doc", node=func_node) + + def visit_yieldfrom(self, node): + self.visit_yield(node) + + def check_arguments_in_docstring( + self, doc, arguments_node, warning_node, accept_no_param_doc=None + ): + """Check that all parameters in a function, method or class constructor + on the one hand and the parameters mentioned in the parameter + documentation (e.g. the Sphinx tags 'param' and 'type') on the other + hand are consistent with each other. + + * Undocumented parameters except 'self' are noticed. + * Undocumented parameter types except for 'self' and the ``*<args>`` + and ``**<kwargs>`` parameters are noticed. + * Parameters mentioned in the parameter documentation that don't or no + longer exist in the function parameter list are noticed. + * If the text "For the parameters, see" or "For the other parameters, + see" (ignoring additional whitespace) is mentioned in the docstring, + missing parameter documentation is tolerated. + * If there's no Sphinx style, Google style or NumPy style parameter + documentation at all, i.e. ``:param`` is never mentioned etc., the + checker assumes that the parameters are documented in another format + and the absence is tolerated. + + :param doc: Docstring for the function, method or class. + :type doc: str + + :param arguments_node: Arguments node for the function, method or + class constructor. + :type arguments_node: :class:`astroid.scoped_nodes.Arguments` + + :param warning_node: The node to assign the warnings to + :type warning_node: :class:`astroid.scoped_nodes.Node` + + :param accept_no_param_doc: Whether or not to allow no parameters + to be documented. + If None then this value is read from the configuration. + :type accept_no_param_doc: bool or None + """ + # Tolerate missing param or type declarations if there is a link to + # another method carrying the same name. + if not doc.doc: + return + + if accept_no_param_doc is None: + accept_no_param_doc = self.config.accept_no_param_doc + tolerate_missing_params = doc.params_documented_elsewhere() + + # Collect the function arguments. + expected_argument_names = {arg.name for arg in arguments_node.args} + expected_argument_names.update(arg.name for arg in arguments_node.kwonlyargs) + not_needed_type_in_docstring = self.not_needed_param_in_docstring.copy() + + if arguments_node.vararg is not None: + expected_argument_names.add(arguments_node.vararg) + not_needed_type_in_docstring.add(arguments_node.vararg) + if arguments_node.kwarg is not None: + expected_argument_names.add(arguments_node.kwarg) + not_needed_type_in_docstring.add(arguments_node.kwarg) + params_with_doc, params_with_type = doc.match_param_docs() + + # Tolerate no parameter documentation at all. + if not params_with_doc and not params_with_type and accept_no_param_doc: + tolerate_missing_params = True + + def _compare_missing_args(found_argument_names, message_id, not_needed_names): + """Compare the found argument names with the expected ones and + generate a message if there are arguments missing. + + :param set found_argument_names: argument names found in the + docstring + + :param str message_id: pylint message id + + :param not_needed_names: names that may be omitted + :type not_needed_names: set of str + """ + if not tolerate_missing_params: + missing_argument_names = ( + expected_argument_names - found_argument_names + ) - not_needed_names + if missing_argument_names: + self.add_message( + message_id, + args=(", ".join(sorted(missing_argument_names)),), + node=warning_node, + ) + + def _compare_different_args(found_argument_names, message_id, not_needed_names): + """Compare the found argument names with the expected ones and + generate a message if there are extra arguments found. + + :param set found_argument_names: argument names found in the + docstring + + :param str message_id: pylint message id + + :param not_needed_names: names that may be omitted + :type not_needed_names: set of str + """ + differing_argument_names = ( + (expected_argument_names ^ found_argument_names) + - not_needed_names + - expected_argument_names + ) + + if differing_argument_names: + self.add_message( + message_id, + args=(", ".join(sorted(differing_argument_names)),), + node=warning_node, + ) + + _compare_missing_args( + params_with_doc, "missing-param-doc", self.not_needed_param_in_docstring + ) + + for index, arg_name in enumerate(arguments_node.args): + if arguments_node.annotations[index]: + params_with_type.add(arg_name.name) + + _compare_missing_args( + params_with_type, "missing-type-doc", not_needed_type_in_docstring + ) + + _compare_different_args( + params_with_doc, "differing-param-doc", self.not_needed_param_in_docstring + ) + _compare_different_args( + params_with_type, "differing-type-doc", not_needed_type_in_docstring + ) + + def check_single_constructor_params(self, class_doc, init_doc, class_node): + if class_doc.has_params() and init_doc.has_params(): + self.add_message( + "multiple-constructor-doc", args=(class_node.name,), node=class_node + ) + + def _handle_no_raise_doc(self, excs, node): + if self.config.accept_no_raise_doc: + return + + self._add_raise_message(excs, node) + + def _add_raise_message(self, missing_excs, node): + """ + Adds a message on :param:`node` for the missing exception type. + + :param missing_excs: A list of missing exception types. + :type missing_excs: set(str) + + :param node: The node show the message on. + :type node: astroid.node_classes.NodeNG + """ + if node.is_abstract(): + try: + missing_excs.remove("NotImplementedError") + except KeyError: + pass + + if not missing_excs: + return + + self.add_message( + "missing-raises-doc", args=(", ".join(sorted(missing_excs)),), node=node + ) + + +def register(linter): + """Required method to auto register this checker. + + :param linter: Main interface object for Pylint plugins + :type linter: Pylint object + """ + linter.register_checker(DocstringParameterChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/docstyle.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/docstyle.py new file mode 100644 index 0000000..1f50a41 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/docstyle.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Luis Escobar <lescobar@vauxoo.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import linecache + +from pylint import checkers +from pylint.interfaces import IAstroidChecker, HIGH +from pylint.checkers.utils import check_messages + + +class DocStringStyleChecker(checkers.BaseChecker): + """Checks format of docstrings based on PEP 0257""" + + __implements__ = IAstroidChecker + name = "docstyle" + + msgs = { + "C0198": ( + 'Bad docstring quotes in %s, expected """, given %s', + "bad-docstring-quotes", + "Used when a docstring does not have triple double quotes.", + ), + "C0199": ( + "First line empty in %s docstring", + "docstring-first-line-empty", + "Used when a blank line is found at the beginning of a docstring.", + ), + } + + @check_messages("docstring-first-line-empty", "bad-docstring-quotes") + def visit_module(self, node): + self._check_docstring("module", node) + + def visit_classdef(self, node): + self._check_docstring("class", node) + + def visit_functiondef(self, node): + ftype = "method" if node.is_method() else "function" + self._check_docstring(ftype, node) + + visit_asyncfunctiondef = visit_functiondef + + def _check_docstring(self, node_type, node): + docstring = node.doc + if docstring and docstring[0] == "\n": + self.add_message( + "docstring-first-line-empty", + node=node, + args=(node_type,), + confidence=HIGH, + ) + + # Use "linecache", instead of node.as_string(), because the latter + # looses the original form of the docstrings. + + if docstring: + lineno = node.fromlineno + 1 + line = linecache.getline(node.root().file, lineno).lstrip() + if line and line.find('"""') == 0: + return + if line and "'''" in line: + quotes = "'''" + elif line and line[0] == '"': + quotes = '"' + elif line and line[0] == "'": + quotes = "'" + else: + quotes = False + if quotes: + self.add_message( + "bad-docstring-quotes", + node=node, + args=(node_type, quotes), + confidence=HIGH, + ) + + +def register(linter): + """Required method to auto register this checker. + + :param linter: Main interface object for Pylint plugins + :type linter: Pylint object + """ + linter.register_checker(DocStringStyleChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/emptystring.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/emptystring.py new file mode 100644 index 0000000..ddca8f7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/emptystring.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Looks for comparisons to empty string.""" + +import itertools + +import astroid + +from pylint import interfaces +from pylint import checkers +from pylint.checkers import utils + + +def _is_constant_empty_str(node): + return isinstance(node, astroid.Const) and node.value == "" + + +class CompareToEmptyStringChecker(checkers.BaseChecker): + """Checks for comparisons to empty string. + Most of the times you should use the fact that empty strings are false. + An exception to this rule is when an empty string value is allowed in the program + and has a different meaning than None! + """ + + __implements__ = (interfaces.IAstroidChecker,) + + # configuration section name + name = "compare-to-empty-string" + msgs = { + "C1901": ( + "Avoid comparisons to empty string", + "compare-to-empty-string", + "Used when Pylint detects comparison to an empty string constant.", + ) + } + + priority = -2 + options = () + + @utils.check_messages("compare-to-empty-string") + def visit_compare(self, node): + _operators = ["!=", "==", "is not", "is"] + # note: astroid.Compare has the left most operand in node.left + # while the rest are a list of tuples in node.ops + # the format of the tuple is ('compare operator sign', node) + # here we squash everything into `ops` to make it easier for processing later + ops = [("", node.left)] + ops.extend(node.ops) + ops = list(itertools.chain(*ops)) + + for ops_idx in range(len(ops) - 2): + op_1 = ops[ops_idx] + op_2 = ops[ops_idx + 1] + op_3 = ops[ops_idx + 2] + error_detected = False + + # x ?? "" + if _is_constant_empty_str(op_1) and op_2 in _operators: + error_detected = True + # '' ?? X + elif op_2 in _operators and _is_constant_empty_str(op_3): + error_detected = True + + if error_detected: + self.add_message("compare-to-empty-string", node=node) + + +def register(linter): + """Required method to auto register this checker.""" + linter.register_checker(CompareToEmptyStringChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/mccabe.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/mccabe.py new file mode 100644 index 0000000..41eca28 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/mccabe.py @@ -0,0 +1,201 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Module to add McCabe checker class for pylint. """ + +from __future__ import absolute_import + +from mccabe import ( + PathGraph as Mccabe_PathGraph, + PathGraphingAstVisitor as Mccabe_PathGraphingAstVisitor, +) +from pylint import checkers +from pylint.checkers.utils import check_messages +from pylint.interfaces import HIGH, IAstroidChecker + + +class PathGraph(Mccabe_PathGraph): + def __init__(self, node): + super(PathGraph, self).__init__(name="", entity="", lineno=1) + self.root = node + + +class PathGraphingAstVisitor(Mccabe_PathGraphingAstVisitor): + def __init__(self): + super(PathGraphingAstVisitor, self).__init__() + self._bottom_counter = 0 + + def default(self, node, *args): + for child in node.get_children(): + self.dispatch(child, *args) + + def dispatch(self, node, *args): + self.node = node + klass = node.__class__ + meth = self._cache.get(klass) + if meth is None: + className = klass.__name__ + meth = getattr(self.visitor, "visit" + className, self.default) + self._cache[klass] = meth + return meth(node, *args) + + def visitFunctionDef(self, node): + if self.graph is not None: + # closure + pathnode = self._append_node(node) + self.tail = pathnode + self.dispatch_list(node.body) + bottom = "%s" % self._bottom_counter + self._bottom_counter += 1 + self.graph.connect(self.tail, bottom) + self.graph.connect(node, bottom) + self.tail = bottom + else: + self.graph = PathGraph(node) + self.tail = node + self.dispatch_list(node.body) + self.graphs["%s%s" % (self.classname, node.name)] = self.graph + self.reset() + + visitAsyncFunctionDef = visitFunctionDef + + def visitSimpleStatement(self, node): + self._append_node(node) + + visitAssert = ( + visitAssign + ) = ( + visitAugAssign + ) = ( + visitDelete + ) = ( + visitPrint + ) = ( + visitRaise + ) = ( + visitYield + ) = ( + visitImport + ) = ( + visitCall + ) = ( + visitSubscript + ) = ( + visitPass + ) = ( + visitContinue + ) = ( + visitBreak + ) = visitGlobal = visitReturn = visitExpr = visitAwait = visitSimpleStatement + + def visitWith(self, node): + self._append_node(node) + self.dispatch_list(node.body) + + visitAsyncWith = visitWith + + def _append_node(self, node): + if not self.tail: + return None + self.graph.connect(self.tail, node) + self.tail = node + return node + + def _subgraph(self, node, name, extra_blocks=()): + """create the subgraphs representing any `if` and `for` statements""" + if self.graph is None: + # global loop + self.graph = PathGraph(node) + self._subgraph_parse(node, node, extra_blocks) + self.graphs["%s%s" % (self.classname, name)] = self.graph + self.reset() + else: + self._append_node(node) + self._subgraph_parse(node, node, extra_blocks) + + def _subgraph_parse( + self, node, pathnode, extra_blocks + ): # pylint: disable=unused-argument + """parse the body and any `else` block of `if` and `for` statements""" + loose_ends = [] + self.tail = node + self.dispatch_list(node.body) + loose_ends.append(self.tail) + for extra in extra_blocks: + self.tail = node + self.dispatch_list(extra.body) + loose_ends.append(self.tail) + if node.orelse: + self.tail = node + self.dispatch_list(node.orelse) + loose_ends.append(self.tail) + else: + loose_ends.append(node) + if node: + bottom = "%s" % self._bottom_counter + self._bottom_counter += 1 + for le in loose_ends: + self.graph.connect(le, bottom) + self.tail = bottom + + +class McCabeMethodChecker(checkers.BaseChecker): + """Checks McCabe complexity cyclomatic threshold in methods and functions + to validate a too complex code. + """ + + __implements__ = IAstroidChecker + name = "design" + + msgs = { + "R1260": ( + "%s is too complex. The McCabe rating is %d", + "too-complex", + "Used when a method or function is too complex based on " + "McCabe Complexity Cyclomatic", + ) + } + options = ( + ( + "max-complexity", + { + "default": 10, + "type": "int", + "metavar": "<int>", + "help": "McCabe complexity cyclomatic threshold", + }, + ), + ) + + @check_messages("too-complex") + def visit_module(self, node): + """visit an astroid.Module node to check too complex rating and + add message if is greather than max_complexity stored from options""" + visitor = PathGraphingAstVisitor() + for child in node.body: + visitor.preorder(child, visitor) + for graph in visitor.graphs.values(): + complexity = graph.complexity() + node = graph.root + if hasattr(node, "name"): + node_name = "'%s'" % node.name + else: + node_name = "This '%s'" % node.__class__.__name__.lower() + if complexity <= self.config.max_complexity: + continue + self.add_message( + "too-complex", node=node, confidence=HIGH, args=(node_name, complexity) + ) + + +def register(linter): + """Required method to auto register this checker. + + :param linter: Main interface object for Pylint plugins + :type linter: Pylint object + """ + linter.register_checker(McCabeMethodChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/overlapping_exceptions.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/overlapping_exceptions.py new file mode 100644 index 0000000..3b1454c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/overlapping_exceptions.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Looks for overlapping exceptions.""" + +import astroid + +from pylint import interfaces +from pylint import checkers +from pylint.checkers import utils + +from pylint.checkers.exceptions import _annotated_unpack_infer + + +class OverlappingExceptionsChecker(checkers.BaseChecker): + """Checks for two or more exceptions in the same exception handler + clause that are identical or parts of the same inheritance hierarchy + (i.e. overlapping).""" + + __implements__ = interfaces.IAstroidChecker + + name = "overlap-except" + msgs = { + "W0714": ( + "Overlapping exceptions (%s)", + "overlapping-except", + "Used when exceptions in handler overlap or are identical", + ) + } + priority = -2 + options = () + + @utils.check_messages("overlapping-except") + def visit_tryexcept(self, node): + """check for empty except""" + for handler in node.handlers: + if handler.type is None: + continue + if isinstance(handler.type, astroid.BoolOp): + continue + try: + excs = list(_annotated_unpack_infer(handler.type)) + except astroid.InferenceError: + continue + + handled_in_clause = [] + for part, exc in excs: + if exc is astroid.Uninferable: + continue + if isinstance(exc, astroid.Instance) and utils.inherit_from_std_ex(exc): + # pylint: disable=protected-access + exc = exc._proxied + + if not isinstance(exc, astroid.ClassDef): + continue + + exc_ancestors = [ + anc for anc in exc.ancestors() if isinstance(anc, astroid.ClassDef) + ] + + for prev_part, prev_exc in handled_in_clause: + prev_exc_ancestors = [ + anc + for anc in prev_exc.ancestors() + if isinstance(anc, astroid.ClassDef) + ] + if exc == prev_exc: + self.add_message( + "overlapping-except", + node=handler.type, + args="%s and %s are the same" + % (prev_part.as_string(), part.as_string()), + ) + elif prev_exc in exc_ancestors or exc in prev_exc_ancestors: + ancestor = part if exc in prev_exc_ancestors else prev_part + descendant = part if prev_exc in exc_ancestors else prev_part + self.add_message( + "overlapping-except", + node=handler.type, + args="%s is an ancestor class of %s" + % (ancestor.as_string(), descendant.as_string()), + ) + handled_in_clause += [(part, exc)] + + +def register(linter): + """Required method to auto register this checker.""" + linter.register_checker(OverlappingExceptionsChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/extensions/redefined_variable_type.py b/basic python programmes/venv/Lib/site-packages/pylint/extensions/redefined_variable_type.py new file mode 100644 index 0000000..a58f04e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/extensions/redefined_variable_type.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import astroid +from pylint.checkers import BaseChecker +from pylint.checkers.utils import check_messages, is_none, node_type +from pylint.interfaces import IAstroidChecker + + +BUILTINS = "builtins" + + +class MultipleTypesChecker(BaseChecker): + """Checks for variable type redefinitions (NoneType excepted) + + At a function, method, class or module scope + + This rule could be improved: + + - Currently, if an attribute is set to different types in 2 methods of a + same class, it won't be detected (see functional test) + - One could improve the support for inference on assignment with tuples, + ifexpr, etc. Also it would be great to have support for inference on + str.split() + """ + + __implements__ = IAstroidChecker + + name = "multiple_types" + msgs = { + "R0204": ( + "Redefinition of %s type from %s to %s", + "redefined-variable-type", + "Used when the type of a variable changes inside a " + "method or a function.", + ) + } + + def visit_classdef(self, _): + self._assigns.append({}) + + @check_messages("redefined-variable-type") + def leave_classdef(self, _): + self._check_and_add_messages() + + visit_functiondef = visit_classdef + leave_functiondef = leave_module = leave_classdef + + def visit_module(self, _): + self._assigns = [{}] + + def _check_and_add_messages(self): + assigns = self._assigns.pop() + for name, args in assigns.items(): + if len(args) <= 1: + continue + orig_node, orig_type = args[0] + # Check if there is a type in the following nodes that would be + # different from orig_type. + for redef_node, redef_type in args[1:]: + if redef_type == orig_type: + continue + # if a variable is defined to several types in an if node, + # this is not actually redefining. + orig_parent = orig_node.parent + redef_parent = redef_node.parent + if isinstance(orig_parent, astroid.If): + if orig_parent == redef_parent: + if ( + redef_node in orig_parent.orelse + and orig_node not in orig_parent.orelse + ): + orig_node, orig_type = redef_node, redef_type + continue + elif isinstance( + redef_parent, astroid.If + ) and redef_parent in orig_parent.nodes_of_class(astroid.If): + orig_node, orig_type = redef_node, redef_type + continue + orig_type = orig_type.replace(BUILTINS + ".", "") + redef_type = redef_type.replace(BUILTINS + ".", "") + self.add_message( + "redefined-variable-type", + node=redef_node, + args=(name, orig_type, redef_type), + ) + break + + def visit_assign(self, node): + # we don't handle multiple assignment nor slice assignment + target = node.targets[0] + if isinstance(target, (astroid.Tuple, astroid.Subscript)): + return + # ignore NoneType + if is_none(node): + return + _type = node_type(node.value) + if _type: + self._assigns[-1].setdefault(target.as_string(), []).append( + (node, _type.pytype()) + ) + + +def register(linter): + """Required method to auto register this checker. + + :param linter: Main interface object for Pylint plugins + :type linter: Pylint object + """ + linter.register_checker(MultipleTypesChecker(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/graph.py b/basic python programmes/venv/Lib/site-packages/pylint/graph.py new file mode 100644 index 0000000..f7790da --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/graph.py @@ -0,0 +1,198 @@ +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Graph manipulation utilities. + +(dot generation adapted from pypy/translator/tool/make_dot.py) +""" + +import os.path as osp +import os +import sys +import tempfile +import codecs + + +def target_info_from_filename(filename): + """Transforms /some/path/foo.png into ('/some/path', 'foo.png', 'png').""" + basename = osp.basename(filename) + storedir = osp.dirname(osp.abspath(filename)) + target = filename.split(".")[-1] + return storedir, basename, target + + +class DotBackend: + """Dot File backend.""" + + def __init__( + self, + graphname, + rankdir=None, + size=None, + ratio=None, + charset="utf-8", + renderer="dot", + additional_param=None, + ): + if additional_param is None: + additional_param = {} + self.graphname = graphname + self.renderer = renderer + self.lines = [] + self._source = None + self.emit("digraph %s {" % normalize_node_id(graphname)) + if rankdir: + self.emit("rankdir=%s" % rankdir) + if ratio: + self.emit("ratio=%s" % ratio) + if size: + self.emit('size="%s"' % size) + if charset: + assert charset.lower() in ("utf-8", "iso-8859-1", "latin1"), ( + "unsupported charset %s" % charset + ) + self.emit('charset="%s"' % charset) + for param in additional_param.items(): + self.emit("=".join(param)) + + def get_source(self): + """returns self._source""" + if self._source is None: + self.emit("}\n") + self._source = "\n".join(self.lines) + del self.lines + return self._source + + source = property(get_source) + + def generate(self, outputfile=None, dotfile=None, mapfile=None): + """Generates a graph file. + + :param str outputfile: filename and path [defaults to graphname.png] + :param str dotfile: filename and path [defaults to graphname.dot] + :param str mapfile: filename and path + + :rtype: str + :return: a path to the generated file + """ + import subprocess # introduced in py 2.4 + + name = self.graphname + if not dotfile: + # if 'outputfile' is a dot file use it as 'dotfile' + if outputfile and outputfile.endswith(".dot"): + dotfile = outputfile + else: + dotfile = "%s.dot" % name + if outputfile is not None: + storedir, _, target = target_info_from_filename(outputfile) + if target != "dot": + pdot, dot_sourcepath = tempfile.mkstemp(".dot", name) + os.close(pdot) + else: + dot_sourcepath = osp.join(storedir, dotfile) + else: + target = "png" + pdot, dot_sourcepath = tempfile.mkstemp(".dot", name) + ppng, outputfile = tempfile.mkstemp(".png", name) + os.close(pdot) + os.close(ppng) + pdot = codecs.open(dot_sourcepath, "w", encoding="utf8") + pdot.write(self.source) + pdot.close() + if target != "dot": + use_shell = sys.platform == "win32" + if mapfile: + subprocess.call( + [ + self.renderer, + "-Tcmapx", + "-o", + mapfile, + "-T", + target, + dot_sourcepath, + "-o", + outputfile, + ], + shell=use_shell, + ) + else: + subprocess.call( + [self.renderer, "-T", target, dot_sourcepath, "-o", outputfile], + shell=use_shell, + ) + os.unlink(dot_sourcepath) + return outputfile + + def emit(self, line): + """Adds <line> to final output.""" + self.lines.append(line) + + def emit_edge(self, name1, name2, **props): + """emit an edge from <name1> to <name2>. + edge properties: see http://www.graphviz.org/doc/info/attrs.html + """ + attrs = ['%s="%s"' % (prop, value) for prop, value in props.items()] + n_from, n_to = normalize_node_id(name1), normalize_node_id(name2) + self.emit("%s -> %s [%s];" % (n_from, n_to, ", ".join(sorted(attrs)))) + + def emit_node(self, name, **props): + """emit a node with given properties. + node properties: see http://www.graphviz.org/doc/info/attrs.html + """ + attrs = ['%s="%s"' % (prop, value) for prop, value in props.items()] + self.emit("%s [%s];" % (normalize_node_id(name), ", ".join(sorted(attrs)))) + + +def normalize_node_id(nid): + """Returns a suitable DOT node id for `nid`.""" + return '"%s"' % nid + + +def get_cycles(graph_dict, vertices=None): + """given a dictionary representing an ordered graph (i.e. key are vertices + and values is a list of destination vertices representing edges), return a + list of detected cycles + """ + if not graph_dict: + return () + result = [] + if vertices is None: + vertices = graph_dict.keys() + for vertice in vertices: + _get_cycles(graph_dict, [], set(), result, vertice) + return result + + +def _get_cycles(graph_dict, path, visited, result, vertice): + """recursive function doing the real work for get_cycles""" + if vertice in path: + cycle = [vertice] + for node in path[::-1]: + if node == vertice: + break + cycle.insert(0, node) + # make a canonical representation + start_from = min(cycle) + index = cycle.index(start_from) + cycle = cycle[index:] + cycle[0:index] + # append it to result if not already in + if cycle not in result: + result.append(cycle) + return + path.append(vertice) + try: + for node in graph_dict[vertice]: + # don't check already visited nodes again + if node not in visited: + _get_cycles(graph_dict, path, visited, result, node) + visited.add(node) + except KeyError: + pass + path.pop() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/interfaces.py b/basic python programmes/venv/Lib/site-packages/pylint/interfaces.py new file mode 100644 index 0000000..378585c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/interfaces.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2010, 2012-2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Interfaces for Pylint objects""" +from collections import namedtuple + +Confidence = namedtuple("Confidence", ["name", "description"]) +# Warning Certainties +HIGH = Confidence("HIGH", "No false positive possible.") +INFERENCE = Confidence("INFERENCE", "Warning based on inference result.") +INFERENCE_FAILURE = Confidence( + "INFERENCE_FAILURE", "Warning based on inference with failures." +) +UNDEFINED = Confidence("UNDEFINED", "Warning without any associated confidence level.") + +CONFIDENCE_LEVELS = [HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED] + + +class Interface: + """Base class for interfaces.""" + + @classmethod + def is_implemented_by(cls, instance): + return implements(instance, cls) + + +def implements(obj, interface): + """Return true if the give object (maybe an instance or class) implements + the interface. + """ + kimplements = getattr(obj, "__implements__", ()) + if not isinstance(kimplements, (list, tuple)): + kimplements = (kimplements,) + for implementedinterface in kimplements: + if issubclass(implementedinterface, interface): + return True + return False + + +class IChecker(Interface): + """This is a base interface, not designed to be used elsewhere than for + sub interfaces definition. + """ + + def open(self): + """called before visiting project (i.e set of modules)""" + + def close(self): + """called after visiting project (i.e set of modules)""" + + +class IRawChecker(IChecker): + """interface for checker which need to parse the raw file + """ + + def process_module(self, astroid): + """ process a module + + the module's content is accessible via astroid.stream + """ + + +class ITokenChecker(IChecker): + """Interface for checkers that need access to the token list.""" + + def process_tokens(self, tokens): + """Process a module. + + tokens is a list of all source code tokens in the file. + """ + + +class IAstroidChecker(IChecker): + """ interface for checker which prefers receive events according to + statement type + """ + + +class IReporter(Interface): + """ reporter collect messages and display results encapsulated in a layout + """ + + def handle_message(self, msg): + """Handle the given message object.""" + + def display_reports(self, layout): + """display results encapsulated in the layout tree + """ + + +__all__ = ("IRawChecker", "IAstroidChecker", "ITokenChecker", "IReporter") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/lint.py b/basic python programmes/venv/Lib/site-packages/pylint/lint.py new file mode 100644 index 0000000..6c11dfc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/lint.py @@ -0,0 +1,1681 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2008 Fabrice Douchant <Fabrice.Douchant@logilab.fr> +# Copyright (c) 2009 Vincent +# Copyright (c) 2009 Mads Kiilerich <mads@kiilerich.com> +# Copyright (c) 2011-2014 Google, Inc. +# Copyright (c) 2012 David Pursehouse <david.pursehouse@sonymobile.com> +# Copyright (c) 2012 Kevin Jing Qiu <kevin.jing.qiu@gmail.com> +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2012 JT Olds <jtolds@xnet5.com> +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014-2015 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Alexandru Coman <fcoman@bitdefender.com> +# Copyright (c) 2014 Daniel Harding <dharding@living180.net> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2014 Dan Goldsmith <djgoldsmith@googlemail.com> +# Copyright (c) 2015-2016 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Aru Sahni <arusahni@gmail.com> +# Copyright (c) 2015 Steven Myint <hg@stevenmyint.com> +# Copyright (c) 2015 Simu Toni <simutoni@gmail.com> +# Copyright (c) 2015 Mihai Balint <balint.mihai@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Alan Evangelista <alanoe@linux.vnet.ibm.com> +# Copyright (c) 2017-2018 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Daniel Miller <millerdev@gmail.com> +# Copyright (c) 2017 Roman Ivanov <me@roivanov.com> +# Copyright (c) 2017 Ned Batchelder <ned@nedbatchelder.com> +# Copyright (c) 2018 Randall Leeds <randall@bleeds.info> +# Copyright (c) 2018 Mike Frysinger <vapier@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Jason Owen <jason.a.owen@gmail.com> +# Copyright (c) 2018 Gary Tyler McLeod <mail@garytyler.com> +# Copyright (c) 2018 Yuval Langer <yuvallanger@mail.tau.ac.il> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> +# Copyright (c) 2018 kapsh <kapsh@kap.sh> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +# pylint: disable=broad-except + +""" %prog [options] modules_or_packages + + Check that module(s) satisfy a coding standard (and more !). + + %prog --help + + Display this help message and exit. + + %prog --help-msg <msg-id>[,<msg-id>] + + Display help messages about given message identifiers and exit. +""" +from __future__ import print_function + +import collections +import contextlib +import operator +import os + +try: + import multiprocessing +except ImportError: + multiprocessing = None # type: ignore +import sys +import tokenize +import warnings + +import astroid +from astroid.__pkginfo__ import version as astroid_version +from astroid import modutils +from pylint import checkers +from pylint import interfaces +from pylint import reporters +from pylint import exceptions +from pylint import utils +from pylint import config +from pylint.__pkginfo__ import version +from pylint.reporters.ureports import nodes as report_nodes + + +MANAGER = astroid.MANAGER + + +def _get_new_args(message): + location = ( + message.abspath, + message.path, + message.module, + message.obj, + message.line, + message.column, + ) + return (message.msg_id, message.symbol, location, message.msg, message.confidence) + + +def _get_python_path(filepath): + dirname = os.path.realpath(os.path.expanduser(filepath)) + if not os.path.isdir(dirname): + dirname = os.path.dirname(dirname) + while True: + if not os.path.exists(os.path.join(dirname, "__init__.py")): + return dirname + old_dirname = dirname + dirname = os.path.dirname(dirname) + if old_dirname == dirname: + return os.getcwd() + return None + + +def _merge_stats(stats): + merged = {} + by_msg = collections.Counter() + for stat in stats: + message_stats = stat.pop("by_msg", {}) + by_msg.update(message_stats) + + for key, item in stat.items(): + if key not in merged: + merged[key] = item + else: + if isinstance(item, dict): + merged[key].update(item) + else: + merged[key] = merged[key] + item + + merged["by_msg"] = by_msg + return merged + + +@contextlib.contextmanager +def _patch_sysmodules(): + # Context manager that permits running pylint, on Windows, with -m switch + # and with --jobs, as in 'python -2 -m pylint .. --jobs'. + # For more details why this is needed, + # see Python issue http://bugs.python.org/issue10845. + + mock_main = __name__ != "__main__" # -m switch + if mock_main: + sys.modules["__main__"] = sys.modules[__name__] + + try: + yield + finally: + if mock_main: + sys.modules.pop("__main__") + + +# Python Linter class ######################################################### + +MSGS = { + "F0001": ( + "%s", + "fatal", + "Used when an error occurred preventing the analysis of a \ + module (unable to find it for instance).", + ), + "F0002": ( + "%s: %s", + "astroid-error", + "Used when an unexpected error occurred while building the " + "Astroid representation. This is usually accompanied by a " + "traceback. Please report such errors !", + ), + "F0010": ( + "error while code parsing: %s", + "parse-error", + "Used when an exception occurred while building the Astroid " + "representation which could be handled by astroid.", + ), + "I0001": ( + "Unable to run raw checkers on built-in module %s", + "raw-checker-failed", + "Used to inform that a built-in module has not been checked " + "using the raw checkers.", + ), + "I0010": ( + "Unable to consider inline option %r", + "bad-inline-option", + "Used when an inline option is either badly formatted or can't " + "be used inside modules.", + ), + "I0011": ( + "Locally disabling %s (%s)", + "locally-disabled", + "Used when an inline option disables a message or a messages category.", + ), + "I0013": ( + "Ignoring entire file", + "file-ignored", + "Used to inform that the file will not be checked", + ), + "I0020": ( + "Suppressed %s (from line %d)", + "suppressed-message", + "A message was triggered on a line, but suppressed explicitly " + "by a disable= comment in the file. This message is not " + "generated for messages that are ignored due to configuration " + "settings.", + ), + "I0021": ( + "Useless suppression of %s", + "useless-suppression", + "Reported when a message is explicitly disabled for a line or " + "a block of code, but never triggered.", + ), + "I0022": ( + 'Pragma "%s" is deprecated, use "%s" instead', + "deprecated-pragma", + "Some inline pylint options have been renamed or reworked, " + "only the most recent form should be used. " + "NOTE:skip-all is only available with pylint >= 0.26", + {"old_names": [("I0014", "deprecated-disable-all")]}, + ), + "E0001": ("%s", "syntax-error", "Used when a syntax error is raised for a module."), + "E0011": ( + "Unrecognized file option %r", + "unrecognized-inline-option", + "Used when an unknown inline option is encountered.", + ), + "E0012": ( + "Bad option value %r", + "bad-option-value", + "Used when a bad value for an inline option is encountered.", + ), +} + + +def _cpu_count() -> int: + """Use sched_affinity if available for virtualized or containerized environments.""" + sched_getaffinity = getattr(os, "sched_getaffinity", None) + # pylint: disable=not-callable,using-constant-test + if sched_getaffinity: + return len(sched_getaffinity(0)) + if multiprocessing: + return multiprocessing.cpu_count() + return 1 + + +if multiprocessing is not None: + + class ChildLinter(multiprocessing.Process): + def run(self): + # pylint: disable=no-member, unbalanced-tuple-unpacking + tasks_queue, results_queue, self._config = self._args + + self._config["jobs"] = 1 # Child does not parallelize any further. + self._python3_porting_mode = self._config.pop("python3_porting_mode", None) + self._plugins = self._config.pop("plugins", None) + + # Run linter for received files/modules. + for file_or_module in iter(tasks_queue.get, "STOP"): + try: + result = self._run_linter(file_or_module[0]) + results_queue.put(result) + except Exception as ex: + print( + "internal error with sending report for module %s" + % file_or_module, + file=sys.stderr, + ) + print(ex, file=sys.stderr) + results_queue.put({}) + + def _run_linter(self, file_or_module): + linter = PyLinter() + + # Register standard checkers. + linter.load_default_plugins() + # Load command line plugins. + if self._plugins: + linter.load_plugin_modules(self._plugins) + + linter.load_configuration_from_config(self._config) + linter.set_reporter(reporters.CollectingReporter()) + + # Enable the Python 3 checker mode. This option is + # passed down from the parent linter up to here, since + # the Python 3 porting flag belongs to the Run class, + # instead of the Linter class. + if self._python3_porting_mode: + linter.python3_porting_mode() + + # Run the checks. + linter.check(file_or_module) + + msgs = [_get_new_args(m) for m in linter.reporter.messages] + return ( + file_or_module, + linter.file_state.base_name, + linter.current_name, + msgs, + linter.stats, + linter.msg_status, + ) + + +# pylint: disable=too-many-instance-attributes +class PyLinter( + config.OptionsManagerMixIn, + utils.MessagesHandlerMixIn, + utils.ReportsHandlerMixIn, + checkers.BaseTokenChecker, +): + """lint Python modules using external checkers. + + This is the main checker controlling the other ones and the reports + generation. It is itself both a raw checker and an astroid checker in order + to: + * handle message activation / deactivation at the module level + * handle some basic but necessary stats'data (number of classes, methods...) + + IDE plugin developers: you may have to call + `astroid.builder.MANAGER.astroid_cache.clear()` across runs if you want + to ensure the latest code version is actually checked. + """ + + __implements__ = (interfaces.ITokenChecker,) + + name = "master" + priority = 0 + level = 0 + msgs = MSGS + + @staticmethod + def make_options(): + return ( + ( + "ignore", + { + "type": "csv", + "metavar": "<file>[,<file>...]", + "dest": "black_list", + "default": ("CVS",), + "help": "Add files or directories to the blacklist. " + "They should be base names, not paths.", + }, + ), + ( + "ignore-patterns", + { + "type": "regexp_csv", + "metavar": "<pattern>[,<pattern>...]", + "dest": "black_list_re", + "default": (), + "help": "Add files or directories matching the regex patterns to the" + " blacklist. The regex matches against base names, not paths.", + }, + ), + ( + "persistent", + { + "default": True, + "type": "yn", + "metavar": "<y_or_n>", + "level": 1, + "help": "Pickle collected data for later comparisons.", + }, + ), + ( + "load-plugins", + { + "type": "csv", + "metavar": "<modules>", + "default": (), + "level": 1, + "help": "List of plugins (as comma separated values of " + "python modules names) to load, usually to register " + "additional checkers.", + }, + ), + ( + "output-format", + { + "default": "text", + "type": "string", + "metavar": "<format>", + "short": "f", + "group": "Reports", + "help": "Set the output format. Available formats are text," + " parseable, colorized, json and msvs (visual studio)." + " You can also give a reporter class, e.g. mypackage.mymodule." + "MyReporterClass.", + }, + ), + ( + "reports", + { + "default": False, + "type": "yn", + "metavar": "<y_or_n>", + "short": "r", + "group": "Reports", + "help": "Tells whether to display a full report or only the " + "messages.", + }, + ), + ( + "evaluation", + { + "type": "string", + "metavar": "<python_expression>", + "group": "Reports", + "level": 1, + "default": "10.0 - ((float(5 * error + warning + refactor + " + "convention) / statement) * 10)", + "help": "Python expression which should return a note less " + "than 10 (10 is the highest note). You have access " + "to the variables errors warning, statement which " + "respectively contain the number of errors / " + "warnings messages and the total number of " + "statements analyzed. This is used by the global " + "evaluation report (RP0004).", + }, + ), + ( + "score", + { + "default": True, + "type": "yn", + "metavar": "<y_or_n>", + "short": "s", + "group": "Reports", + "help": "Activate the evaluation score.", + }, + ), + ( + "confidence", + { + "type": "multiple_choice", + "metavar": "<levels>", + "default": "", + "choices": [c.name for c in interfaces.CONFIDENCE_LEVELS], + "group": "Messages control", + "help": "Only show warnings with the listed confidence levels." + " Leave empty to show all. Valid levels: %s." + % (", ".join(c.name for c in interfaces.CONFIDENCE_LEVELS),), + }, + ), + ( + "enable", + { + "type": "csv", + "metavar": "<msg ids>", + "short": "e", + "group": "Messages control", + "help": "Enable the message, report, category or checker with the " + "given id(s). You can either give multiple identifier " + "separated by comma (,) or put this option multiple time " + "(only on the command line, not in the configuration file " + "where it should appear only once). " + 'See also the "--disable" option for examples.', + }, + ), + ( + "disable", + { + "type": "csv", + "metavar": "<msg ids>", + "short": "d", + "group": "Messages control", + "help": "Disable the message, report, category or checker " + "with the given id(s). You can either give multiple identifiers " + "separated by comma (,) or put this option multiple times " + "(only on the command line, not in the configuration file " + "where it should appear only once). " + 'You can also use "--disable=all" to disable everything first ' + "and then reenable specific checks. For example, if you want " + "to run only the similarities checker, you can use " + '"--disable=all --enable=similarities". ' + "If you want to run only the classes checker, but have no " + "Warning level messages displayed, use " + '"--disable=all --enable=classes --disable=W".', + }, + ), + ( + "msg-template", + { + "type": "string", + "metavar": "<template>", + "group": "Reports", + "help": ( + "Template used to display messages. " + "This is a python new-style format string " + "used to format the message information. " + "See doc for all details." + ), + }, + ), + ( + "jobs", + { + "type": "int", + "metavar": "<n-processes>", + "short": "j", + "default": 1, + "help": "Use multiple processes to speed up Pylint. Specifying 0 will " + "auto-detect the number of processors available to use.", + }, + ), + ( + "unsafe-load-any-extension", + { + "type": "yn", + "metavar": "<yn>", + "default": False, + "hide": True, + "help": ( + "Allow loading of arbitrary C extensions. Extensions" + " are imported into the active Python interpreter and" + " may run arbitrary code." + ), + }, + ), + ( + "limit-inference-results", + { + "type": "int", + "metavar": "<number-of-results>", + "default": 100, + "help": ( + "Control the amount of potential inferred values when inferring " + "a single object. This can help the performance when dealing with " + "large functions or complex, nested conditions. " + ), + }, + ), + ( + "extension-pkg-whitelist", + { + "type": "csv", + "metavar": "<pkg[,pkg]>", + "default": [], + "help": ( + "A comma-separated list of package or module names" + " from where C extensions may be loaded. Extensions are" + " loading into the active Python interpreter and may run" + " arbitrary code." + ), + }, + ), + ( + "suggestion-mode", + { + "type": "yn", + "metavar": "<yn>", + "default": True, + "help": ( + "When enabled, pylint would attempt to guess common " + "misconfiguration and emit user-friendly hints instead " + "of false-positive error messages." + ), + }, + ), + ( + "exit-zero", + { + "action": "store_true", + "help": ( + "Always return a 0 (non-error) status code, even if " + "lint errors are found. This is primarily useful in " + "continuous integration scripts." + ), + }, + ), + ) + + option_groups = ( + ("Messages control", "Options controlling analysis messages"), + ("Reports", "Options related to output formatting and reporting"), + ) + + def __init__(self, options=(), reporter=None, option_groups=(), pylintrc=None): + # some stuff has to be done before ancestors initialization... + # + # messages store / checkers / reporter / astroid manager + self.msgs_store = utils.MessagesStore() + self.reporter = None + self._reporter_name = None + self._reporters = {} + self._checkers = collections.defaultdict(list) + self._pragma_lineno = {} + self._ignore_file = False + # visit variables + self.file_state = utils.FileState() + self.current_name = None + self.current_file = None + self.stats = None + # init options + self._external_opts = options + self.options = options + PyLinter.make_options() + self.option_groups = option_groups + PyLinter.option_groups + self._options_methods = {"enable": self.enable, "disable": self.disable} + self._bw_options_methods = { + "disable-msg": self.disable, + "enable-msg": self.enable, + } + full_version = "%%prog %s\nastroid %s\nPython %s" % ( + version, + astroid_version, + sys.version, + ) + utils.MessagesHandlerMixIn.__init__(self) + utils.ReportsHandlerMixIn.__init__(self) + super(PyLinter, self).__init__( + usage=__doc__, version=full_version, config_file=pylintrc or config.PYLINTRC + ) + checkers.BaseTokenChecker.__init__(self) + # provided reports + self.reports = ( + ("RP0001", "Messages by category", report_total_messages_stats), + ( + "RP0002", + "% errors / warnings by module", + report_messages_by_module_stats, + ), + ("RP0003", "Messages", report_messages_stats), + ) + self.register_checker(self) + self._dynamic_plugins = set() + self._python3_porting_mode = False + self._error_mode = False + self.load_provider_defaults() + if reporter: + self.set_reporter(reporter) + + def load_default_plugins(self): + checkers.initialize(self) + reporters.initialize(self) + # Make sure to load the default reporter, because + # the option has been set before the plugins had been loaded. + if not self.reporter: + self._load_reporter() + + def load_plugin_modules(self, modnames): + """take a list of module names which are pylint plugins and load + and register them + """ + for modname in modnames: + if modname in self._dynamic_plugins: + continue + self._dynamic_plugins.add(modname) + module = modutils.load_module_from_name(modname) + module.register(self) + + def _load_reporter(self): + name = self._reporter_name.lower() + if name in self._reporters: + self.set_reporter(self._reporters[name]()) + else: + try: + reporter_class = self._load_reporter_class() + except (ImportError, AttributeError): + raise exceptions.InvalidReporterError(name) + else: + self.set_reporter(reporter_class()) + + def _load_reporter_class(self): + qname = self._reporter_name + module = modutils.load_module_from_name(modutils.get_module_part(qname)) + class_name = qname.split(".")[-1] + reporter_class = getattr(module, class_name) + return reporter_class + + def set_reporter(self, reporter): + """set the reporter used to display messages and reports""" + self.reporter = reporter + reporter.linter = self + + def set_option(self, optname, value, action=None, optdict=None): + """overridden from config.OptionsProviderMixin to handle some + special options + """ + if optname in self._options_methods or optname in self._bw_options_methods: + if value: + try: + meth = self._options_methods[optname] + except KeyError: + meth = self._bw_options_methods[optname] + warnings.warn( + "%s is deprecated, replace it by %s" + % (optname, optname.split("-")[0]), + DeprecationWarning, + ) + value = utils._check_csv(value) + if isinstance(value, (list, tuple)): + for _id in value: + meth(_id, ignore_unknown=True) + else: + meth(value) + return # no need to call set_option, disable/enable methods do it + elif optname == "output-format": + self._reporter_name = value + # If the reporters are already available, load + # the reporter class. + if self._reporters: + self._load_reporter() + + try: + checkers.BaseTokenChecker.set_option(self, optname, value, action, optdict) + except config.UnsupportedAction: + print("option %s can't be read from config file" % optname, file=sys.stderr) + + def register_reporter(self, reporter_class): + self._reporters[reporter_class.name] = reporter_class + + def report_order(self): + reports = sorted(self._reports, key=lambda x: getattr(x, "name", "")) + try: + # Remove the current reporter and add it + # at the end of the list. + reports.pop(reports.index(self)) + except ValueError: + pass + else: + reports.append(self) + return reports + + # checkers manipulation methods ############################################ + + def register_checker(self, checker): + """register a new checker + + checker is an object implementing IRawChecker or / and IAstroidChecker + """ + assert checker.priority <= 0, "checker priority can't be >= 0" + self._checkers[checker.name].append(checker) + for r_id, r_title, r_cb in checker.reports: + self.register_report(r_id, r_title, r_cb, checker) + self.register_options_provider(checker) + if hasattr(checker, "msgs"): + self.msgs_store.register_messages(checker) + checker.load_defaults() + + # Register the checker, but disable all of its messages. + # TODO(cpopa): we should have a better API for this. + if not getattr(checker, "enabled", True): + self.disable(checker.name) + + def disable_noerror_messages(self): + for msgcat, msgids in self.msgs_store._msgs_by_category.items(): + # enable only messages with 'error' severity and above ('fatal') + if msgcat in ["E", "F"]: + for msgid in msgids: + self.enable(msgid) + else: + for msgid in msgids: + self.disable(msgid) + + def disable_reporters(self): + """disable all reporters""" + for _reporters in self._reports.values(): + for report_id, _, _ in _reporters: + self.disable_report(report_id) + + def error_mode(self): + """error mode: enable only errors; no reports, no persistent""" + self._error_mode = True + self.disable_noerror_messages() + self.disable("miscellaneous") + if self._python3_porting_mode: + self.disable("all") + for msg_id in self._checker_messages("python3"): + if msg_id.startswith("E"): + self.enable(msg_id) + config_parser = self.cfgfile_parser + if config_parser.has_option("MESSAGES CONTROL", "disable"): + value = config_parser.get("MESSAGES CONTROL", "disable") + self.global_set_option("disable", value) + else: + self.disable("python3") + self.set_option("reports", False) + self.set_option("persistent", False) + self.set_option("score", False) + + def python3_porting_mode(self): + """Disable all other checkers and enable Python 3 warnings.""" + self.disable("all") + self.enable("python3") + if self._error_mode: + # The error mode was activated, using the -E flag. + # So we'll need to enable only the errors from the + # Python 3 porting checker. + for msg_id in self._checker_messages("python3"): + if msg_id.startswith("E"): + self.enable(msg_id) + else: + self.disable(msg_id) + config_parser = self.cfgfile_parser + if config_parser.has_option("MESSAGES CONTROL", "disable"): + value = config_parser.get("MESSAGES CONTROL", "disable") + self.global_set_option("disable", value) + self._python3_porting_mode = True + + # block level option handling ############################################# + # + # see func_block_disable_msg.py test case for expected behaviour + + def process_tokens(self, tokens): + """process tokens from the current module to search for module/block + level options + """ + control_pragmas = {"disable", "enable"} + for (tok_type, content, start, _, _) in tokens: + if tok_type != tokenize.COMMENT: + continue + match = utils.OPTION_RGX.search(content) + if match is None: + continue + + first_group = match.group(1) + if ( + first_group.strip() == "disable-all" + or first_group.strip() == "skip-file" + ): + if first_group.strip() == "disable-all": + self.add_message( + "deprecated-pragma", + line=start[0], + args=("disable-all", "skip-file"), + ) + self.add_message("file-ignored", line=start[0]) + self._ignore_file = True + return + try: + opt, value = first_group.split("=", 1) + except ValueError: + self.add_message( + "bad-inline-option", args=first_group.strip(), line=start[0] + ) + continue + opt = opt.strip() + if opt in self._options_methods or opt in self._bw_options_methods: + try: + meth = self._options_methods[opt] + except KeyError: + meth = self._bw_options_methods[opt] + # found a "(dis|en)able-msg" pragma deprecated suppression + self.add_message( + "deprecated-pragma", + line=start[0], + args=(opt, opt.replace("-msg", "")), + ) + for msgid in utils._splitstrip(value): + # Add the line where a control pragma was encountered. + if opt in control_pragmas: + self._pragma_lineno[msgid] = start[0] + + try: + if (opt, msgid) == ("disable", "all"): + self.add_message( + "deprecated-pragma", + line=start[0], + args=("disable=all", "skip-file"), + ) + self.add_message("file-ignored", line=start[0]) + self._ignore_file = True + return + meth(msgid, "module", start[0]) + except exceptions.UnknownMessageError: + self.add_message("bad-option-value", args=msgid, line=start[0]) + else: + self.add_message("unrecognized-inline-option", args=opt, line=start[0]) + + # code checking methods ################################################### + + def get_checkers(self): + """return all available checkers as a list""" + return [self] + [ + c + for _checkers in self._checkers.values() + for c in _checkers + if c is not self + ] + + def prepare_checkers(self): + """return checkers needed for activated messages and reports""" + if not self.config.reports: + self.disable_reporters() + # get needed checkers + neededcheckers = [self] + for checker in self.get_checkers()[1:]: + messages = {msg for msg in checker.msgs if self.is_message_enabled(msg)} + if messages or any(self.report_is_enabled(r[0]) for r in checker.reports): + neededcheckers.append(checker) + # Sort checkers by priority + neededcheckers = sorted( + neededcheckers, key=operator.attrgetter("priority"), reverse=True + ) + return neededcheckers + + # pylint: disable=unused-argument + @staticmethod + def should_analyze_file(modname, path, is_argument=False): + """Returns whether or not a module should be checked. + + This implementation returns True for all python source file, indicating + that all files should be linted. + + Subclasses may override this method to indicate that modules satisfying + certain conditions should not be linted. + + :param str modname: The name of the module to be checked. + :param str path: The full path to the source code of the module. + :param bool is_argument: Whetter the file is an argument to pylint or not. + Files which respect this property are always + checked, since the user requested it explicitly. + :returns: True if the module should be checked. + :rtype: bool + """ + if is_argument: + return True + return path.endswith(".py") + + # pylint: enable=unused-argument + + def check(self, files_or_modules): + """main checking entry: check a list of files or modules from their + name. + """ + # initialize msgs_state now that all messages have been registered into + # the store + for msg in self.msgs_store.messages: + if not msg.may_be_emitted(): + self._msgs_state[msg.msgid] = False + + if not isinstance(files_or_modules, (list, tuple)): + files_or_modules = (files_or_modules,) + + if self.config.jobs == 1: + self._do_check(files_or_modules) + else: + with _patch_sysmodules(): + self._parallel_check(files_or_modules) + + def _get_jobs_config(self): + child_config = collections.OrderedDict() + filter_options = {"long-help"} + filter_options.update((opt_name for opt_name, _ in self._external_opts)) + for opt_providers in self._all_options.values(): + for optname, optdict, val in opt_providers.options_and_values(): + if optdict.get("deprecated"): + continue + + if optname not in filter_options: + child_config[optname] = utils._format_option_value(optdict, val) + child_config["python3_porting_mode"] = self._python3_porting_mode + child_config["plugins"] = self._dynamic_plugins + return child_config + + def _parallel_task(self, files_or_modules): + # Prepare configuration for child linters. + child_config = self._get_jobs_config() + + children = [] + manager = multiprocessing.Manager() + tasks_queue = manager.Queue() + results_queue = manager.Queue() + + # Send files to child linters. + expanded_files = [] + for descr in self.expand_files(files_or_modules): + modname, filepath, is_arg = descr["name"], descr["path"], descr["isarg"] + if self.should_analyze_file(modname, filepath, is_argument=is_arg): + expanded_files.append(descr) + + # do not start more jobs than needed + for _ in range(min(self.config.jobs, len(expanded_files))): + child_linter = ChildLinter(args=(tasks_queue, results_queue, child_config)) + child_linter.start() + children.append(child_linter) + + for files_or_module in expanded_files: + path = files_or_module["path"] + tasks_queue.put([path]) + + # collect results from child linters + failed = False + for _ in expanded_files: + try: + result = results_queue.get() + except Exception as ex: + print( + "internal error while receiving results from child linter", + file=sys.stderr, + ) + print(ex, file=sys.stderr) + failed = True + break + yield result + + # Stop child linters and wait for their completion. + for _ in range(self.config.jobs): + tasks_queue.put("STOP") + for child in children: + child.join() + + if failed: + print("Error occurred, stopping the linter.", file=sys.stderr) + sys.exit(32) + + def _parallel_check(self, files_or_modules): + # Reset stats. + self.open() + + all_stats = [] + module = None + for result in self._parallel_task(files_or_modules): + if not result: + continue + (_, self.file_state.base_name, module, messages, stats, msg_status) = result + + for msg in messages: + msg = utils.Message(*msg) + self.set_current_module(module) + self.reporter.handle_message(msg) + + all_stats.append(stats) + self.msg_status |= msg_status + + self.stats = _merge_stats(all_stats) + self.current_name = module + + # Insert stats data to local checkers. + for checker in self.get_checkers(): + if checker is not self: + checker.stats = self.stats + + def _do_check(self, files_or_modules): + walker = utils.PyLintASTWalker(self) + _checkers = self.prepare_checkers() + tokencheckers = [ + c + for c in _checkers + if interfaces.implements(c, interfaces.ITokenChecker) and c is not self + ] + rawcheckers = [ + c for c in _checkers if interfaces.implements(c, interfaces.IRawChecker) + ] + # notify global begin + for checker in _checkers: + checker.open() + if interfaces.implements(checker, interfaces.IAstroidChecker): + walker.add_checker(checker) + # build ast and check modules or packages + for descr in self.expand_files(files_or_modules): + modname, filepath, is_arg = descr["name"], descr["path"], descr["isarg"] + if not self.should_analyze_file(modname, filepath, is_argument=is_arg): + continue + + self.set_current_module(modname, filepath) + # get the module representation + ast_node = self.get_ast(filepath, modname) + if ast_node is None: + continue + # XXX to be correct we need to keep module_msgs_state for every + # analyzed module (the problem stands with localized messages which + # are only detected in the .close step) + self.file_state = utils.FileState(descr["basename"]) + self._ignore_file = False + # fix the current file (if the source file was not available or + # if it's actually a c extension) + self.current_file = ast_node.file # pylint: disable=maybe-no-member + self.check_astroid_module(ast_node, walker, rawcheckers, tokencheckers) + # warn about spurious inline messages handling + spurious_messages = self.file_state.iter_spurious_suppression_messages( + self.msgs_store + ) + for msgid, line, args in spurious_messages: + self.add_message(msgid, line, None, args) + # notify global end + self.stats["statement"] = walker.nbstatements + for checker in reversed(_checkers): + checker.close() + + def expand_files(self, modules): + """get modules and errors from a list of modules and handle errors + """ + result, errors = utils.expand_modules( + modules, self.config.black_list, self.config.black_list_re + ) + for error in errors: + message = modname = error["mod"] + key = error["key"] + self.set_current_module(modname) + if key == "fatal": + message = str(error["ex"]).replace(os.getcwd() + os.sep, "") + self.add_message(key, args=message) + return result + + def set_current_module(self, modname, filepath=None): + """set the name of the currently analyzed module and + init statistics for it + """ + if not modname and filepath is None: + return + self.reporter.on_set_current_module(modname, filepath) + self.current_name = modname + self.current_file = filepath or modname + self.stats["by_module"][modname] = {} + self.stats["by_module"][modname]["statement"] = 0 + for msg_cat in utils.MSG_TYPES.values(): + self.stats["by_module"][modname][msg_cat] = 0 + + def get_ast(self, filepath, modname): + """return an ast(roid) representation for a module""" + try: + return MANAGER.ast_from_file(filepath, modname, source=True) + except astroid.AstroidSyntaxError as ex: + # pylint: disable=no-member + self.add_message( + "syntax-error", line=getattr(ex.error, "lineno", 0), args=str(ex.error) + ) + except astroid.AstroidBuildingException as ex: + self.add_message("parse-error", args=ex) + except Exception as ex: + import traceback + + traceback.print_exc() + self.add_message("astroid-error", args=(ex.__class__, ex)) + + def check_astroid_module(self, ast_node, walker, rawcheckers, tokencheckers): + """Check a module from its astroid representation.""" + try: + tokens = utils.tokenize_module(ast_node) + except tokenize.TokenError as ex: + self.add_message("syntax-error", line=ex.args[1][0], args=ex.args[0]) + return None + + if not ast_node.pure_python: + self.add_message("raw-checker-failed", args=ast_node.name) + else: + # assert astroid.file.endswith('.py') + # invoke ITokenChecker interface on self to fetch module/block + # level options + self.process_tokens(tokens) + if self._ignore_file: + return False + # walk ast to collect line numbers + self.file_state.collect_block_lines(self.msgs_store, ast_node) + # run raw and tokens checkers + for checker in rawcheckers: + checker.process_module(ast_node) + for checker in tokencheckers: + checker.process_tokens(tokens) + # generate events to astroid checkers + walker.walk(ast_node) + return True + + # IAstroidChecker interface ################################################# + + def open(self): + """initialize counters""" + self.stats = {"by_module": {}, "by_msg": {}} + MANAGER.always_load_extensions = self.config.unsafe_load_any_extension + MANAGER.max_inferable_values = self.config.limit_inference_results + MANAGER.extension_package_whitelist.update(self.config.extension_pkg_whitelist) + for msg_cat in utils.MSG_TYPES.values(): + self.stats[msg_cat] = 0 + + def generate_reports(self): + """close the whole package /module, it's time to make reports ! + + if persistent run, pickle results for later comparison + """ + # Display whatever messages are left on the reporter. + self.reporter.display_messages(report_nodes.Section()) + + if self.file_state.base_name is not None: + # load previous results if any + previous_stats = config.load_results(self.file_state.base_name) + # XXX code below needs refactoring to be more reporter agnostic + self.reporter.on_close(self.stats, previous_stats) + if self.config.reports: + sect = self.make_reports(self.stats, previous_stats) + else: + sect = report_nodes.Section() + + if self.config.reports: + self.reporter.display_reports(sect) + self._report_evaluation() + # save results if persistent run + if self.config.persistent: + config.save_results(self.stats, self.file_state.base_name) + else: + self.reporter.on_close(self.stats, {}) + + def _report_evaluation(self): + """make the global evaluation report""" + # check with at least check 1 statements (usually 0 when there is a + # syntax error preventing pylint from further processing) + previous_stats = config.load_results(self.file_state.base_name) + if self.stats["statement"] == 0: + return + + # get a global note for the code + evaluation = self.config.evaluation + try: + note = eval(evaluation, {}, self.stats) # pylint: disable=eval-used + except Exception as ex: + msg = "An exception occurred while rating: %s" % ex + else: + self.stats["global_note"] = note + msg = "Your code has been rated at %.2f/10" % note + pnote = previous_stats.get("global_note") + if pnote is not None: + msg += " (previous run: %.2f/10, %+.2f)" % (pnote, note - pnote) + + if self.config.score: + sect = report_nodes.EvaluationSection(msg) + self.reporter.display_reports(sect) + + +# some reporting functions #################################################### + + +def report_total_messages_stats(sect, stats, previous_stats): + """make total errors / warnings report""" + lines = ["type", "number", "previous", "difference"] + lines += checkers.table_lines_from_stats( + stats, previous_stats, ("convention", "refactor", "warning", "error") + ) + sect.append(report_nodes.Table(children=lines, cols=4, rheaders=1)) + + +def report_messages_stats(sect, stats, _): + """make messages type report""" + if not stats["by_msg"]: + # don't print this report when we didn't detected any errors + raise exceptions.EmptyReportError() + in_order = sorted( + [ + (value, msg_id) + for msg_id, value in stats["by_msg"].items() + if not msg_id.startswith("I") + ] + ) + in_order.reverse() + lines = ("message id", "occurrences") + for value, msg_id in in_order: + lines += (msg_id, str(value)) + sect.append(report_nodes.Table(children=lines, cols=2, rheaders=1)) + + +def report_messages_by_module_stats(sect, stats, _): + """make errors / warnings by modules report""" + if len(stats["by_module"]) == 1: + # don't print this report when we are analysing a single module + raise exceptions.EmptyReportError() + by_mod = collections.defaultdict(dict) + for m_type in ("fatal", "error", "warning", "refactor", "convention"): + total = stats[m_type] + for module in stats["by_module"].keys(): + mod_total = stats["by_module"][module][m_type] + if total == 0: + percent = 0 + else: + percent = float((mod_total) * 100) / total + by_mod[module][m_type] = percent + sorted_result = [] + for module, mod_info in by_mod.items(): + sorted_result.append( + ( + mod_info["error"], + mod_info["warning"], + mod_info["refactor"], + mod_info["convention"], + module, + ) + ) + sorted_result.sort() + sorted_result.reverse() + lines = ["module", "error", "warning", "refactor", "convention"] + for line in sorted_result: + # Don't report clean modules. + if all(entry == 0 for entry in line[:-1]): + continue + lines.append(line[-1]) + for val in line[:-1]: + lines.append("%.2f" % val) + if len(lines) == 5: + raise exceptions.EmptyReportError() + sect.append(report_nodes.Table(children=lines, cols=5, rheaders=1)) + + +# utilities ################################################################### + + +class ArgumentPreprocessingError(Exception): + """Raised if an error occurs during argument preprocessing.""" + + +def preprocess_options(args, search_for): + """look for some options (keys of <search_for>) which have to be processed + before others + + values of <search_for> are callback functions to call when the option is + found + """ + i = 0 + while i < len(args): + arg = args[i] + if arg.startswith("--"): + try: + option, val = arg[2:].split("=", 1) + except ValueError: + option, val = arg[2:], None + try: + cb, takearg = search_for[option] + except KeyError: + i += 1 + else: + del args[i] + if takearg and val is None: + if i >= len(args) or args[i].startswith("-"): + msg = "Option %s expects a value" % option + raise ArgumentPreprocessingError(msg) + val = args[i] + del args[i] + elif not takearg and val is not None: + msg = "Option %s doesn't expects a value" % option + raise ArgumentPreprocessingError(msg) + cb(option, val) + else: + i += 1 + + +@contextlib.contextmanager +def fix_import_path(args): + """Prepare sys.path for running the linter checks. + + Within this context, each of the given arguments is importable. + Paths are added to sys.path in corresponding order to the arguments. + We avoid adding duplicate directories to sys.path. + `sys.path` is reset to its original value upon exiting this context. + """ + orig = list(sys.path) + changes = [] + for arg in args: + path = _get_python_path(arg) + if path in changes: + continue + else: + changes.append(path) + sys.path[:] = changes + ["."] + sys.path + try: + yield + finally: + sys.path[:] = orig + + +class Run: + """helper class to use as main for pylint : + + run(*sys.argv[1:]) + """ + + LinterClass = PyLinter + option_groups = ( + ( + "Commands", + "Options which are actually commands. Options in this \ +group are mutually exclusive.", + ), + ) + + def __init__(self, args, reporter=None, do_exit=True): + self._rcfile = None + self._plugins = [] + self.verbose = None + try: + preprocess_options( + args, + { + # option: (callback, takearg) + "init-hook": (cb_init_hook, True), + "rcfile": (self.cb_set_rcfile, True), + "load-plugins": (self.cb_add_plugins, True), + "verbose": (self.cb_verbose_mode, False), + }, + ) + except ArgumentPreprocessingError as ex: + print(ex, file=sys.stderr) + sys.exit(32) + + self.linter = linter = self.LinterClass( + ( + ( + "rcfile", + { + "action": "callback", + "callback": lambda *args: 1, + "type": "string", + "metavar": "<file>", + "help": "Specify a configuration file.", + }, + ), + ( + "init-hook", + { + "action": "callback", + "callback": lambda *args: 1, + "type": "string", + "metavar": "<code>", + "level": 1, + "help": "Python code to execute, usually for sys.path " + "manipulation such as pygtk.require().", + }, + ), + ( + "help-msg", + { + "action": "callback", + "type": "string", + "metavar": "<msg-id>", + "callback": self.cb_help_message, + "group": "Commands", + "help": "Display a help message for the given message id and " + "exit. The value may be a comma separated list of message ids.", + }, + ), + ( + "list-msgs", + { + "action": "callback", + "metavar": "<msg-id>", + "callback": self.cb_list_messages, + "group": "Commands", + "level": 1, + "help": "Generate pylint's messages.", + }, + ), + ( + "list-conf-levels", + { + "action": "callback", + "callback": cb_list_confidence_levels, + "group": "Commands", + "level": 1, + "help": "Generate pylint's confidence levels.", + }, + ), + ( + "full-documentation", + { + "action": "callback", + "metavar": "<msg-id>", + "callback": self.cb_full_documentation, + "group": "Commands", + "level": 1, + "help": "Generate pylint's full documentation.", + }, + ), + ( + "generate-rcfile", + { + "action": "callback", + "callback": self.cb_generate_config, + "group": "Commands", + "help": "Generate a sample configuration file according to " + "the current configuration. You can put other options " + "before this one to get them in the generated " + "configuration.", + }, + ), + ( + "generate-man", + { + "action": "callback", + "callback": self.cb_generate_manpage, + "group": "Commands", + "help": "Generate pylint's man page.", + "hide": True, + }, + ), + ( + "errors-only", + { + "action": "callback", + "callback": self.cb_error_mode, + "short": "E", + "help": "In error mode, checkers without error messages are " + "disabled and for others, only the ERROR messages are " + "displayed, and no reports are done by default.", + }, + ), + ( + "py3k", + { + "action": "callback", + "callback": self.cb_python3_porting_mode, + "help": "In Python 3 porting mode, all checkers will be " + "disabled and only messages emitted by the porting " + "checker will be displayed.", + }, + ), + ( + "verbose", + { + "action": "callback", + "callback": self.cb_verbose_mode, + "short": "v", + "help": "In verbose mode, extra non-checker-related info " + "will be displayed.", + }, + ), + ), + option_groups=self.option_groups, + pylintrc=self._rcfile, + ) + # register standard checkers + linter.load_default_plugins() + # load command line plugins + linter.load_plugin_modules(self._plugins) + # add some help section + linter.add_help_section("Environment variables", config.ENV_HELP, level=1) + # pylint: disable=bad-continuation + linter.add_help_section( + "Output", + "Using the default text output, the message format is : \n" + " \n" + " MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE \n" + " \n" + "There are 5 kind of message types : \n" + " * (C) convention, for programming standard violation \n" + " * (R) refactor, for bad code smell \n" + " * (W) warning, for python specific problems \n" + " * (E) error, for probable bugs in the code \n" + " * (F) fatal, if an error occurred which prevented pylint from doing further\n" + "processing.\n", + level=1, + ) + linter.add_help_section( + "Output status code", + "Pylint should leave with following status code: \n" + " * 0 if everything went fine \n" + " * 1 if a fatal message was issued \n" + " * 2 if an error message was issued \n" + " * 4 if a warning message was issued \n" + " * 8 if a refactor message was issued \n" + " * 16 if a convention message was issued \n" + " * 32 on usage error \n" + " \n" + "status 1 to 16 will be bit-ORed so you can know which different categories has\n" + "been issued by analysing pylint output status code\n", + level=1, + ) + # read configuration + linter.disable("I") + linter.enable("c-extension-no-member") + linter.read_config_file(verbose=self.verbose) + config_parser = linter.cfgfile_parser + # run init hook, if present, before loading plugins + if config_parser.has_option("MASTER", "init-hook"): + cb_init_hook( + "init-hook", utils._unquote(config_parser.get("MASTER", "init-hook")) + ) + # is there some additional plugins in the file configuration, in + if config_parser.has_option("MASTER", "load-plugins"): + plugins = utils._splitstrip(config_parser.get("MASTER", "load-plugins")) + linter.load_plugin_modules(plugins) + # now we can load file config and command line, plugins (which can + # provide options) have been registered + linter.load_config_file() + if reporter: + # if a custom reporter is provided as argument, it may be overridden + # by file parameters, so re-set it here, but before command line + # parsing so it's still overrideable by command line option + linter.set_reporter(reporter) + try: + args = linter.load_command_line_configuration(args) + except SystemExit as exc: + if exc.code == 2: # bad options + exc.code = 32 + raise + if not args: + print(linter.help()) + sys.exit(32) + + if linter.config.jobs < 0: + print( + "Jobs number (%d) should be greater than or equal to 0" + % linter.config.jobs, + file=sys.stderr, + ) + sys.exit(32) + if linter.config.jobs > 1 or linter.config.jobs == 0: + if multiprocessing is None: + print( + "Multiprocessing library is missing, " "fallback to single process", + file=sys.stderr, + ) + linter.set_option("jobs", 1) + else: + if linter.config.jobs == 0: + linter.config.jobs = _cpu_count() + + # insert current working directory to the python path to have a correct + # behaviour + with fix_import_path(args): + linter.check(args) + linter.generate_reports() + if do_exit: + if linter.config.exit_zero: + sys.exit(0) + else: + sys.exit(self.linter.msg_status) + + def cb_set_rcfile(self, name, value): + """callback for option preprocessing (i.e. before option parsing)""" + self._rcfile = value + + def cb_add_plugins(self, name, value): + """callback for option preprocessing (i.e. before option parsing)""" + self._plugins.extend(utils._splitstrip(value)) + + def cb_error_mode(self, *args, **kwargs): + """error mode: + * disable all but error messages + * disable the 'miscellaneous' checker which can be safely deactivated in + debug + * disable reports + * do not save execution information + """ + self.linter.error_mode() + + def cb_generate_config(self, *args, **kwargs): + """optik callback for sample config file generation""" + self.linter.generate_config(skipsections=("COMMANDS",)) + sys.exit(0) + + def cb_generate_manpage(self, *args, **kwargs): + """optik callback for sample config file generation""" + from pylint import __pkginfo__ + + self.linter.generate_manpage(__pkginfo__) + sys.exit(0) + + def cb_help_message(self, option, optname, value, parser): + """optik callback for printing some help about a particular message""" + self.linter.msgs_store.help_message(utils._splitstrip(value)) + sys.exit(0) + + def cb_full_documentation(self, option, optname, value, parser): + """optik callback for printing full documentation""" + self.linter.print_full_documentation() + sys.exit(0) + + def cb_list_messages(self, option, optname, value, parser): # FIXME + """optik callback for printing available messages""" + self.linter.msgs_store.list_messages() + sys.exit(0) + + def cb_python3_porting_mode(self, *args, **kwargs): + """Activate only the python3 porting checker.""" + self.linter.python3_porting_mode() + + def cb_verbose_mode(self, *args, **kwargs): + self.verbose = True + + +def cb_list_confidence_levels(option, optname, value, parser): + for level in interfaces.CONFIDENCE_LEVELS: + print("%-18s: %s" % level) + sys.exit(0) + + +def cb_init_hook(optname, value): + """exec arbitrary code to set sys.path for instance""" + exec(value) # pylint: disable=exec-used + + +if __name__ == "__main__": + Run(sys.argv[1:]) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__init__.py new file mode 100644 index 0000000..8a12c4f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__init__.py @@ -0,0 +1,9 @@ + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" +pyreverse.extensions +""" + +__revision__ = "$Id $" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..8a76697 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/diadefslib.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/diadefslib.cpython-37.pyc new file mode 100644 index 0000000..ee93ebe Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/diadefslib.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/diagrams.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/diagrams.cpython-37.pyc new file mode 100644 index 0000000..e06779d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/diagrams.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/inspector.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/inspector.cpython-37.pyc new file mode 100644 index 0000000..b4f0cca Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/inspector.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/main.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/main.cpython-37.pyc new file mode 100644 index 0000000..ed50664 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/main.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000..b94439b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/vcgutils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/vcgutils.cpython-37.pyc new file mode 100644 index 0000000..4ba3497 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/vcgutils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/writer.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/writer.cpython-37.pyc new file mode 100644 index 0000000..e52be35 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/__pycache__/writer.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/diadefslib.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/diadefslib.py new file mode 100644 index 0000000..e64614f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/diadefslib.py @@ -0,0 +1,238 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006, 2008-2010, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""handle diagram generation options for class diagram or default diagrams +""" + +import astroid + +from pylint.pyreverse.diagrams import PackageDiagram, ClassDiagram +from pylint.pyreverse.utils import LocalsVisitor + +BUILTINS_NAME = "builtins" + +# diagram generators ########################################################## + + +class DiaDefGenerator: + """handle diagram generation options""" + + def __init__(self, linker, handler): + """common Diagram Handler initialization""" + self.config = handler.config + self._set_default_options() + self.linker = linker + self.classdiagram = None # defined by subclasses + + def get_title(self, node): + """get title for objects""" + title = node.name + if self.module_names: + title = "%s.%s" % (node.root().name, title) + return title + + def _set_option(self, option): + """activate some options if not explicitly deactivated""" + # if we have a class diagram, we want more information by default; + # so if the option is None, we return True + if option is None: + return bool(self.config.classes) + return option + + def _set_default_options(self): + """set different default options with _default dictionary""" + self.module_names = self._set_option(self.config.module_names) + all_ancestors = self._set_option(self.config.all_ancestors) + all_associated = self._set_option(self.config.all_associated) + anc_level, association_level = (0, 0) + if all_ancestors: + anc_level = -1 + if all_associated: + association_level = -1 + if self.config.show_ancestors is not None: + anc_level = self.config.show_ancestors + if self.config.show_associated is not None: + association_level = self.config.show_associated + self.anc_level, self.association_level = anc_level, association_level + + def _get_levels(self): + """help function for search levels""" + return self.anc_level, self.association_level + + def show_node(self, node): + """true if builtins and not show_builtins""" + if self.config.show_builtin: + return True + return node.root().name != BUILTINS_NAME + + def add_class(self, node): + """visit one class and add it to diagram""" + self.linker.visit(node) + self.classdiagram.add_object(self.get_title(node), node) + + def get_ancestors(self, node, level): + """return ancestor nodes of a class node""" + if level == 0: + return + for ancestor in node.ancestors(recurs=False): + if not self.show_node(ancestor): + continue + yield ancestor + + def get_associated(self, klass_node, level): + """return associated nodes of a class node""" + if level == 0: + return + for association_nodes in list(klass_node.instance_attrs_type.values()) + list( + klass_node.locals_type.values() + ): + for node in association_nodes: + if isinstance(node, astroid.Instance): + node = node._proxied + if not (isinstance(node, astroid.ClassDef) and self.show_node(node)): + continue + yield node + + def extract_classes(self, klass_node, anc_level, association_level): + """extract recursively classes related to klass_node""" + if self.classdiagram.has_node(klass_node) or not self.show_node(klass_node): + return + self.add_class(klass_node) + + for ancestor in self.get_ancestors(klass_node, anc_level): + self.extract_classes(ancestor, anc_level - 1, association_level) + + for node in self.get_associated(klass_node, association_level): + self.extract_classes(node, anc_level, association_level - 1) + + +class DefaultDiadefGenerator(LocalsVisitor, DiaDefGenerator): + """generate minimum diagram definition for the project : + + * a package diagram including project's modules + * a class diagram including project's classes + """ + + def __init__(self, linker, handler): + DiaDefGenerator.__init__(self, linker, handler) + LocalsVisitor.__init__(self) + + def visit_project(self, node): + """visit a pyreverse.utils.Project node + + create a diagram definition for packages + """ + mode = self.config.mode + if len(node.modules) > 1: + self.pkgdiagram = PackageDiagram("packages %s" % node.name, mode) + else: + self.pkgdiagram = None + self.classdiagram = ClassDiagram("classes %s" % node.name, mode) + + def leave_project(self, node): # pylint: disable=unused-argument + """leave the pyreverse.utils.Project node + + return the generated diagram definition + """ + if self.pkgdiagram: + return self.pkgdiagram, self.classdiagram + return (self.classdiagram,) + + def visit_module(self, node): + """visit an astroid.Module node + + add this class to the package diagram definition + """ + if self.pkgdiagram: + self.linker.visit(node) + self.pkgdiagram.add_object(node.name, node) + + def visit_classdef(self, node): + """visit an astroid.Class node + + add this class to the class diagram definition + """ + anc_level, association_level = self._get_levels() + self.extract_classes(node, anc_level, association_level) + + def visit_importfrom(self, node): + """visit astroid.ImportFrom and catch modules for package diagram + """ + if self.pkgdiagram: + self.pkgdiagram.add_from_depend(node, node.modname) + + +class ClassDiadefGenerator(DiaDefGenerator): + """generate a class diagram definition including all classes related to a + given class + """ + + def __init__(self, linker, handler): + DiaDefGenerator.__init__(self, linker, handler) + + def class_diagram(self, project, klass): + """return a class diagram definition for the given klass and its + related klasses + """ + + self.classdiagram = ClassDiagram(klass, self.config.mode) + if len(project.modules) > 1: + module, klass = klass.rsplit(".", 1) + module = project.get_module(module) + else: + module = project.modules[0] + klass = klass.split(".")[-1] + klass = next(module.ilookup(klass)) + + anc_level, association_level = self._get_levels() + self.extract_classes(klass, anc_level, association_level) + return self.classdiagram + + +# diagram handler ############################################################# + + +class DiadefsHandler: + """handle diagram definitions : + + get it from user (i.e. xml files) or generate them + """ + + def __init__(self, config): + self.config = config + + def get_diadefs(self, project, linker): + """Get the diagrams configuration data + + :param project:The pyreverse project + :type project: pyreverse.utils.Project + :param linker: The linker + :type linker: pyreverse.inspector.Linker(IdGeneratorMixIn, LocalsVisitor) + + :returns: The list of diagram definitions + :rtype: list(:class:`pylint.pyreverse.diagrams.ClassDiagram`) + """ + + # read and interpret diagram definitions (Diadefs) + diagrams = [] + generator = ClassDiadefGenerator(linker, self) + for klass in self.config.classes: + diagrams.append(generator.class_diagram(project, klass)) + if not diagrams: + diagrams = DefaultDiadefGenerator(linker, self).visit(project) + for diagram in diagrams: + diagram.extract_relationships() + return diagrams diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/diagrams.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/diagrams.py new file mode 100644 index 0000000..afd7ffe --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/diagrams.py @@ -0,0 +1,267 @@ +# Copyright (c) 2006, 2008-2010, 2012-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""diagram objects +""" + +import astroid +from pylint.pyreverse.utils import is_interface, FilterMixIn +from pylint.checkers.utils import decorated_with_property + + +class Figure: + """base class for counter handling""" + + +class Relationship(Figure): + """a relation ship from an object in the diagram to another + """ + + def __init__(self, from_object, to_object, relation_type, name=None): + Figure.__init__(self) + self.from_object = from_object + self.to_object = to_object + self.type = relation_type + self.name = name + + +class DiagramEntity(Figure): + """a diagram object, i.e. a label associated to an astroid node + """ + + def __init__(self, title="No name", node=None): + Figure.__init__(self) + self.title = title + self.node = node + + +class ClassDiagram(Figure, FilterMixIn): + """main class diagram handling + """ + + TYPE = "class" + + def __init__(self, title, mode): + FilterMixIn.__init__(self, mode) + Figure.__init__(self) + self.title = title + self.objects = [] + self.relationships = {} + self._nodes = {} + self.depends = [] + + def get_relationships(self, role): + # sorted to get predictable (hence testable) results + return sorted( + self.relationships.get(role, ()), + key=lambda x: (x.from_object.fig_id, x.to_object.fig_id), + ) + + def add_relationship(self, from_object, to_object, relation_type, name=None): + """create a relation ship + """ + rel = Relationship(from_object, to_object, relation_type, name) + self.relationships.setdefault(relation_type, []).append(rel) + + def get_relationship(self, from_object, relation_type): + """return a relation ship or None + """ + for rel in self.relationships.get(relation_type, ()): + if rel.from_object is from_object: + return rel + raise KeyError(relation_type) + + def get_attrs(self, node): + """return visible attributes, possibly with class name""" + attrs = [] + properties = [ + (n, m) + for n, m in node.items() + if isinstance(m, astroid.FunctionDef) and decorated_with_property(m) + ] + for node_name, associated_nodes in ( + list(node.instance_attrs_type.items()) + + list(node.locals_type.items()) + + properties + ): + if not self.show_attr(node_name): + continue + names = self.class_names(associated_nodes) + if names: + node_name = "%s : %s" % (node_name, ", ".join(names)) + attrs.append(node_name) + return sorted(attrs) + + def get_methods(self, node): + """return visible methods""" + methods = [ + m + for m in node.values() + if isinstance(m, astroid.FunctionDef) + and not decorated_with_property(m) + and self.show_attr(m.name) + ] + return sorted(methods, key=lambda n: n.name) + + def add_object(self, title, node): + """create a diagram object + """ + assert node not in self._nodes + ent = DiagramEntity(title, node) + self._nodes[node] = ent + self.objects.append(ent) + + def class_names(self, nodes): + """return class names if needed in diagram""" + names = [] + for node in nodes: + if isinstance(node, astroid.Instance): + node = node._proxied + if ( + isinstance(node, astroid.ClassDef) + and hasattr(node, "name") + and not self.has_node(node) + ): + if node.name not in names: + node_name = node.name + names.append(node_name) + return names + + def nodes(self): + """return the list of underlying nodes + """ + return self._nodes.keys() + + def has_node(self, node): + """return true if the given node is included in the diagram + """ + return node in self._nodes + + def object_from_node(self, node): + """return the diagram object mapped to node + """ + return self._nodes[node] + + def classes(self): + """return all class nodes in the diagram""" + return [o for o in self.objects if isinstance(o.node, astroid.ClassDef)] + + def classe(self, name): + """return a class by its name, raise KeyError if not found + """ + for klass in self.classes(): + if klass.node.name == name: + return klass + raise KeyError(name) + + def extract_relationships(self): + """extract relation ships between nodes in the diagram + """ + for obj in self.classes(): + node = obj.node + obj.attrs = self.get_attrs(node) + obj.methods = self.get_methods(node) + # shape + if is_interface(node): + obj.shape = "interface" + else: + obj.shape = "class" + # inheritance link + for par_node in node.ancestors(recurs=False): + try: + par_obj = self.object_from_node(par_node) + self.add_relationship(obj, par_obj, "specialization") + except KeyError: + continue + # implements link + for impl_node in node.implements: + try: + impl_obj = self.object_from_node(impl_node) + self.add_relationship(obj, impl_obj, "implements") + except KeyError: + continue + # associations link + for name, values in list(node.instance_attrs_type.items()) + list( + node.locals_type.items() + ): + for value in values: + if value is astroid.Uninferable: + continue + if isinstance(value, astroid.Instance): + value = value._proxied + try: + associated_obj = self.object_from_node(value) + self.add_relationship(associated_obj, obj, "association", name) + except KeyError: + continue + + +class PackageDiagram(ClassDiagram): + """package diagram handling + """ + + TYPE = "package" + + def modules(self): + """return all module nodes in the diagram""" + return [o for o in self.objects if isinstance(o.node, astroid.Module)] + + def module(self, name): + """return a module by its name, raise KeyError if not found + """ + for mod in self.modules(): + if mod.node.name == name: + return mod + raise KeyError(name) + + def get_module(self, name, node): + """return a module by its name, looking also for relative imports; + raise KeyError if not found + """ + for mod in self.modules(): + mod_name = mod.node.name + if mod_name == name: + return mod + # search for fullname of relative import modules + package = node.root().name + if mod_name == "%s.%s" % (package, name): + return mod + if mod_name == "%s.%s" % (package.rsplit(".", 1)[0], name): + return mod + raise KeyError(name) + + def add_from_depend(self, node, from_module): + """add dependencies created by from-imports + """ + mod_name = node.root().name + obj = self.module(mod_name) + if from_module not in obj.node.depends: + obj.node.depends.append(from_module) + + def extract_relationships(self): + """extract relation ships between nodes in the diagram + """ + ClassDiagram.extract_relationships(self) + for obj in self.classes(): + # ownership + try: + mod = self.object_from_node(obj.node.root()) + self.add_relationship(obj, mod, "ownership") + except KeyError: + continue + for obj in self.modules(): + obj.shape = "package" + # dependencies + for dep_name in obj.node.depends: + try: + dep = self.get_module(dep_name, obj.node) + except KeyError: + continue + self.add_relationship(obj, dep, "depends") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/inspector.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/inspector.py new file mode 100644 index 0000000..eca4b67 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/inspector.py @@ -0,0 +1,368 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" +Visitor doing some postprocessing on the astroid tree. +Try to resolve definitions (namespace) dictionary, relationship... +""" +from __future__ import print_function + +import collections +import os +import traceback + +import astroid +from astroid import bases +from astroid import exceptions +from astroid import manager +from astroid import modutils +from astroid import node_classes + + +from pylint.pyreverse import utils + + +def _iface_hdlr(_): + """Handler used by interfaces to handle suspicious interface nodes.""" + return True + + +def _astroid_wrapper(func, modname): + print("parsing %s..." % modname) + try: + return func(modname) + except exceptions.AstroidBuildingException as exc: + print(exc) + except Exception as exc: # pylint: disable=broad-except + traceback.print_exc() + + +def interfaces(node, herited=True, handler_func=_iface_hdlr): + """Return an iterator on interfaces implemented by the given class node.""" + # FIXME: what if __implements__ = (MyIFace, MyParent.__implements__)... + try: + implements = bases.Instance(node).getattr("__implements__")[0] + except exceptions.NotFoundError: + return + if not herited and implements.frame() is not node: + return + found = set() + missing = False + for iface in node_classes.unpack_infer(implements): + if iface is astroid.Uninferable: + missing = True + continue + if iface not in found and handler_func(iface): + found.add(iface) + yield iface + if missing: + raise exceptions.InferenceError() + + +class IdGeneratorMixIn: + """Mixin adding the ability to generate integer uid.""" + + def __init__(self, start_value=0): + self.id_count = start_value + + def init_counter(self, start_value=0): + """init the id counter + """ + self.id_count = start_value + + def generate_id(self): + """generate a new identifier + """ + self.id_count += 1 + return self.id_count + + +class Linker(IdGeneratorMixIn, utils.LocalsVisitor): + """Walk on the project tree and resolve relationships. + + According to options the following attributes may be + added to visited nodes: + + * uid, + a unique identifier for the node (on astroid.Project, astroid.Module, + astroid.Class and astroid.locals_type). Only if the linker + has been instantiated with tag=True parameter (False by default). + + * Function + a mapping from locals names to their bounded value, which may be a + constant like a string or an integer, or an astroid node + (on astroid.Module, astroid.Class and astroid.Function). + + * instance_attrs_type + as locals_type but for klass member attributes (only on astroid.Class) + + * implements, + list of implemented interface _objects_ (only on astroid.Class nodes) + """ + + def __init__(self, project, inherited_interfaces=0, tag=False): + IdGeneratorMixIn.__init__(self) + utils.LocalsVisitor.__init__(self) + # take inherited interface in consideration or not + self.inherited_interfaces = inherited_interfaces + # tag nodes or not + self.tag = tag + # visited project + self.project = project + + def visit_project(self, node): + """visit a pyreverse.utils.Project node + + * optionally tag the node with a unique id + """ + if self.tag: + node.uid = self.generate_id() + for module in node.modules: + self.visit(module) + + def visit_package(self, node): + """visit an astroid.Package node + + * optionally tag the node with a unique id + """ + if self.tag: + node.uid = self.generate_id() + for subelmt in node.values(): + self.visit(subelmt) + + def visit_module(self, node): + """visit an astroid.Module node + + * set the locals_type mapping + * set the depends mapping + * optionally tag the node with a unique id + """ + if hasattr(node, "locals_type"): + return + node.locals_type = collections.defaultdict(list) + node.depends = [] + if self.tag: + node.uid = self.generate_id() + + def visit_classdef(self, node): + """visit an astroid.Class node + + * set the locals_type and instance_attrs_type mappings + * set the implements list and build it + * optionally tag the node with a unique id + """ + if hasattr(node, "locals_type"): + return + node.locals_type = collections.defaultdict(list) + if self.tag: + node.uid = self.generate_id() + # resolve ancestors + for baseobj in node.ancestors(recurs=False): + specializations = getattr(baseobj, "specializations", []) + specializations.append(node) + baseobj.specializations = specializations + # resolve instance attributes + node.instance_attrs_type = collections.defaultdict(list) + for assignattrs in node.instance_attrs.values(): + for assignattr in assignattrs: + self.handle_assignattr_type(assignattr, node) + # resolve implemented interface + try: + node.implements = list(interfaces(node, self.inherited_interfaces)) + except astroid.InferenceError: + node.implements = () + + def visit_functiondef(self, node): + """visit an astroid.Function node + + * set the locals_type mapping + * optionally tag the node with a unique id + """ + if hasattr(node, "locals_type"): + return + node.locals_type = collections.defaultdict(list) + if self.tag: + node.uid = self.generate_id() + + link_project = visit_project + link_module = visit_module + link_class = visit_classdef + link_function = visit_functiondef + + def visit_assignname(self, node): + """visit an astroid.AssignName node + + handle locals_type + """ + # avoid double parsing done by different Linkers.visit + # running over the same project: + if hasattr(node, "_handled"): + return + node._handled = True + if node.name in node.frame(): + frame = node.frame() + else: + # the name has been defined as 'global' in the frame and belongs + # there. + frame = node.root() + try: + if not hasattr(frame, "locals_type"): + # If the frame doesn't have a locals_type yet, + # it means it wasn't yet visited. Visit it now + # to add what's missing from it. + if isinstance(frame, astroid.ClassDef): + self.visit_classdef(frame) + elif isinstance(frame, astroid.FunctionDef): + self.visit_functiondef(frame) + else: + self.visit_module(frame) + + current = frame.locals_type[node.name] + values = set(node.infer()) + frame.locals_type[node.name] = list(set(current) | values) + except astroid.InferenceError: + pass + + @staticmethod + def handle_assignattr_type(node, parent): + """handle an astroid.assignattr node + + handle instance_attrs_type + """ + try: + values = set(node.infer()) + current = set(parent.instance_attrs_type[node.attrname]) + parent.instance_attrs_type[node.attrname] = list(current | values) + except astroid.InferenceError: + pass + + def visit_import(self, node): + """visit an astroid.Import node + + resolve module dependencies + """ + context_file = node.root().file + for name in node.names: + relative = modutils.is_relative(name[0], context_file) + self._imported_module(node, name[0], relative) + + def visit_importfrom(self, node): + """visit an astroid.ImportFrom node + + resolve module dependencies + """ + basename = node.modname + context_file = node.root().file + if context_file is not None: + relative = modutils.is_relative(basename, context_file) + else: + relative = False + for name in node.names: + if name[0] == "*": + continue + # analyze dependencies + fullname = "%s.%s" % (basename, name[0]) + if fullname.find(".") > -1: + try: + # TODO: don't use get_module_part, + # missing package precedence + fullname = modutils.get_module_part(fullname, context_file) + except ImportError: + continue + if fullname != basename: + self._imported_module(node, fullname, relative) + + def compute_module(self, context_name, mod_path): + """return true if the module should be added to dependencies""" + package_dir = os.path.dirname(self.project.path) + if context_name == mod_path: + return 0 + if modutils.is_standard_module(mod_path, (package_dir,)): + return 1 + return 0 + + def _imported_module(self, node, mod_path, relative): + """Notify an imported module, used to analyze dependencies""" + module = node.root() + context_name = module.name + if relative: + mod_path = "%s.%s" % (".".join(context_name.split(".")[:-1]), mod_path) + if self.compute_module(context_name, mod_path): + # handle dependencies + if not hasattr(module, "depends"): + module.depends = [] + mod_paths = module.depends + if mod_path not in mod_paths: + mod_paths.append(mod_path) + + +class Project: + """a project handle a set of modules / packages""" + + def __init__(self, name=""): + self.name = name + self.path = None + self.modules = [] + self.locals = {} + self.__getitem__ = self.locals.__getitem__ + self.__iter__ = self.locals.__iter__ + self.values = self.locals.values + self.keys = self.locals.keys + self.items = self.locals.items + + def add_module(self, node): + self.locals[node.name] = node + self.modules.append(node) + + def get_module(self, name): + return self.locals[name] + + def get_children(self): + return self.modules + + def __repr__(self): + return "<Project %r at %s (%s modules)>" % ( + self.name, + id(self), + len(self.modules), + ) + + +def project_from_files( + files, func_wrapper=_astroid_wrapper, project_name="no name", black_list=("CVS",) +): + """return a Project from a list of files or modules""" + # build the project representation + astroid_manager = manager.AstroidManager() + project = Project(project_name) + for something in files: + if not os.path.exists(something): + fpath = modutils.file_from_modpath(something.split(".")) + elif os.path.isdir(something): + fpath = os.path.join(something, "__init__.py") + else: + fpath = something + ast = func_wrapper(astroid_manager.ast_from_file, fpath) + if ast is None: + continue + # XXX why is first file defining the project.path ? + project.path = project.path or ast.file + project.add_module(ast) + base_name = ast.name + # recurse in package except if __init__ was explicitly given + if ast.package and something.find("__init__") == -1: + # recurse on others packages / modules if this is a package + for fpath in modutils.get_module_files( + os.path.dirname(ast.file), black_list + ): + ast = func_wrapper(astroid_manager.ast_from_file, fpath) + if ast is None or ast.name == base_name: + continue + project.add_module(ast) + return project diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/main.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/main.py new file mode 100644 index 0000000..2be7c48 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/main.py @@ -0,0 +1,221 @@ +# Copyright (c) 2008-2010, 2012-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Alexander Pervakov <frost.nzcr4@jagmort.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" + %prog [options] <packages> + + create UML diagrams for classes and modules in <packages> +""" +from __future__ import print_function + +import os +import subprocess +import sys + +from pylint.config import ConfigurationMixIn +from pylint.pyreverse.inspector import Linker, project_from_files +from pylint.pyreverse.diadefslib import DiadefsHandler +from pylint.pyreverse import writer +from pylint.pyreverse.utils import insert_default_options + +OPTIONS = ( + ( + "filter-mode", + dict( + short="f", + default="PUB_ONLY", + dest="mode", + type="string", + action="store", + metavar="<mode>", + help="""filter attributes and functions according to + <mode>. Correct modes are : + 'PUB_ONLY' filter all non public attributes + [DEFAULT], equivalent to PRIVATE+SPECIAL_A + 'ALL' no filter + 'SPECIAL' filter Python special functions + except constructor + 'OTHER' filter protected and private + attributes""", + ), + ), + ( + "class", + dict( + short="c", + action="append", + metavar="<class>", + dest="classes", + default=[], + help="create a class diagram with all classes related to <class>;\ + this uses by default the options -ASmy", + ), + ), + ( + "show-ancestors", + dict( + short="a", + action="store", + metavar="<ancestor>", + type="int", + help="show <ancestor> generations of ancestor classes not in <projects>", + ), + ), + ( + "all-ancestors", + dict( + short="A", + default=None, + help="show all ancestors off all classes in <projects>", + ), + ), + ( + "show-associated", + dict( + short="s", + action="store", + metavar="<association_level>", + type="int", + help="show <association_level> levels of associated classes not in <projects>", + ), + ), + ( + "all-associated", + dict( + short="S", + default=None, + help="show recursively all associated off all associated classes", + ), + ), + ( + "show-builtin", + dict( + short="b", + action="store_true", + default=False, + help="include builtin objects in representation of classes", + ), + ), + ( + "module-names", + dict( + short="m", + default=None, + type="yn", + metavar="[yn]", + help="include module name in representation of classes", + ), + ), + # TODO : generate dependencies like in pylint + # ("package-dependencies", + # dict(short="M", action="store", metavar='<package_depth>', type='int', + # help='show <package_depth> module dependencies beyond modules in \ + # <projects> (for the package diagram)')), + ( + "only-classnames", + dict( + short="k", + action="store_true", + default=False, + help="don't show attributes and methods in the class boxes; \ +this disables -f values", + ), + ), + ( + "output", + dict( + short="o", + dest="output_format", + action="store", + default="dot", + metavar="<format>", + help="create a *.<format> output file if format available.", + ), + ), + ( + "ignore", + { + "type": "csv", + "metavar": "<file[,file...]>", + "dest": "black_list", + "default": ("CVS",), + "help": "Add files or directories to the blacklist. They " + "should be base names, not paths.", + }, + ), + ( + "project", + { + "default": "", + "type": "string", + "short": "p", + "metavar": "<project name>", + "help": "set the project name.", + }, + ), +) + + +def _check_graphviz_available(output_format): + """check if we need graphviz for different output format""" + try: + subprocess.call(["dot", "-V"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except OSError: + print( + "The output format '%s' is currently not available.\n" + "Please install 'Graphviz' to have other output formats " + "than 'dot' or 'vcg'." % output_format + ) + sys.exit(32) + + +class Run(ConfigurationMixIn): + """base class providing common behaviour for pyreverse commands""" + + options = OPTIONS # type: ignore + + def __init__(self, args): + ConfigurationMixIn.__init__(self, usage=__doc__) + insert_default_options() + args = self.load_command_line_configuration() + if self.config.output_format not in ("dot", "vcg"): + _check_graphviz_available(self.config.output_format) + + sys.exit(self.run(args)) + + def run(self, args): + """checking arguments and run project""" + if not args: + print(self.help()) + return 1 + # insert current working directory to the python path to recognize + # dependencies to local modules even if cwd is not in the PYTHONPATH + sys.path.insert(0, os.getcwd()) + try: + project = project_from_files( + args, + project_name=self.config.project, + black_list=self.config.black_list, + ) + linker = Linker(project, tag=True) + handler = DiadefsHandler(self.config) + diadefs = handler.get_diadefs(project, linker) + finally: + sys.path.pop(0) + + if self.config.output_format == "vcg": + writer.VCGWriter(self.config).write(diadefs) + else: + writer.DotWriter(self.config).write(diadefs) + return 0 + + +if __name__ == "__main__": + Run(sys.argv[1:]) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/utils.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/utils.py new file mode 100644 index 0000000..b60f336 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/utils.py @@ -0,0 +1,221 @@ +# Copyright (c) 2006, 2008, 2010, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" +generic classes/functions for pyreverse core/extensions +""" +from __future__ import print_function + +import os +import re +import sys + +########### pyreverse option utils ############################## + + +RCFILE = ".pyreverserc" + + +def get_default_options(): + """ + Read config file and return list of options + """ + options = [] + home = os.environ.get("HOME", "") + if home: + rcfile = os.path.join(home, RCFILE) + try: + options = open(rcfile).read().split() + except IOError: + pass # ignore if no config file found + return options + + +def insert_default_options(): + """insert default options to sys.argv + """ + options = get_default_options() + options.reverse() + for arg in options: + sys.argv.insert(1, arg) + + +# astroid utilities ########################################################### + +SPECIAL = re.compile("^__[A-Za-z0-9]+[A-Za-z0-9_]*__$") +PRIVATE = re.compile("^__[_A-Za-z0-9]*[A-Za-z0-9]+_?$") +PROTECTED = re.compile("^_[_A-Za-z0-9]*$") + + +def get_visibility(name): + """return the visibility from a name: public, protected, private or special + """ + if SPECIAL.match(name): + visibility = "special" + elif PRIVATE.match(name): + visibility = "private" + elif PROTECTED.match(name): + visibility = "protected" + + else: + visibility = "public" + return visibility + + +ABSTRACT = re.compile("^.*Abstract.*") +FINAL = re.compile("^[A-Z_]*$") + + +def is_abstract(node): + """return true if the given class node correspond to an abstract class + definition + """ + return ABSTRACT.match(node.name) + + +def is_final(node): + """return true if the given class/function node correspond to final + definition + """ + return FINAL.match(node.name) + + +def is_interface(node): + # bw compat + return node.type == "interface" + + +def is_exception(node): + # bw compat + return node.type == "exception" + + +# Helpers ##################################################################### + +_CONSTRUCTOR = 1 +_SPECIAL = 2 +_PROTECTED = 4 +_PRIVATE = 8 +MODES = { + "ALL": 0, + "PUB_ONLY": _SPECIAL + _PROTECTED + _PRIVATE, + "SPECIAL": _SPECIAL, + "OTHER": _PROTECTED + _PRIVATE, +} +VIS_MOD = { + "special": _SPECIAL, + "protected": _PROTECTED, + "private": _PRIVATE, + "public": 0, +} + + +class FilterMixIn: + """filter nodes according to a mode and nodes' visibility + """ + + def __init__(self, mode): + "init filter modes" + __mode = 0 + for nummod in mode.split("+"): + try: + __mode += MODES[nummod] + except KeyError as ex: + print("Unknown filter mode %s" % ex, file=sys.stderr) + self.__mode = __mode + + def show_attr(self, node): + """return true if the node should be treated + """ + visibility = get_visibility(getattr(node, "name", node)) + return not self.__mode & VIS_MOD[visibility] + + +class ASTWalker: + """a walker visiting a tree in preorder, calling on the handler: + + * visit_<class name> on entering a node, where class name is the class of + the node in lower case + + * leave_<class name> on leaving a node, where class name is the class of + the node in lower case + """ + + def __init__(self, handler): + self.handler = handler + self._cache = {} + + def walk(self, node, _done=None): + """walk on the tree from <node>, getting callbacks from handler""" + if _done is None: + _done = set() + if node in _done: + raise AssertionError((id(node), node, node.parent)) + _done.add(node) + self.visit(node) + for child_node in node.get_children(): + assert child_node is not node + self.walk(child_node, _done) + self.leave(node) + assert node.parent is not node + + def get_callbacks(self, node): + """get callbacks from handler for the visited node""" + klass = node.__class__ + methods = self._cache.get(klass) + if methods is None: + handler = self.handler + kid = klass.__name__.lower() + e_method = getattr( + handler, "visit_%s" % kid, getattr(handler, "visit_default", None) + ) + l_method = getattr( + handler, "leave_%s" % kid, getattr(handler, "leave_default", None) + ) + self._cache[klass] = (e_method, l_method) + else: + e_method, l_method = methods + return e_method, l_method + + def visit(self, node): + """walk on the tree from <node>, getting callbacks from handler""" + method = self.get_callbacks(node)[0] + if method is not None: + method(node) + + def leave(self, node): + """walk on the tree from <node>, getting callbacks from handler""" + method = self.get_callbacks(node)[1] + if method is not None: + method(node) + + +class LocalsVisitor(ASTWalker): + """visit a project by traversing the locals dictionary""" + + def __init__(self): + ASTWalker.__init__(self, self) + self._visited = {} + + def visit(self, node): + """launch the visit starting from the given node""" + if node in self._visited: + return None + self._visited[node] = 1 # FIXME: use set ? + methods = self.get_callbacks(node) + if methods[0] is not None: + methods[0](node) + if hasattr(node, "locals"): # skip Instance and other proxy + for local_node in node.values(): + self.visit(local_node) + if methods[1] is not None: + return methods[1](node) + return None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/vcgutils.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/vcgutils.py new file mode 100644 index 0000000..89c6911 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/vcgutils.py @@ -0,0 +1,229 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Functions to generate files readable with Georg Sander's vcg +(Visualization of Compiler Graphs). + +You can download vcg at http://rw4.cs.uni-sb.de/~sander/html/gshome.html +Note that vcg exists as a debian package. + +See vcg's documentation for explanation about the different values that +maybe used for the functions parameters. +""" + +ATTRS_VAL = { + "algos": ( + "dfs", + "tree", + "minbackward", + "left_to_right", + "right_to_left", + "top_to_bottom", + "bottom_to_top", + "maxdepth", + "maxdepthslow", + "mindepth", + "mindepthslow", + "mindegree", + "minindegree", + "minoutdegree", + "maxdegree", + "maxindegree", + "maxoutdegree", + ), + "booleans": ("yes", "no"), + "colors": ( + "black", + "white", + "blue", + "red", + "green", + "yellow", + "magenta", + "lightgrey", + "cyan", + "darkgrey", + "darkblue", + "darkred", + "darkgreen", + "darkyellow", + "darkmagenta", + "darkcyan", + "gold", + "lightblue", + "lightred", + "lightgreen", + "lightyellow", + "lightmagenta", + "lightcyan", + "lilac", + "turquoise", + "aquamarine", + "khaki", + "purple", + "yellowgreen", + "pink", + "orange", + "orchid", + ), + "shapes": ("box", "ellipse", "rhomb", "triangle"), + "textmodes": ("center", "left_justify", "right_justify"), + "arrowstyles": ("solid", "line", "none"), + "linestyles": ("continuous", "dashed", "dotted", "invisible"), +} + +# meaning of possible values: +# O -> string +# 1 -> int +# list -> value in list +GRAPH_ATTRS = { + "title": 0, + "label": 0, + "color": ATTRS_VAL["colors"], + "textcolor": ATTRS_VAL["colors"], + "bordercolor": ATTRS_VAL["colors"], + "width": 1, + "height": 1, + "borderwidth": 1, + "textmode": ATTRS_VAL["textmodes"], + "shape": ATTRS_VAL["shapes"], + "shrink": 1, + "stretch": 1, + "orientation": ATTRS_VAL["algos"], + "vertical_order": 1, + "horizontal_order": 1, + "xspace": 1, + "yspace": 1, + "layoutalgorithm": ATTRS_VAL["algos"], + "late_edge_labels": ATTRS_VAL["booleans"], + "display_edge_labels": ATTRS_VAL["booleans"], + "dirty_edge_labels": ATTRS_VAL["booleans"], + "finetuning": ATTRS_VAL["booleans"], + "manhattan_edges": ATTRS_VAL["booleans"], + "smanhattan_edges": ATTRS_VAL["booleans"], + "port_sharing": ATTRS_VAL["booleans"], + "edges": ATTRS_VAL["booleans"], + "nodes": ATTRS_VAL["booleans"], + "splines": ATTRS_VAL["booleans"], +} +NODE_ATTRS = { + "title": 0, + "label": 0, + "color": ATTRS_VAL["colors"], + "textcolor": ATTRS_VAL["colors"], + "bordercolor": ATTRS_VAL["colors"], + "width": 1, + "height": 1, + "borderwidth": 1, + "textmode": ATTRS_VAL["textmodes"], + "shape": ATTRS_VAL["shapes"], + "shrink": 1, + "stretch": 1, + "vertical_order": 1, + "horizontal_order": 1, +} +EDGE_ATTRS = { + "sourcename": 0, + "targetname": 0, + "label": 0, + "linestyle": ATTRS_VAL["linestyles"], + "class": 1, + "thickness": 0, + "color": ATTRS_VAL["colors"], + "textcolor": ATTRS_VAL["colors"], + "arrowcolor": ATTRS_VAL["colors"], + "backarrowcolor": ATTRS_VAL["colors"], + "arrowsize": 1, + "backarrowsize": 1, + "arrowstyle": ATTRS_VAL["arrowstyles"], + "backarrowstyle": ATTRS_VAL["arrowstyles"], + "textmode": ATTRS_VAL["textmodes"], + "priority": 1, + "anchor": 1, + "horizontal_order": 1, +} + + +# Misc utilities ############################################################### + + +class VCGPrinter: + """A vcg graph writer. + """ + + def __init__(self, output_stream): + self._stream = output_stream + self._indent = "" + + def open_graph(self, **args): + """open a vcg graph + """ + self._stream.write("%sgraph:{\n" % self._indent) + self._inc_indent() + self._write_attributes(GRAPH_ATTRS, **args) + + def close_graph(self): + """close a vcg graph + """ + self._dec_indent() + self._stream.write("%s}\n" % self._indent) + + def node(self, title, **args): + """draw a node + """ + self._stream.write('%snode: {title:"%s"' % (self._indent, title)) + self._write_attributes(NODE_ATTRS, **args) + self._stream.write("}\n") + + def edge(self, from_node, to_node, edge_type="", **args): + """draw an edge from a node to another. + """ + self._stream.write( + '%s%sedge: {sourcename:"%s" targetname:"%s"' + % (self._indent, edge_type, from_node, to_node) + ) + self._write_attributes(EDGE_ATTRS, **args) + self._stream.write("}\n") + + # private ################################################################## + + def _write_attributes(self, attributes_dict, **args): + """write graph, node or edge attributes + """ + for key, value in args.items(): + try: + _type = attributes_dict[key] + except KeyError: + raise Exception( + """no such attribute %s +possible attributes are %s""" + % (key, attributes_dict.keys()) + ) + + if not _type: + self._stream.write('%s%s:"%s"\n' % (self._indent, key, value)) + elif _type == 1: + self._stream.write("%s%s:%s\n" % (self._indent, key, int(value))) + elif value in _type: + self._stream.write("%s%s:%s\n" % (self._indent, key, value)) + else: + raise Exception( + """value %s isn\'t correct for attribute %s +correct values are %s""" + % (value, key, _type) + ) + + def _inc_indent(self): + """increment indentation + """ + self._indent = " %s" % self._indent + + def _dec_indent(self): + """decrement indentation + """ + self._indent = self._indent[:-2] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/writer.py b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/writer.py new file mode 100644 index 0000000..332c288 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/pyreverse/writer.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2008-2010, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Mike Frysinger <vapier@gentoo.org> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Utilities for creating VCG and Dot diagrams""" + +from pylint.pyreverse.utils import is_exception +from pylint.pyreverse.vcgutils import VCGPrinter +from pylint.graph import DotBackend + + +class DiagramWriter: + """base class for writing project diagrams + """ + + def __init__(self, config, styles): + self.config = config + self.pkg_edges, self.inh_edges, self.imp_edges, self.association_edges = styles + self.printer = None # defined in set_printer + + def write(self, diadefs): + """write files for <project> according to <diadefs> + """ + for diagram in diadefs: + basename = diagram.title.strip().replace(" ", "_") + file_name = "%s.%s" % (basename, self.config.output_format) + self.set_printer(file_name, basename) + if diagram.TYPE == "class": + self.write_classes(diagram) + else: + self.write_packages(diagram) + self.close_graph() + + def write_packages(self, diagram): + """write a package diagram""" + # sorted to get predictable (hence testable) results + for i, obj in enumerate(sorted(diagram.modules(), key=lambda x: x.title)): + self.printer.emit_node(i, label=self.get_title(obj), shape="box") + obj.fig_id = i + # package dependencies + for rel in diagram.get_relationships("depends"): + self.printer.emit_edge( + rel.from_object.fig_id, rel.to_object.fig_id, **self.pkg_edges + ) + + def write_classes(self, diagram): + """write a class diagram""" + # sorted to get predictable (hence testable) results + for i, obj in enumerate(sorted(diagram.objects, key=lambda x: x.title)): + self.printer.emit_node(i, **self.get_values(obj)) + obj.fig_id = i + # inheritance links + for rel in diagram.get_relationships("specialization"): + self.printer.emit_edge( + rel.from_object.fig_id, rel.to_object.fig_id, **self.inh_edges + ) + # implementation links + for rel in diagram.get_relationships("implements"): + self.printer.emit_edge( + rel.from_object.fig_id, rel.to_object.fig_id, **self.imp_edges + ) + # generate associations + for rel in diagram.get_relationships("association"): + self.printer.emit_edge( + rel.from_object.fig_id, + rel.to_object.fig_id, + label=rel.name, + **self.association_edges + ) + + def set_printer(self, file_name, basename): + """set printer""" + raise NotImplementedError + + def get_title(self, obj): + """get project title""" + raise NotImplementedError + + def get_values(self, obj): + """get label and shape for classes.""" + raise NotImplementedError + + def close_graph(self): + """finalize the graph""" + raise NotImplementedError + + +class DotWriter(DiagramWriter): + """write dot graphs from a diagram definition and a project + """ + + def __init__(self, config): + styles = [ + dict(arrowtail="none", arrowhead="open"), + dict(arrowtail="none", arrowhead="empty"), + dict(arrowtail="node", arrowhead="empty", style="dashed"), + dict( + fontcolor="green", arrowtail="none", arrowhead="diamond", style="solid" + ), + ] + DiagramWriter.__init__(self, config, styles) + + def set_printer(self, file_name, basename): + """initialize DotWriter and add options for layout. + """ + layout = dict(rankdir="BT") + self.printer = DotBackend(basename, additional_param=layout) + self.file_name = file_name + + def get_title(self, obj): + """get project title""" + return obj.title + + def get_values(self, obj): + """get label and shape for classes. + + The label contains all attributes and methods + """ + label = obj.title + if obj.shape == "interface": + label = "«interface»\\n%s" % label + if not self.config.only_classnames: + label = r"%s|%s\l|" % (label, r"\l".join(obj.attrs)) + for func in obj.methods: + label = r"%s%s()\l" % (label, func.name) + label = "{%s}" % label + if is_exception(obj.node): + return dict(fontcolor="red", label=label, shape="record") + return dict(label=label, shape="record") + + def close_graph(self): + """print the dot graph into <file_name>""" + self.printer.generate(self.file_name) + + +class VCGWriter(DiagramWriter): + """write vcg graphs from a diagram definition and a project + """ + + def __init__(self, config): + styles = [ + dict(arrowstyle="solid", backarrowstyle="none", backarrowsize=0), + dict(arrowstyle="solid", backarrowstyle="none", backarrowsize=10), + dict( + arrowstyle="solid", + backarrowstyle="none", + linestyle="dotted", + backarrowsize=10, + ), + dict(arrowstyle="solid", backarrowstyle="none", textcolor="green"), + ] + DiagramWriter.__init__(self, config, styles) + + def set_printer(self, file_name, basename): + """initialize VCGWriter for a UML graph""" + self.graph_file = open(file_name, "w+") + self.printer = VCGPrinter(self.graph_file) + self.printer.open_graph( + title=basename, + layoutalgorithm="dfs", + late_edge_labels="yes", + port_sharing="no", + manhattan_edges="yes", + ) + self.printer.emit_node = self.printer.node + self.printer.emit_edge = self.printer.edge + + def get_title(self, obj): + """get project title in vcg format""" + return r"\fb%s\fn" % obj.title + + def get_values(self, obj): + """get label and shape for classes. + + The label contains all attributes and methods + """ + if is_exception(obj.node): + label = r"\fb\f09%s\fn" % obj.title + else: + label = r"\fb%s\fn" % obj.title + if obj.shape == "interface": + shape = "ellipse" + else: + shape = "box" + if not self.config.only_classnames: + attrs = obj.attrs + methods = [func.name for func in obj.methods] + # box width for UML like diagram + maxlen = max(len(name) for name in [obj.title] + methods + attrs) + line = "_" * (maxlen + 2) + label = r"%s\n\f%s" % (label, line) + for attr in attrs: + label = r"%s\n\f08%s" % (label, attr) + if attrs: + label = r"%s\n\f%s" % (label, line) + for func in methods: + label = r"%s\n\f10%s()" % (label, func) + return dict(label=label, shape=shape) + + def close_graph(self): + """close graph and file""" + self.printer.close_graph() + self.graph_file.close() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__init__.py new file mode 100644 index 0000000..c09ebdd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__init__.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006, 2010, 2012-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Ricardo Gemignani <ricardo.gemignani@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Simu Toni <simutoni@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2017 Kári Tristan Helgason <kthelgason@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""utilities methods and classes for reporters""" +from __future__ import print_function + +import sys +import locale +import os +import warnings + + +CMPS = ["=", "-", "+"] + +# py3k has no more cmp builtin +if sys.version_info >= (3, 0): + + def cmp(a, b): # pylint: disable=redefined-builtin + return (a > b) - (a < b) + + +def diff_string(old, new): + """given an old and new int value, return a string representing the + difference + """ + diff = abs(old - new) + diff_str = "%s%s" % (CMPS[cmp(old, new)], diff and ("%.2f" % diff) or "") + return diff_str + + +class BaseReporter: + """base class for reporters + + symbols: show short symbolic names for messages. + """ + + extension = "" + + def __init__(self, output=None): + self.linter = None + self.section = 0 + self.out = None + self.out_encoding = None + self.set_output(output) + # Build the path prefix to strip to get relative paths + self.path_strip_prefix = os.getcwd() + os.sep + + def handle_message(self, msg): + """Handle a new message triggered on the current file.""" + + def set_output(self, output=None): + """set output stream""" + self.out = output or sys.stdout + + def writeln(self, string=""): + """write a line in the output buffer""" + print(string, file=self.out) + + def display_reports(self, layout): + """display results encapsulated in the layout tree""" + self.section = 0 + if hasattr(layout, "report_id"): + layout.children[0].children[0].data += " (%s)" % layout.report_id + self._display(layout) + + def _display(self, layout): + """display the layout""" + raise NotImplementedError() + + def display_messages(self, layout): + """Hook for displaying the messages of the reporter + + This will be called whenever the underlying messages + needs to be displayed. For some reporters, it probably + doesn't make sense to display messages as soon as they + are available, so some mechanism of storing them could be used. + This method can be implemented to display them after they've + been aggregated. + """ + + # Event callbacks + + def on_set_current_module(self, module, filepath): + """Hook called when a module starts to be analysed.""" + + def on_close(self, stats, previous_stats): + """Hook called when a module finished analyzing.""" + + +class CollectingReporter(BaseReporter): + """collects messages""" + + name = "collector" + + def __init__(self): + BaseReporter.__init__(self) + self.messages = [] + + def handle_message(self, msg): + self.messages.append(msg) + + _display = None + + +def initialize(linter): + """initialize linter with reporters in this package """ + from pylint import utils + + utils.register_plugins(linter, __path__[0]) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..e83627e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/json.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/json.cpython-37.pyc new file mode 100644 index 0000000..f7aa821 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/json.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/text.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/text.cpython-37.pyc new file mode 100644 index 0000000..6df57d2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/reporters/__pycache__/text.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/json.py b/basic python programmes/venv/Lib/site-packages/pylint/reporters/json.py new file mode 100644 index 0000000..6a50201 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/reporters/json.py @@ -0,0 +1,61 @@ +# Copyright (c) 2014 Vlad Temian <vladtemian@gmail.com> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2017 guillaume2 <guillaume.peillex@gmail.col> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""JSON reporter""" +from __future__ import absolute_import, print_function + +import cgi +import json +import sys + +from pylint.interfaces import IReporter +from pylint.reporters import BaseReporter + + +class JSONReporter(BaseReporter): + """Report messages and layouts in JSON.""" + + __implements__ = IReporter + name = "json" + extension = "json" + + def __init__(self, output=sys.stdout): + BaseReporter.__init__(self, output) + self.messages = [] + + def handle_message(self, msg): + """Manage message of different type and in the context of path.""" + self.messages.append( + { + "type": msg.category, + "module": msg.module, + "obj": msg.obj, + "line": msg.line, + "column": msg.column, + "path": msg.path, + "symbol": msg.symbol, + # pylint: disable=deprecated-method; deprecated since 3.2. + "message": cgi.escape(msg.msg or ""), + "message-id": msg.msg_id, + } + ) + + def display_messages(self, layout): + """Launch layouts display""" + print(json.dumps(self.messages, indent=4), file=self.out) + + def display_reports(self, layout): # pylint: disable=arguments-differ + """Don't do nothing in this reporter.""" + + def _display(self, layout): + """Do nothing.""" + + +def register(linter): + """Register the reporter classes with the linter.""" + linter.register_reporter(JSONReporter) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/text.py b/basic python programmes/venv/Lib/site-packages/pylint/reporters/text.py new file mode 100644 index 0000000..4c682ae --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/reporters/text.py @@ -0,0 +1,250 @@ +# Copyright (c) 2006-2007, 2010-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 y2kbugger <y2kbugger@users.noreply.github.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Jace Browning <jacebrowning@gmail.com> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Plain text reporters: + +:text: the default one grouping messages by module +:colorized: an ANSI colorized text reporter +""" +from __future__ import print_function + +import os +import warnings +import sys + +from pylint.interfaces import IReporter +from pylint.reporters import BaseReporter +from pylint import utils +from pylint.reporters.ureports.text_writer import TextWriter + + +TITLE_UNDERLINES = ["", "=", "-", "."] + +ANSI_PREFIX = "\033[" +ANSI_END = "m" +ANSI_RESET = "\033[0m" +ANSI_STYLES = { + "reset": "0", + "bold": "1", + "italic": "3", + "underline": "4", + "blink": "5", + "inverse": "7", + "strike": "9", +} +ANSI_COLORS = { + "reset": "0", + "black": "30", + "red": "31", + "green": "32", + "yellow": "33", + "blue": "34", + "magenta": "35", + "cyan": "36", + "white": "37", +} + + +def _get_ansi_code(color=None, style=None): + """return ansi escape code corresponding to color and style + + :type color: str or None + :param color: + the color name (see `ANSI_COLORS` for available values) + or the color number when 256 colors are available + + :type style: str or None + :param style: + style string (see `ANSI_COLORS` for available values). To get + several style effects at the same time, use a coma as separator. + + :raise KeyError: if an unexistent color or style identifier is given + + :rtype: str + :return: the built escape code + """ + ansi_code = [] + if style: + style_attrs = utils._splitstrip(style) + for effect in style_attrs: + ansi_code.append(ANSI_STYLES[effect]) + if color: + if color.isdigit(): + ansi_code.extend(["38", "5"]) + ansi_code.append(color) + else: + ansi_code.append(ANSI_COLORS[color]) + if ansi_code: + return ANSI_PREFIX + ";".join(ansi_code) + ANSI_END + return "" + + +def colorize_ansi(msg, color=None, style=None): + """colorize message by wrapping it with ansi escape codes + + :type msg: str or unicode + :param msg: the message string to colorize + + :type color: str or None + :param color: + the color identifier (see `ANSI_COLORS` for available values) + + :type style: str or None + :param style: + style string (see `ANSI_COLORS` for available values). To get + several style effects at the same time, use a coma as separator. + + :raise KeyError: if an unexistent color or style identifier is given + + :rtype: str or unicode + :return: the ansi escaped string + """ + # If both color and style are not defined, then leave the text as is + if color is None and style is None: + return msg + escape_code = _get_ansi_code(color, style) + # If invalid (or unknown) color, don't wrap msg with ansi codes + if escape_code: + return "%s%s%s" % (escape_code, msg, ANSI_RESET) + return msg + + +class TextReporter(BaseReporter): + """reports messages and layouts in plain text""" + + __implements__ = IReporter + name = "text" + extension = "txt" + line_format = "{path}:{line}:{column}: {msg_id}: {msg} ({symbol})" + + def __init__(self, output=None): + BaseReporter.__init__(self, output) + self._modules = set() + self._template = None + + def on_set_current_module(self, module, filepath): + self._template = str(self.linter.config.msg_template or self.line_format) + + def write_message(self, msg): + """Convenience method to write a formated message with class default template""" + self.writeln(msg.format(self._template)) + + def handle_message(self, msg): + """manage message of different type and in the context of path""" + if msg.module not in self._modules: + if msg.module: + self.writeln("************* Module %s" % msg.module) + self._modules.add(msg.module) + else: + self.writeln("************* ") + self.write_message(msg) + + def _display(self, layout): + """launch layouts display""" + print(file=self.out) + TextWriter().format(layout, self.out) + + +class ParseableTextReporter(TextReporter): + """a reporter very similar to TextReporter, but display messages in a form + recognized by most text editors : + + <filename>:<linenum>:<msg> + """ + + name = "parseable" + line_format = "{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" + + def __init__(self, output=None): + warnings.warn( + "%s output format is deprecated. This is equivalent " + "to --msg-template=%s" % (self.name, self.line_format), + DeprecationWarning, + ) + TextReporter.__init__(self, output) + + +class VSTextReporter(ParseableTextReporter): + """Visual studio text reporter""" + + name = "msvs" + line_format = "{path}({line}): [{msg_id}({symbol}){obj}] {msg}" + + +class ColorizedTextReporter(TextReporter): + """Simple TextReporter that colorizes text output""" + + name = "colorized" + COLOR_MAPPING = { + "I": ("green", None), + "C": (None, "bold"), + "R": ("magenta", "bold, italic"), + "W": ("magenta", None), + "E": ("red", "bold"), + "F": ("red", "bold, underline"), + "S": ("yellow", "inverse"), # S stands for module Separator + } + + def __init__(self, output=None, color_mapping=None): + TextReporter.__init__(self, output) + self.color_mapping = color_mapping or dict(ColorizedTextReporter.COLOR_MAPPING) + ansi_terms = ["xterm-16color", "xterm-256color"] + if os.environ.get("TERM") not in ansi_terms: + if sys.platform == "win32": + # pylint: disable=import-error + import colorama + + self.out = colorama.AnsiToWin32(self.out) + + def _get_decoration(self, msg_id): + """Returns the tuple color, style associated with msg_id as defined + in self.color_mapping + """ + try: + return self.color_mapping[msg_id[0]] + except KeyError: + return None, None + + def handle_message(self, msg): + """manage message of different types, and colorize output + using ansi escape codes + """ + if msg.module not in self._modules: + color, style = self._get_decoration("S") + if msg.module: + modsep = colorize_ansi( + "************* Module %s" % msg.module, color, style + ) + else: + modsep = colorize_ansi("************* %s" % msg.module, color, style) + self.writeln(modsep) + self._modules.add(msg.module) + color, style = self._get_decoration(msg.C) + + msg = msg._replace( + **{ + attr: colorize_ansi(getattr(msg, attr), color, style) + for attr in ("msg", "symbol", "category", "C") + } + ) + self.write_message(msg) + + +def register(linter): + """Register the reporter classes with the linter.""" + linter.register_reporter(TextReporter) + linter.register_reporter(ParseableTextReporter) + linter.register_reporter(VSTextReporter) + linter.register_reporter(ColorizedTextReporter) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__init__.py new file mode 100644 index 0000000..56a829f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__init__.py @@ -0,0 +1,97 @@ +# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Universal report objects and some formatting drivers. + +A way to create simple reports using python objects, primarily designed to be +formatted as text and html. +""" +import os +import sys + +from io import StringIO + + +class BaseWriter: + """base class for ureport writers""" + + def format(self, layout, stream=None, encoding=None): + """format and write the given layout into the stream object + + unicode policy: unicode strings may be found in the layout; + try to call stream.write with it, but give it back encoded using + the given encoding if it fails + """ + if stream is None: + stream = sys.stdout + if not encoding: + encoding = getattr(stream, "encoding", "UTF-8") + self.encoding = encoding or "UTF-8" + self.out = stream + self.begin_format() + layout.accept(self) + self.end_format() + + def format_children(self, layout): + """recurse on the layout children and call their accept method + (see the Visitor pattern) + """ + for child in getattr(layout, "children", ()): + child.accept(self) + + def writeln(self, string=""): + """write a line in the output buffer""" + self.write(string + os.linesep) + + def write(self, string): + """write a string in the output buffer""" + self.out.write(string) + + def begin_format(self): + """begin to format a layout""" + self.section = 0 + + def end_format(self): + """finished to format a layout""" + + def get_table_content(self, table): + """trick to get table content without actually writing it + + return an aligned list of lists containing table cells values as string + """ + result = [[]] + cols = table.cols + for cell in self.compute_content(table): + if cols == 0: + result.append([]) + cols = table.cols + cols -= 1 + result[-1].append(cell) + # fill missing cells + while len(result[-1]) < cols: + result[-1].append("") + return result + + def compute_content(self, layout): + """trick to compute the formatting of children layout before actually + writing it + + return an iterator on strings (one for each child element) + """ + # Patch the underlying output stream with a fresh-generated stream, + # which is used to store a temporary representation of a child + # node. + out = self.out + try: + for child in layout.children: + stream = StringIO() + self.out = stream + child.accept(self) + yield stream.getvalue() + finally: + self.out = out diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..224dd56 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/nodes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/nodes.cpython-37.pyc new file mode 100644 index 0000000..609ad95 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/nodes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/text_writer.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/text_writer.cpython-37.pyc new file mode 100644 index 0000000..0014510 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/__pycache__/text_writer.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/nodes.py b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/nodes.py new file mode 100644 index 0000000..8fafb20 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/nodes.py @@ -0,0 +1,188 @@ +# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Micro reports objects. + +A micro report is a tree of layout and content objects. +""" + + +class VNode: + def __init__(self, nid=None): + self.id = nid + # navigation + self.parent = None + self.children = [] + + def __iter__(self): + return iter(self.children) + + def append(self, child): + """add a node to children""" + self.children.append(child) + child.parent = self + + def insert(self, index, child): + """insert a child node""" + self.children.insert(index, child) + child.parent = self + + def _get_visit_name(self): + """ + return the visit name for the mixed class. When calling 'accept', the + method <'visit_' + name returned by this method> will be called on the + visitor + """ + try: + # pylint: disable=no-member + return self.TYPE.replace("-", "_") + # pylint: disable=broad-except + except Exception: + return self.__class__.__name__.lower() + + def accept(self, visitor, *args, **kwargs): + func = getattr(visitor, "visit_%s" % self._get_visit_name()) + return func(self, *args, **kwargs) + + def leave(self, visitor, *args, **kwargs): + func = getattr(visitor, "leave_%s" % self._get_visit_name()) + return func(self, *args, **kwargs) + + +class BaseLayout(VNode): + """base container node + + attributes + * children : components in this table (i.e. the table's cells) + """ + + def __init__(self, children=(), **kwargs): + super(BaseLayout, self).__init__(**kwargs) + for child in children: + if isinstance(child, VNode): + self.append(child) + else: + self.add_text(child) + + def append(self, child): + """overridden to detect problems easily""" + assert child not in self.parents() + VNode.append(self, child) + + def parents(self): + """return the ancestor nodes""" + assert self.parent is not self + if self.parent is None: + return [] + return [self.parent] + self.parent.parents() + + def add_text(self, text): + """shortcut to add text data""" + self.children.append(Text(text)) + + +# non container nodes ######################################################### + + +class Text(VNode): + """a text portion + + attributes : + * data : the text value as an encoded or unicode string + """ + + def __init__(self, data, escaped=True, **kwargs): + super(Text, self).__init__(**kwargs) + # if isinstance(data, unicode): + # data = data.encode('ascii') + assert isinstance(data, str), data.__class__ + self.escaped = escaped + self.data = data + + +class VerbatimText(Text): + """a verbatim text, display the raw data + + attributes : + * data : the text value as an encoded or unicode string + """ + + +# container nodes ############################################################# + + +class Section(BaseLayout): + """a section + + attributes : + * BaseLayout attributes + + a title may also be given to the constructor, it'll be added + as a first element + a description may also be given to the constructor, it'll be added + as a first paragraph + """ + + def __init__(self, title=None, description=None, **kwargs): + super(Section, self).__init__(**kwargs) + if description: + self.insert(0, Paragraph([Text(description)])) + if title: + self.insert(0, Title(children=(title,))) + + +class EvaluationSection(Section): + def __init__(self, message, **kwargs): + super(EvaluationSection, self).__init__(**kwargs) + title = Paragraph() + title.append(Text("-" * len(message))) + self.append(title) + + message_body = Paragraph() + message_body.append(Text(message)) + self.append(message_body) + + +class Title(BaseLayout): + """a title + + attributes : + * BaseLayout attributes + + A title must not contains a section nor a paragraph! + """ + + +class Paragraph(BaseLayout): + """a simple text paragraph + + attributes : + * BaseLayout attributes + + A paragraph must not contains a section ! + """ + + +class Table(BaseLayout): + """some tabular data + + attributes : + * BaseLayout attributes + * cols : the number of columns of the table (REQUIRED) + * rheaders : the first row's elements are table's header + * cheaders : the first col's elements are table's header + * title : the table's optional title + """ + + def __init__(self, cols, title=None, rheaders=0, cheaders=0, **kwargs): + super(Table, self).__init__(**kwargs) + assert isinstance(cols, int) + self.cols = cols + self.title = title + self.rheaders = rheaders + self.cheaders = cheaders diff --git a/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/text_writer.py b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/text_writer.py new file mode 100644 index 0000000..9d9e1ad --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/reporters/ureports/text_writer.py @@ -0,0 +1,97 @@ +# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Text formatting drivers for ureports""" + +from __future__ import print_function + +from pylint.reporters.ureports import BaseWriter + + +TITLE_UNDERLINES = ["", "=", "-", "`", ".", "~", "^"] +BULLETS = ["*", "-"] + + +class TextWriter(BaseWriter): + """format layouts as text + (ReStructured inspiration but not totally handled yet) + """ + + def begin_format(self): + super(TextWriter, self).begin_format() + self.list_level = 0 + + def visit_section(self, layout): + """display a section as text + """ + self.section += 1 + self.writeln() + self.format_children(layout) + self.section -= 1 + self.writeln() + + def visit_evaluationsection(self, layout): + """Display an evaluation section as a text.""" + self.section += 1 + self.format_children(layout) + self.section -= 1 + self.writeln() + + def visit_title(self, layout): + title = "".join(list(self.compute_content(layout))) + self.writeln(title) + try: + self.writeln(TITLE_UNDERLINES[self.section] * len(title)) + except IndexError: + print("FIXME TITLE TOO DEEP. TURNING TITLE INTO TEXT") + + def visit_paragraph(self, layout): + """enter a paragraph""" + self.format_children(layout) + self.writeln() + + def visit_table(self, layout): + """display a table as text""" + table_content = self.get_table_content(layout) + # get columns width + cols_width = [0] * len(table_content[0]) + for row in table_content: + for index, col in enumerate(row): + cols_width[index] = max(cols_width[index], len(col)) + self.default_table(layout, table_content, cols_width) + self.writeln() + + def default_table(self, layout, table_content, cols_width): + """format a table""" + cols_width = [size + 1 for size in cols_width] + format_strings = " ".join(["%%-%ss"] * len(cols_width)) + format_strings = format_strings % tuple(cols_width) + format_strings = format_strings.split(" ") + table_linesep = "\n+" + "+".join(["-" * w for w in cols_width]) + "+\n" + headsep = "\n+" + "+".join(["=" * w for w in cols_width]) + "+\n" + # FIXME: layout.cheaders + self.write(table_linesep) + for index, line in enumerate(table_content): + self.write("|") + for line_index, at_index in enumerate(line): + self.write(format_strings[line_index] % at_index) + self.write("|") + if index == 0 and layout.rheaders: + self.write(headsep) + else: + self.write(table_linesep) + + def visit_verbatimtext(self, layout): + """display a verbatim layout as text (so difficult ;) + """ + self.writeln("::\n") + for line in layout.data.splitlines(): + self.writeln(" " + line) + self.writeln() + + def visit_text(self, layout): + """add some text""" + self.write("%s" % layout.data) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/conftest.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/conftest.cpython-37.pyc new file mode 100644 index 0000000..e82c4f6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/conftest.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_func.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_func.cpython-37.pyc new file mode 100644 index 0000000..dd8cf6e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_func.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_functional.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_functional.cpython-37.pyc new file mode 100644 index 0000000..91469b7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_functional.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_import_graph.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_import_graph.cpython-37.pyc new file mode 100644 index 0000000..ec5c1a1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_import_graph.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_regr.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_regr.cpython-37.pyc new file mode 100644 index 0000000..1e007aa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_regr.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_self.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_self.cpython-37.pyc new file mode 100644 index 0000000..5153afd Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/test_self.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_base.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_base.cpython-37.pyc new file mode 100644 index 0000000..3d8d6b2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_base.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_classes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_classes.cpython-37.pyc new file mode 100644 index 0000000..834cfe0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_classes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_exceptions.cpython-37.pyc new file mode 100644 index 0000000..9cfc19a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_format.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_format.cpython-37.pyc new file mode 100644 index 0000000..acc7ead Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_format.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_imports.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_imports.cpython-37.pyc new file mode 100644 index 0000000..d11954f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_imports.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_logging.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_logging.cpython-37.pyc new file mode 100644 index 0000000..0978714 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_logging.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_misc.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_misc.cpython-37.pyc new file mode 100644 index 0000000..a15d01f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_misc.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_python3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_python3.cpython-37.pyc new file mode 100644 index 0000000..3154d45 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_python3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_similar.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_similar.cpython-37.pyc new file mode 100644 index 0000000..a13931b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_similar.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_spelling.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_spelling.cpython-37.pyc new file mode 100644 index 0000000..a1ecdc9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_spelling.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_stdlib.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_stdlib.cpython-37.pyc new file mode 100644 index 0000000..ba426c0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_stdlib.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_strings.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_strings.cpython-37.pyc new file mode 100644 index 0000000..aae5f46 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_strings.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_typecheck.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_typecheck.cpython-37.pyc new file mode 100644 index 0000000..7d901e3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_typecheck.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_variables.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_variables.cpython-37.pyc new file mode 100644 index 0000000..e2916ec Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checker_variables.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checkers_utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checkers_utils.cpython-37.pyc new file mode 100644 index 0000000..2ebadd8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_checkers_utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_config.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_config.cpython-37.pyc new file mode 100644 index 0000000..56c9248 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_config.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_lint.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_lint.cpython-37.pyc new file mode 100644 index 0000000..e2b17c5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_lint.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_diadefs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_diadefs.cpython-37.pyc new file mode 100644 index 0000000..0653246 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_diadefs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_inspector.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_inspector.cpython-37.pyc new file mode 100644 index 0000000..c4bab59 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_inspector.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_writer.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_writer.cpython-37.pyc new file mode 100644 index 0000000..b8c8fde Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_pyreverse_writer.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_reporters_json.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_reporters_json.cpython-37.pyc new file mode 100644 index 0000000..09563e5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_reporters_json.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_reporting.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_reporting.cpython-37.pyc new file mode 100644 index 0000000..d539f35 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_reporting.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_utils.cpython-37.pyc new file mode 100644 index 0000000..1a42011 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/__pycache__/unittest_utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/acceptance/__pycache__/test_stdlib.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/acceptance/__pycache__/test_stdlib.cpython-37.pyc new file mode 100644 index 0000000..8f49f34 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/acceptance/__pycache__/test_stdlib.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/acceptance/test_stdlib.py b/basic python programmes/venv/Lib/site-packages/pylint/test/acceptance/test_stdlib.py new file mode 100644 index 0000000..1b97fd2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/acceptance/test_stdlib.py @@ -0,0 +1,54 @@ +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import contextlib +import io +import os +import sys + +import pytest + +import pylint.lint + + +def is_module(filename): + return filename.endswith(".py") + + +def is_package(filename, location): + return os.path.exists(os.path.join(location, filename, "__init__.py")) + + +@contextlib.contextmanager +def _patch_stdout(out): + sys.stdout = out + try: + yield + finally: + sys.stdout = sys.__stdout__ + + +LIB_DIRS = [os.path.dirname(os.__file__)] +MODULES_TO_CHECK = [ + (location, module) + for location in LIB_DIRS + for module in os.listdir(location) + if is_module(module) or is_package(module, location) +] +MODULES_NAMES = [m[1] for m in MODULES_TO_CHECK] + + +@pytest.mark.acceptance +@pytest.mark.parametrize( + ("test_module_location", "test_module_name"), MODULES_TO_CHECK, ids=MODULES_NAMES +) +def test_libmodule(test_module_location, test_module_name): + os.chdir(test_module_location) + with _patch_stdout(io.StringIO()): + try: + pylint.lint.Run([test_module_name, "--enable=all", "--ignore=test"]) + except SystemExit as ex: + assert ex.code != 32 + return + + assert False, "shouldn't get there" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/conftest.py b/basic python programmes/venv/Lib/site-packages/pylint/test/conftest.py new file mode 100644 index 0000000..d75522b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/conftest.py @@ -0,0 +1,53 @@ +# pylint: disable=redefined-outer-name +import os +import pytest + +from pylint import checkers +from pylint.lint import PyLinter + +# pylint: disable=no-name-in-module +from pylint.testutils import MinimalTestReporter + + +@pytest.fixture +def linter(checker, register, enable, disable, reporter): + _linter = PyLinter() + _linter.set_reporter(reporter()) + checkers.initialize(_linter) + if register: + register(_linter) + if checker: + _linter.register_checker(checker(_linter)) + if disable: + for msg in disable: + _linter.disable(msg) + if enable: + for msg in enable: + _linter.enable(msg) + os.environ.pop("PYLINTRC", None) + return _linter + + +@pytest.fixture(scope="module") +def checker(): + return None + + +@pytest.fixture(scope="module") +def register(): + return None + + +@pytest.fixture(scope="module") +def enable(): + return None + + +@pytest.fixture(scope="module") +def disable(): + return None + + +@pytest.fixture(scope="module") +def reporter(): + return MinimalTestReporter diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/data/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..4a95d75 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/clientmodule_test.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/clientmodule_test.cpython-37.pyc new file mode 100644 index 0000000..0b893dc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/clientmodule_test.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/suppliermodule_test.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/suppliermodule_test.cpython-37.pyc new file mode 100644 index 0000000..5fac0db Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/data/__pycache__/suppliermodule_test.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/ascript b/basic python programmes/venv/Lib/site-packages/pylint/test/data/ascript new file mode 100644 index 0000000..f401ebc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/data/ascript @@ -0,0 +1,2 @@ +#!/usr/bin/python +"""ttttttttttttttttttttoooooooooooooooooooooooooooooooooooooooooooooooooooooo lllllllllllooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnngggggggggggggggggg""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/classes_No_Name.dot b/basic python programmes/venv/Lib/site-packages/pylint/test/data/classes_No_Name.dot new file mode 100644 index 0000000..3a9df79 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/data/classes_No_Name.dot @@ -0,0 +1,12 @@ +digraph "classes_No_Name" { +charset="utf-8" +rankdir=BT +"0" [label="{Ancestor|attr : str\lcls_member\l|get_value()\lset_value()\l}", shape="record"]; +"1" [label="{DoNothing|\l|}", shape="record"]; +"2" [label="{Interface|\l|get_value()\lset_value()\l}", shape="record"]; +"3" [label="{Specialization|TYPE : str\lrelation\ltop : str\l|}", shape="record"]; +"3" -> "0" [arrowhead="empty", arrowtail="none"]; +"0" -> "2" [arrowhead="empty", arrowtail="node", style="dashed"]; +"1" -> "0" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="cls_member", style="solid"]; +"1" -> "3" [arrowhead="diamond", arrowtail="none", fontcolor="green", label="relation", style="solid"]; +} diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/clientmodule_test.py b/basic python programmes/venv/Lib/site-packages/pylint/test/data/clientmodule_test.py new file mode 100644 index 0000000..40db2e7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/data/clientmodule_test.py @@ -0,0 +1,29 @@ +""" docstring for file clientmodule.py """ +from data.suppliermodule_test import Interface, DoNothing + +class Ancestor: + """ Ancestor method """ + __implements__ = (Interface,) + cls_member = DoNothing() + + def __init__(self, value): + local_variable = 0 + self.attr = 'this method shouldn\'t have a docstring' + self.__value = value + + def get_value(self): + """ nice docstring ;-) """ + return self.__value + + def set_value(self, value): + self.__value = value + return 'this method shouldn\'t have a docstring' + +class Specialization(Ancestor): + TYPE = 'final class' + top = 'class' + + def __init__(self, value, _id): + Ancestor.__init__(self, value) + self._id = _id + self.relation = DoNothing() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/packages_No_Name.dot b/basic python programmes/venv/Lib/site-packages/pylint/test/data/packages_No_Name.dot new file mode 100644 index 0000000..1ceeb72 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/data/packages_No_Name.dot @@ -0,0 +1,8 @@ +digraph "packages_No_Name" { +charset="utf-8" +rankdir=BT +"0" [label="data", shape="box"]; +"1" [label="data.clientmodule_test", shape="box"]; +"2" [label="data.suppliermodule_test", shape="box"]; +"1" -> "2" [arrowhead="open", arrowtail="none"]; +} diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/data/suppliermodule_test.py b/basic python programmes/venv/Lib/site-packages/pylint/test/data/suppliermodule_test.py new file mode 100644 index 0000000..24dc9a0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/data/suppliermodule_test.py @@ -0,0 +1,10 @@ +""" file suppliermodule.py """ + +class Interface: + def get_value(self): + raise NotImplementedError + + def set_value(self, value): + raise NotImplementedError + +class DoNothing: pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..795ef11 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_bad_builtin.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_bad_builtin.cpython-37.pyc new file mode 100644 index 0000000..dd8e700 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_bad_builtin.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_docs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_docs.cpython-37.pyc new file mode 100644 index 0000000..f2c35fe Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_docs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_docs_utils.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_docs_utils.cpython-37.pyc new file mode 100644 index 0000000..77bd817 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_docs_utils.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_mccabe.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_mccabe.cpython-37.pyc new file mode 100644 index 0000000..ae1f771 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_mccabe.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_raise_docs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_raise_docs.cpython-37.pyc new file mode 100644 index 0000000..8e5abbe Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_raise_docs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_return_docs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_return_docs.cpython-37.pyc new file mode 100644 index 0000000..6077fe9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_return_docs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_yields_docs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_yields_docs.cpython-37.pyc new file mode 100644 index 0000000..5b40e63 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_check_yields_docs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_comparetozero.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_comparetozero.cpython-37.pyc new file mode 100644 index 0000000..5ad3379 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_comparetozero.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_docstyle.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_docstyle.cpython-37.pyc new file mode 100644 index 0000000..bb5bf22 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_docstyle.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_elseif_used.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_elseif_used.cpython-37.pyc new file mode 100644 index 0000000..d5ba779 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_elseif_used.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_emptystring.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_emptystring.cpython-37.pyc new file mode 100644 index 0000000..c6d9ca5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_emptystring.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_overlapping_exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_overlapping_exceptions.cpython-37.pyc new file mode 100644 index 0000000..2268743 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_overlapping_exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_redefined.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_redefined.cpython-37.pyc new file mode 100644 index 0000000..1654a66 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/__pycache__/test_redefined.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/bad_builtin.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/bad_builtin.cpython-37.pyc new file mode 100644 index 0000000..fa2f537 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/bad_builtin.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/compare_to_zero.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/compare_to_zero.cpython-37.pyc new file mode 100644 index 0000000..f51a719 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/compare_to_zero.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/docstring.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/docstring.cpython-37.pyc new file mode 100644 index 0000000..ffbdd3b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/docstring.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/elif.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/elif.cpython-37.pyc new file mode 100644 index 0000000..10acf8c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/elif.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/empty_string_comparison.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/empty_string_comparison.cpython-37.pyc new file mode 100644 index 0000000..634fdde Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/empty_string_comparison.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/mccabe.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/mccabe.cpython-37.pyc new file mode 100644 index 0000000..7288d9c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/mccabe.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions.cpython-37.pyc new file mode 100644 index 0000000..be8aebf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions_py33.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions_py33.cpython-37.pyc new file mode 100644 index 0000000..affb5e3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/overlapping_exceptions_py33.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/redefined.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/redefined.cpython-37.pyc new file mode 100644 index 0000000..17f65a3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/__pycache__/redefined.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/bad_builtin.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/bad_builtin.py new file mode 100644 index 0000000..fd3e5c0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/bad_builtin.py @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring + +TEST = map(str, (1, 2, 3)) # [bad-builtin] +TEST1 = filter(str, (1, 2, 3)) # [bad-builtin] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/compare_to_zero.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/compare_to_zero.py new file mode 100644 index 0000000..06f3475 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/compare_to_zero.py @@ -0,0 +1,28 @@ +# pylint: disable=literal-comparison,missing-docstring,misplaced-comparison-constant + +X = 123 +Y = len('test') + +if X is 0: # [compare-to-zero] + pass + +if Y is not 0: # [compare-to-zero] + pass + +if X == 0: # [compare-to-zero] + pass + +if Y != 0: # [compare-to-zero] + pass + +if X > 0: # [compare-to-zero] + pass + +if X < 0: # this is allowed + pass + +if 0 < X: # [compare-to-zero] + pass + +if 0 > X: # this is allowed + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/docstring.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/docstring.py new file mode 100644 index 0000000..8f34c65 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/docstring.py @@ -0,0 +1,40 @@ +"""Checks of Dosctrings 'docstring-first-line-empty' 'bad-docstring-quotes'""" + + +def check_messages(*messages): + """ + docstring""" + return messages + +def function2(): + """Test Ok""" + +class FFFF: + """ + Test Docstring First Line Empty + """ + + def method1(self): + ''' + Test Triple Single Quotes docstring + ''' + + def method2(self): + "bad docstring 1" + + def method3(self): + 'bad docstring 2' + + def method4(self): + ' """bad docstring 3 ' + + @check_messages('bad-open-mode', 'redundant-unittest-assert', + 'deprecated-module') + def method5(self): + """Test OK 1 with decorators""" + + def method6(self): + r"""Test OK 2 with raw string""" + + def method7(self): + u"""Test OK 3 with unicode string""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/elif.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/elif.py new file mode 100644 index 0000000..22e79c1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/elif.py @@ -0,0 +1,26 @@ +"""Checks use of "else if" triggers a refactor message""" + +def my_function(): + """docstring""" + myint = 2 + if myint > 5: + pass + else: + if myint <= 5: + pass + else: + myint = 3 + if myint > 2: + if myint > 3: + pass + elif myint == 3: + pass + elif myint < 3: + pass + else: + if myint: + pass + else: + if myint: + pass + myint = 4 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/empty_string_comparison.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/empty_string_comparison.py new file mode 100644 index 0000000..c6dcf8e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/empty_string_comparison.py @@ -0,0 +1,16 @@ +# pylint: disable=literal-comparison,missing-docstring + +X = '' +Y = 'test' + +if X is '': # [compare-to-empty-string] + pass + +if Y is not "": # [compare-to-empty-string] + pass + +if X == "": # [compare-to-empty-string] + pass + +if Y != '': # [compare-to-empty-string] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/mccabe.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/mccabe.py new file mode 100644 index 0000000..fdbdb5f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/mccabe.py @@ -0,0 +1,205 @@ +"""Checks use of "too-complex" check""" + + +def f1(): + """McCabe rating: 1""" + pass + + +def f2(n): + """McCabe rating: 1""" + k = n + 4 + s = k + n + return s + + +def f3(n): + """McCabe rating: 3""" + if n > 3: + return "bigger than three" + elif n > 4: + return "is never executed" + else: + return "smaller than or equal to three" + + +def f4(): + """McCabe rating: 2""" + for i in range(10): + print(i) + + +def f5(mylist): + """McCabe rating: 2""" + for i in mylist: + print(i) + else: + print(None) + + +def f6(n): + """McCabe rating: 2""" + if n > 4: + return f(n - 1) + else: + return n + + +def f7(): + """McCabe rating: 3""" + def b(): + """McCabe rating: 2""" + def c(): + """McCabe rating: 1""" + pass + c() + b() + + +def f8(): + """McCabe rating: 4""" + try: + print(1) + except TypeA: + print(2) + except TypeB: + print(3) + else: + print(4) + + +def f9(): + """McCabe rating: 9""" + myint = 2 + if myint > 5: + pass + else: + if myint <= 5: + pass + else: + myint = 3 + if myint > 2: + if myint > 3: + pass + elif myint == 3: + pass + elif myint < 3: + pass + else: + if myint: + pass + else: + if myint: + pass + myint = 4 + + +def f10(): + """McCabe rating: 11""" + myint = 2 + if myint == 5: + return myint + elif myint == 6: + return myint + elif myint == 7: + return myint + elif myint == 8: + return myint + elif myint == 9: + return myint + elif myint == 10: + if myint == 8: + while True: + return True + elif myint == 8: + with myint: + return 8 + else: + if myint == 2: + return myint + return myint + return myint + + +class MyClass1(object): + """Class of example to test mccabe""" + _name = 'MyClass' # To force a tail.node=None + + def method1(): + """McCabe rating: 1""" + pass + + def method2(self, param1): + """McCabe rating: 18""" + if not param1: + pass + pass + if param1: + pass + else: + pass + + pass + + if param1: + pass + if param1: + pass + if param1: + pass + if param1: + pass + if param1: + pass + if param1: + pass + if param1: + for value in range(5): + pass + + pass + for count in range(6): + with open('myfile') as fp: + count += 1 + pass + pass + try: + pass + if not param1: + pass + else: + pass + if param1: + raise BaseException('Error') + with open('myfile2') as fp2: + pass + pass + finally: + if param1 is not None: + pass + for count2 in range(8): + try: + pass + except BaseException('Error2'): + pass + return param1 + + +for count in range(10): + if count == 1: + exit(0) + elif count == 2: + exit(1) + else: + exit(2) + + +def method3(self): + try: + if True: + pass + else: + pass + finally: + pass + return True diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/overlapping_exceptions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/overlapping_exceptions.py new file mode 100644 index 0000000..5ee50f3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/overlapping_exceptions.py @@ -0,0 +1,45 @@ +# pylint: disable=missing-docstring + +class SomeException(Exception): + pass + +class SubclassException(SomeException): + pass + +AliasException = SomeException + +try: + pass +except (SomeException, SomeException): # [overlapping-except] + pass + +try: + pass +except (SomeException, SubclassException): # [overlapping-except] + pass + +try: + pass +except (SomeException, AliasException): # [overlapping-except] + pass + +try: + pass +except (AliasException, SubclassException): # [overlapping-except] + pass + +try: + pass +# +1:[overlapping-except, overlapping-except, overlapping-except] +except (SomeException, AliasException, SubclassException): + pass + +try: + pass +except (ArithmeticError, FloatingPointError): # [overlapping-except] + pass + +try: + pass +except (ValueError, UnicodeDecodeError): # [overlapping-except] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/overlapping_exceptions_py33.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/overlapping_exceptions_py33.py new file mode 100644 index 0000000..16d5c30 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/overlapping_exceptions_py33.py @@ -0,0 +1,18 @@ +# pylint: disable=missing-docstring + +import socket + +try: + pass +except (IOError, OSError): # [overlapping-except] + pass + +try: + pass +except (socket.error, OSError): # [overlapping-except] + pass + +try: + pass +except (ConnectionError, socket.error): # [overlapping-except] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/redefined.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/redefined.py new file mode 100644 index 0000000..7db75e8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/data/redefined.py @@ -0,0 +1,85 @@ +"""Checks variable types aren't redefined within a method or a function""" + +# pylint: disable=too-few-public-methods,missing-docstring,unused-variable,invalid-name, useless-object-inheritance + +_OK = True + +class MyClass(object): + + class Klass(object): + def __init__(self): + self.var2 = 'var' + + def __init__(self): + self.var = True + self.var1 = 2 + self.var2 = 1. + self.var1 = 2. # [redefined-variable-type] + self.a_str = "hello" + a_str = False + (a_str, b_str) = (1, 2) # no support for inference on tuple assignment + a_str = 2.0 if self.var else 1.0 # no support for inference on ifexpr + + def _getter(self): + return self.a_str + def _setter(self, val): + self.a_str = val + var2 = property(_getter, _setter) + + def some_method(self): + def func(): + var = 1 + test = 'bar' + var = 'baz' # [redefined-variable-type] + self.var = 1 # the rule checks for redefinitions in the scope of a function or method + test = 'foo' + myint = 2 + myint = False # [redefined-variable-type] + +_OK = "This is OK" # [redefined-variable-type] + +if _OK: + SOME_FLOAT = 1. + +def dummy_function(): + return 2 + +def other_function(): + instance = MyClass() + instance = True # [redefined-variable-type] + +SOME_FLOAT = dummy_function() # [redefined-variable-type] + +A_GLOB = None +A_GLOB = [1, 2, 3] + +def func2(x): + if x: + var = 'foo' + else: + var = True + + if x: + var2 = 'foo' + elif not x: + var2 = 2 + else: + pass + + if x: + var3 = 'foo' + var3 = 2 # [redefined-variable-type] + else: + pass + + var = 2 # [redefined-variable-type] + + if x: + pass + elif not x: + var4 = True + elif _OK: + pass + else: + var4 = 2. + var4 = 'baz' # [redefined-variable-type] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_bad_builtin.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_bad_builtin.py new file mode 100644 index 0000000..7d5d7f3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_bad_builtin.py @@ -0,0 +1,43 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.bad_builtin +""" + +import os.path as osp + +import pytest + +from pylint.extensions.bad_builtin import BadBuiltinChecker +from pylint.lint import fix_import_path + + +EXPECTED = [ + "Used builtin function 'map'. Using a list comprehension can be clearer.", + "Used builtin function 'filter'. Using a list comprehension can be clearer.", +] + + +@pytest.fixture(scope='module') +def checker(checker): + return BadBuiltinChecker + + +@pytest.fixture(scope='module') +def disable(disable): + return ['I'] + + +def test_types_redefined(linter): + elif_test = osp.join(osp.dirname(osp.abspath(__file__)), 'data', + 'bad_builtin.py') + with fix_import_path([elif_test]): + linter.check([elif_test]) + msgs = sorted(linter.reporter.messages, key=lambda item: item.line) + assert len(msgs) == 2 + for msg, expected in zip(msgs, EXPECTED): + assert msg.symbol == 'bad-builtin' + assert msg.msg == expected diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_docs.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_docs.py new file mode 100644 index 0000000..bad6baf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_docs.py @@ -0,0 +1,2192 @@ +# Copyright (c) 2014-2015 Bruno Daniel <bruno.daniel@blue-yonder.com> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2018 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Mitar <mitar.github@tnode.com> +# Copyright (c) 2017 John Paraskevopoulos <io.paraskev@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Adrian Chirieac <chirieacam@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the pylint checkers in :mod:`pylint.extensions.check_docs`, +in particular the parameter documentation checker `DocstringChecker` +""" +from __future__ import division, print_function, absolute_import + +import sys + +import pytest + +import astroid +from pylint.testutils import CheckerTestCase, Message, set_config + +from pylint.extensions.docparams import DocstringParameterChecker + + +class TestParamDocChecker(CheckerTestCase): + """Tests for pylint_plugin.ParamDocChecker""" + CHECKER_CLASS = DocstringParameterChecker + CONFIG = { + 'accept_no_param_doc': False, + } + + def test_missing_func_params_in_sphinx_docstring(self): + """Example of a function with missing Sphinx parameter documentation in + the docstring + """ + node = astroid.extract_node(""" + def function_foo(x, y, z): + '''docstring ... + + :param x: bla + + :param int z: bar + ''' + pass + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('y',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)) + ): + self.checker.visit_functiondef(node) + + def test_missing_func_params_in_google_docstring(self): + """Example of a function with missing Google style parameter + documentation in the docstring + """ + node = astroid.extract_node(""" + def function_foo(x, y, z): + '''docstring ... + + Args: + x: bla + z (int): bar + + some other stuff + ''' + pass + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('y',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)) + ): + self.checker.visit_functiondef(node) + + def test_missing_func_params_with_annotations_in_google_docstring(self): + """Example of a function with missing Google style parameter + documentation in the docstring. + """ + node = astroid.extract_node(""" + def function_foo(x: int, y: bool, z): + '''docstring ... + + Args: + x: bla + y: blah blah + z (int): bar + + some other stuff + ''' + pass + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_default_arg_with_annotations_in_google_docstring(self): + """Example of a function with missing Google style parameter + documentation in the docstring. + """ + node = astroid.extract_node(""" + def function_foo(x: int, y: bool, z: int = 786): + '''docstring ... + + Args: + x: bla + y: blah blah + z: bar + + some other stuff + ''' + pass + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_missing_func_params_with_partial_annotations_in_google_docstring(self): + """Example of a function with missing Google style parameter + documentation in the docstring. + """ + node = astroid.extract_node(""" + def function_foo(x, y: bool, z): + '''docstring ... + + Args: + x: bla + y: blah blah + z (int): bar + + some other stuff + ''' + pass + """) + with self.assertAddsMessages( + Message( + msg_id='missing-type-doc', + node=node, + args=('x',)) + ): + self.checker.visit_functiondef(node) + + def test_non_builtin_annotations_in_google_docstring(self): + """Example of a function with missing Google style parameter + documentation in the docstring. + """ + node = astroid.extract_node(""" + def area(bottomleft: Point, topright: Point) -> float: + '''Calculate area of fake rectangle. + Args: + bottomleft: bottom left point of rectangle + topright: top right point of rectangle + ''' + pass + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_non_builtin_annotations_for_returntype_in_google_docstring(self): + """Example of a function with missing Google style parameter + documentation in the docstring. + """ + node = astroid.extract_node(""" + def get_midpoint(bottomleft: Point, topright: Point) -> Point: + '''Calculate midpoint of fake rectangle. + Args: + bottomleft: bottom left point of rectangle + topright: top right point of rectangle + ''' + pass + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_func_params_and_keyword_params_in_google_docstring(self): + """Example of a function with Google style parameter splitted + in Args and Keyword Args in the docstring + """ + node = astroid.extract_node(""" + def my_func(this, other, that=True): + '''Prints this, other and that + + Args: + this (str): Printed first + other (int): Other args + + Keyword Args: + that (bool): Printed second + ''' + print(this, that, other) + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_func_params_and_wrong_keyword_params_in_google_docstring(self): + """Example of a function with Google style parameter splitted + in Args and Keyword Args in the docstring but with wrong keyword args + """ + node = astroid.extract_node(""" + def my_func(this, other, that=True): + '''Prints this, other and that + + Args: + this (str): Printed first + other (int): Other args + + Keyword Args: + these (bool): Printed second + ''' + print(this, that, other) + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('that',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('that',)), + Message( + msg_id='differing-param-doc', + node=node, + args=('these',)), + Message( + msg_id='differing-type-doc', + node=node, + args=('these',)) + ): + self.checker.visit_functiondef(node) + + def test_missing_func_params_in_numpy_docstring(self): + """Example of a function with missing NumPy style parameter + documentation in the docstring + """ + node = astroid.extract_node(""" + def function_foo(x, y, z): + '''docstring ... + + Parameters + ---------- + x: + bla + z: int + bar + + some other stuff + ''' + pass + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('y',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)) + ): + self.checker.visit_functiondef(node) + + @set_config(accept_no_param_doc=True) + def test_tolerate_no_param_documentation_at_all(self): + """Example of a function with no parameter documentation at all + + No error message is emitted. + """ + node = astroid.extract_node(""" + def function_foo(x, y): + '''docstring ... + + missing parameter documentation''' + pass + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_don_t_tolerate_no_param_documentation_at_all(self): + """Example of a function with no parameter documentation at all + + Missing documentation error message is emitted. + """ + node = astroid.extract_node(""" + def function_foo(x, y): + '''docstring ... + + missing parameter documentation''' + pass + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('x, y',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)) + ): + self.checker.visit_functiondef(node) + + def test_see_tolerate_no_param_documentation_at_all(self): + """Example for the usage of "For the parameters, see" + to suppress missing-param warnings. + """ + node = astroid.extract_node(""" + def function_foo(x, y): + '''docstring ... + + For the parameters, see :func:`blah` + ''' + pass + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def _visit_methods_of_class(self, node): + """Visit all methods of a class node + + :param node: class node + :type node: :class:`astroid.scoped_nodes.Class` + """ + for body_item in node.body: + if (isinstance(body_item, astroid.FunctionDef) + and hasattr(body_item, 'name')): + self.checker.visit_functiondef(body_item) + + def test_missing_method_params_in_sphinx_docstring(self): + """Example of a class method with missing parameter documentation in + the Sphinx style docstring + """ + node = astroid.extract_node(""" + class Foo(object): + def method_foo(self, x, y): + '''docstring ... + + missing parameter documentation + + :param x: bla + ''' + pass + """) + method_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=method_node, + args=('y',)), + Message( + msg_id='missing-type-doc', + node=method_node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_missing_method_params_in_google_docstring(self): + """Example of a class method with missing parameter documentation in + the Google style docstring + """ + node = astroid.extract_node(""" + class Foo(object): + def method_foo(self, x, y): + '''docstring ... + + missing parameter documentation + + Args: + x: bla + ''' + pass + """) + method_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=method_node, + args=('y',)), + Message( + msg_id='missing-type-doc', + node=method_node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_missing_method_params_in_numpy_docstring(self): + """Example of a class method with missing parameter documentation in + the Numpy style docstring + """ + node = astroid.extract_node(""" + class Foo(object): + def method_foo(self, x, y): + '''docstring ... + + missing parameter documentation + + Parameters + ---------- + x: + bla + ''' + pass + """) + method_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=method_node, + args=('y',)), + Message( + msg_id='missing-type-doc', + node=method_node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_existing_func_params_in_sphinx_docstring(self): + """Example of a function with correctly documented parameters and + return values (Sphinx style) + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg, zarg, warg): + '''function foo ... + + :param xarg: bla xarg + :type xarg: int + + :parameter yarg: bla yarg + :type yarg: my.qualified.type + + :arg int zarg: bla zarg + + :keyword my.qualified.type warg: bla warg + + :return: sum + :rtype: float + ''' + return xarg + yarg + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_existing_func_params_in_google_docstring(self): + """Example of a function with correctly documented parameters and + return values (Google style) + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg, zarg, warg): + '''function foo ... + + Args: + xarg (int): bla xarg + yarg (my.qualified.type): bla + bla yarg + + zarg (int): bla zarg + warg (my.qualified.type): bla warg + + Returns: + float: sum + ''' + return xarg + yarg + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_existing_func_params_in_numpy_docstring(self): + """Example of a function with correctly documented parameters and + return values (Numpy style) + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg, zarg, warg): + '''function foo ... + + Parameters + ---------- + xarg: int + bla xarg + yarg: my.qualified.type + bla yarg + + zarg: int + bla zarg + warg: my.qualified.type + bla warg + + Returns + ------- + float + sum + ''' + return xarg + yarg + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_wrong_name_of_func_params_in_sphinx_docstring(self): + """Example of functions with inconsistent parameter names in the + signature and in the Sphinx style documentation + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg, zarg): + '''function foo ... + + :param xarg1: bla xarg + :type xarg: int + + :param yarg: bla yarg + :type yarg1: float + + :param str zarg1: bla zarg + ''' + return xarg + yarg + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('xarg, zarg',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('yarg, zarg',)), + Message( + msg_id='differing-param-doc', + node=node, + args=('xarg1, zarg1',)), + Message( + msg_id='differing-type-doc', + node=node, + args=('yarg1, zarg1',)), + ): + self.checker.visit_functiondef(node) + + node = astroid.extract_node(""" + def function_foo(xarg, yarg): + '''function foo ... + + :param yarg1: bla yarg + :type yarg1: float + + For the other parameters, see bla. + ''' + return xarg + yarg + """) + with self.assertAddsMessages( + Message( + msg_id='differing-param-doc', + node=node, + args=('yarg1',)), + Message( + msg_id='differing-type-doc', + node=node, + args=('yarg1',)), + ): + self.checker.visit_functiondef(node) + + def test_wrong_name_of_func_params_in_google_docstring(self): + """Example of functions with inconsistent parameter names in the + signature and in the Google style documentation + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg, zarg): + '''function foo ... + + Args: + xarg1 (int): bla xarg + yarg (float): bla yarg + + zarg1 (str): bla zarg + ''' + return xarg + yarg + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('xarg, zarg',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('xarg, zarg',)), + Message( + msg_id='differing-param-doc', + node=node, + args=('xarg1, zarg1',)), + Message( + msg_id='differing-type-doc', + node=node, + args=('xarg1, zarg1',)), + ): + self.checker.visit_functiondef(node) + + node = astroid.extract_node(""" + def function_foo(xarg, yarg): + '''function foo ... + + Args: + yarg1 (float): bla yarg + + For the other parameters, see bla. + ''' + return xarg + yarg + """) + with self.assertAddsMessages( + Message( + msg_id='differing-param-doc', + node=node, + args=('yarg1',)), + Message( + msg_id='differing-type-doc', + node=node, + args=('yarg1',)) + ): + self.checker.visit_functiondef(node) + + def test_wrong_name_of_func_params_in_numpy_docstring(self): + """Example of functions with inconsistent parameter names in the + signature and in the Numpy style documentation + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg, zarg): + '''function foo ... + + Parameters + ---------- + xarg1: int + bla xarg + yarg: float + bla yarg + + zarg1: str + bla zarg + ''' + return xarg + yarg + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('xarg, zarg',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('xarg, zarg',)), + Message( + msg_id='differing-param-doc', + node=node, + args=('xarg1, zarg1',)), + Message( + msg_id='differing-type-doc', + node=node, + args=('xarg1, zarg1',)), + ): + self.checker.visit_functiondef(node) + + node = astroid.extract_node(""" + def function_foo(xarg, yarg): + '''function foo ... + + Parameters + ---------- + yarg1: float + bla yarg + + For the other parameters, see bla. + ''' + return xarg + yarg + """) + with self.assertAddsMessages( + Message( + msg_id='differing-param-doc', + node=node, + args=('yarg1',)), + Message( + msg_id='differing-type-doc', + node=node, + args=('yarg1',)) + ): + self.checker.visit_functiondef(node) + + def test_see_sentence_for_func_params_in_sphinx_docstring(self): + """Example for the usage of "For the other parameters, see" to avoid + too many repetitions, e.g. in functions or methods adhering to a + given interface (Sphinx style) + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg): + '''function foo ... + + :param yarg: bla yarg + :type yarg: float + + For the other parameters, see :func:`bla` + ''' + return xarg + yarg + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_see_sentence_for_func_params_in_google_docstring(self): + """Example for the usage of "For the other parameters, see" to avoid + too many repetitions, e.g. in functions or methods adhering to a + given interface (Google style) + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg): + '''function foo ... + + Args: + yarg (float): bla yarg + + For the other parameters, see :func:`bla` + ''' + return xarg + yarg + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_see_sentence_for_func_params_in_numpy_docstring(self): + """Example for the usage of "For the other parameters, see" to avoid + too many repetitions, e.g. in functions or methods adhering to a + given interface (Numpy style) + """ + node = astroid.extract_node(""" + def function_foo(xarg, yarg): + '''function foo ... + + Parameters + ---------- + yarg: float + bla yarg + + For the other parameters, see :func:`bla` + ''' + return xarg + yarg + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_constr_params_in_class_sphinx(self): + """Example of a class with missing constructor parameter documentation + (Sphinx style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + '''docstring foo + + :param y: bla + + missing constructor parameter documentation + ''' + + def __init__(self, x, y): + pass + + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_constr_params_in_class_google(self): + """Example of a class with missing constructor parameter documentation + (Google style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + '''docstring foo + + Args: + y: bla + + missing constructor parameter documentation + ''' + + def __init__(self, x, y): + pass + + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_constr_params_in_class_numpy(self): + """Example of a class with missing constructor parameter documentation + (Numpy style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + '''docstring foo + + Parameters + ---------- + y: + bla + + missing constructor parameter documentation + ''' + + def __init__(self, x, y): + pass + + """) + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_constr_params_and_attributes_in_class_numpy(self): + """Example of a class with correct constructor parameter documentation + and an attributes section (Numpy style) + """ + node = astroid.extract_node(""" + class ClassFoo(object): + ''' + Parameters + ---------- + foo : str + Something. + + Attributes + ---------- + bar : str + Something. + ''' + def __init__(self, foo): + self.bar = None + """) + with self.assertNoMessages(): + self._visit_methods_of_class(node) + + def test_constr_params_in_init_sphinx(self): + """Example of a class with missing constructor parameter documentation + (Sphinx style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + def __init__(self, x, y): + '''docstring foo constructor + + :param y: bla + + missing constructor parameter documentation + ''' + + pass + + """) + constructor_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=constructor_node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=constructor_node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_constr_params_in_init_google(self): + """Example of a class with missing constructor parameter documentation + (Google style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + def __init__(self, x, y): + '''docstring foo constructor + + Args: + y: bla + + missing constructor parameter documentation + ''' + pass + + """) + constructor_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=constructor_node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=constructor_node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_constr_params_in_init_numpy(self): + """Example of a class with missing constructor parameter documentation + (Numpy style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + def __init__(self, x, y): + '''docstring foo constructor + + Parameters + ---------- + y: + bla + + missing constructor parameter documentation + ''' + pass + + """) + constructor_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=constructor_node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=constructor_node, + args=('x, y',)) + ): + self._visit_methods_of_class(node) + + def test_see_sentence_for_constr_params_in_class(self): + """Example usage of "For the parameters, see" in class docstring""" + node = astroid.extract_node(""" + class ClassFoo(object): + '''docstring foo + + For the parameters, see :func:`bla` + ''' + + def __init__(self, x, y): + '''init''' + pass + + """) + with self.assertNoMessages(): + self._visit_methods_of_class(node) + + def test_see_sentence_for_constr_params_in_init(self): + """Example usage of "For the parameters, see" in init docstring""" + node = astroid.extract_node(""" + class ClassFoo(object): + '''foo''' + + def __init__(self, x, y): + '''docstring foo constructor + + For the parameters, see :func:`bla` + ''' + pass + + """) + with self.assertNoMessages(): + self._visit_methods_of_class(node) + + + def test_constr_params_in_class_and_init_sphinx(self): + """Example of a class with missing constructor parameter documentation + in both the init docstring and the class docstring + (Sphinx style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + '''docstring foo + + :param y: None + + missing constructor parameter documentation + ''' + + def __init__(self, x, y): + '''docstring foo + + :param y: bla + + missing constructor parameter documentation + ''' + pass + + """) + constructor_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='multiple-constructor-doc', + node=node, + args=(node.name,)), + Message( + msg_id='missing-param-doc', + node=node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)), + Message( + msg_id='missing-param-doc', + node=constructor_node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=constructor_node, + args=('x, y',)), + ): + self._visit_methods_of_class(node) + + def test_constr_params_in_class_and_init_google(self): + """Example of a class with missing constructor parameter documentation + in both the init docstring and the class docstring + (Google style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + '''docstring foo + + Args: + y: bla + + missing constructor parameter documentation + ''' + + def __init__(self, x, y): + '''docstring foo + + Args: + y: bla + + missing constructor parameter documentation + ''' + pass + + """) + constructor_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='multiple-constructor-doc', + node=node, + args=(node.name,)), + Message( + msg_id='missing-param-doc', + node=node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)), + Message( + msg_id='missing-param-doc', + node=constructor_node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=constructor_node, + args=('x, y',)), + ): + self._visit_methods_of_class(node) + + def test_constr_params_in_class_and_init_numpy(self): + """Example of a class with missing constructor parameter documentation + in both the init docstring and the class docstring + (Numpy style) + + Everything is completely analogous to functions. + """ + node = astroid.extract_node(""" + class ClassFoo(object): + '''docstring foo + + Parameters + ---------- + y: + bla + + missing constructor parameter documentation + ''' + + def __init__(self, x, y): + '''docstring foo + + Parameters + ---------- + y: + bla + + missing constructor parameter documentation + ''' + pass + + """) + constructor_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='multiple-constructor-doc', + node=node, + args=(node.name,)), + Message( + msg_id='missing-param-doc', + node=node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=node, + args=('x, y',)), + Message( + msg_id='missing-param-doc', + node=constructor_node, + args=('x',)), + Message( + msg_id='missing-type-doc', + node=constructor_node, + args=('x, y',)), + ): + self._visit_methods_of_class(node) + + @pytest.mark.skipif(sys.version_info[0] != 3, reason="Enabled on Python 3") + def test_kwonlyargs_are_taken_in_account(self): + node = astroid.extract_node(''' + def my_func(arg, *, kwonly, missing_kwonly): + """The docstring + + :param int arg: The argument. + :param bool kwonly: A keyword-arg. + """ + ''') + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('missing_kwonly', )), + Message( + msg_id='missing-type-doc', + node=node, + args=('missing_kwonly', ))): + self.checker.visit_functiondef(node) + + def test_warns_missing_args_sphinx(self): + node = astroid.extract_node(''' + def my_func(named_arg, *args): + """The docstring + + :param named_arg: Returned + :type named_arg: object + :returns: Maybe named_arg + :rtype: object or None + """ + if args: + return named_arg + ''') + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('args',))): + self.checker.visit_functiondef(node) + + def test_warns_missing_kwargs_sphinx(self): + node = astroid.extract_node(''' + def my_func(named_arg, **kwargs): + """The docstring + + :param named_arg: Returned + :type named_arg: object + :returns: Maybe named_arg + :rtype: object or None + """ + if kwargs: + return named_arg + ''') + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('kwargs',))): + self.checker.visit_functiondef(node) + + def test_warns_missing_args_google(self): + node = astroid.extract_node(''' + def my_func(named_arg, *args): + """The docstring + + Args: + named_arg (object): Returned + + Returns: + object or None: Maybe named_arg + """ + if args: + return named_arg + ''') + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('args',))): + self.checker.visit_functiondef(node) + + def test_warns_missing_kwargs_google(self): + node = astroid.extract_node(''' + def my_func(named_arg, **kwargs): + """The docstring + + Args: + named_arg (object): Returned + + Returns: + object or None: Maybe named_arg + """ + if kwargs: + return named_arg + ''') + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('kwargs',))): + self.checker.visit_functiondef(node) + + def test_warns_missing_args_numpy(self): + node = astroid.extract_node(''' + def my_func(named_arg, *args): + """The docstring + + Args + ---- + named_arg : object + Returned + + Returns + ------- + object or None + Maybe named_arg + """ + if args: + return named_arg + ''') + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('args',))): + self.checker.visit_functiondef(node) + + def test_warns_missing_kwargs_numpy(self): + node = astroid.extract_node(''' + def my_func(named_arg, **kwargs): + """The docstring + + Args + ---- + named_arg : object + Returned + + Returns + ------- + object or None + Maybe named_arg + """ + if kwargs: + return named_arg + ''') + with self.assertAddsMessages( + Message( + msg_id='missing-param-doc', + node=node, + args=('kwargs',))): + self.checker.visit_functiondef(node) + + def test_finds_args_without_type_sphinx(self): + node = astroid.extract_node(''' + def my_func(named_arg, *args): + """The docstring + + :param named_arg: Returned + :type named_arg: object + :param args: Optional arguments + :returns: Maybe named_arg + :rtype: object or None + """ + if args: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_kwargs_without_type_sphinx(self): + node = astroid.extract_node(''' + def my_func(named_arg, **kwargs): + """The docstring + + :param named_arg: Returned + :type named_arg: object + :param kwargs: Keyword arguments + :returns: Maybe named_arg + :rtype: object or None + """ + if kwargs: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_args_without_type_google(self): + node = astroid.extract_node(''' + def my_func(named_arg, *args): + """The docstring + + Args: + named_arg (object): Returned + *args: Optional arguments + + Returns: + object or None: Maybe named_arg + """ + if args: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_kwargs_without_type_google(self): + node = astroid.extract_node(''' + def my_func(named_arg, **kwargs): + """The docstring + + Args: + named_arg (object): Returned + **kwargs: Keyword arguments + + Returns: + object or None: Maybe named_arg + """ + if kwargs: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_args_without_type_numpy(self): + node = astroid.extract_node(''' + def my_func(named_arg, *args): + """The docstring + + Args + ---- + named_arg : object + Returned + args : + Optional Arguments + + Returns + ------- + object or None + Maybe named_arg + """ + if args: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_args_with_xref_type_google(self): + node = astroid.extract_node(''' + def my_func(named_arg, **kwargs): + """The docstring + + Args: + named_arg (`example.value`): Returned + **kwargs: Keyword arguments + + Returns: + `example.value`: Maybe named_arg + """ + if kwargs: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_args_with_xref_type_numpy(self): + node = astroid.extract_node(''' + def my_func(named_arg, *args): + """The docstring + + Args + ---- + named_arg : `example.value` + Returned + args : + Optional Arguments + + Returns + ------- + `example.value` + Maybe named_arg + """ + if args: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_kwargs_without_type_numpy(self): + node = astroid.extract_node(''' + def my_func(named_arg, **kwargs): + """The docstring + + Args + ---- + named_arg : object + Returned + kwargs : + Keyword arguments + + Returns + ------- + object or None + Maybe named_arg + """ + if kwargs: + return named_arg + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + CONTAINER_TYPES = [ + 'dict(str,str)', + 'dict[str,str]', + 'tuple(int)', + 'list[tokenize.TokenInfo]', + ] + + COMPLEX_TYPES = CONTAINER_TYPES + [ + 'dict(str, str)', + 'dict[str, str]', + 'int or str', + 'tuple(int or str)', + 'tuple(int) or list(int)', + 'tuple(int or str) or list(int or str)', + ] + + @pytest.mark.parametrize('complex_type', COMPLEX_TYPES) + def test_finds_multiple_types_sphinx(self, complex_type): + node = astroid.extract_node(''' + def my_func(named_arg): + """The docstring + + :param named_arg: Returned + :type named_arg: {0} + + :returns: named_arg + :rtype: {0} + """ + return named_arg + '''.format(complex_type)) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + @pytest.mark.parametrize('complex_type', COMPLEX_TYPES) + def test_finds_multiple_types_google(self, complex_type): + node = astroid.extract_node(''' + def my_func(named_arg): + """The docstring + + Args: + named_arg ({0}): Returned + + Returns: + {0}: named_arg + """ + return named_arg + '''.format(complex_type)) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + @pytest.mark.parametrize('complex_type', COMPLEX_TYPES) + def test_finds_multiple_types_numpy(self, complex_type): + node = astroid.extract_node(''' + def my_func(named_arg): + """The docstring + + Args + ---- + named_arg : {0} + Returned + + Returns + ------- + {0} + named_arg + """ + return named_arg + '''.format(complex_type)) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + @pytest.mark.parametrize('container_type', CONTAINER_TYPES) + def test_finds_compact_container_types_sphinx(self, container_type): + node = astroid.extract_node(''' + def my_func(named_arg): + """The docstring + + :param {0} named_arg: Returned + + :returns: named_arg + :rtype: {0} + """ + return named_arg + '''.format(container_type)) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_optional_specifier_google(self): + node = astroid.extract_node(''' + def do_something(param1, param2, param3=(), param4=[], param5=[], param6=True): + """Do something. + + Args: + param1 (str): Description. + param2 (dict(str, int)): Description. + param3 (tuple(str), optional): Defaults to empty. Description. + param4 (List[str], optional): Defaults to empty. Description. + param5 (list[tuple(str)], optional): Defaults to empty. Description. + param6 (bool, optional): Defaults to True. Description. + + Returns: + int: Description. + """ + return param1, param2, param3, param4, param5, param6 + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_optional_specifier_numpy(self): + node = astroid.extract_node(''' + def do_something(param, param2='all'): + """Do something. + + Parameters + ---------- + param : str + Description. + param2 : str, optional + Description (the default is 'all'). + + Returns + ------- + int + Description. + """ + return param, param2 + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_short_name_exception(self): + node = astroid.extract_node(''' + from fake_package import BadError + + def do_something(): #@ + """Do something. + + Raises: + ~fake_package.exceptions.BadError: When something bad happened. + """ + raise BadError("A bad thing happened.") + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_missing_raises_from_setter_sphinx(self): + """Example of a setter having missing raises documentation in + the Sphinx style docstring of the property + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''docstring ... + + :type: int + ''' + return 10 + + @foo.setter + def foo(self, value): + raise AttributeError() #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=property_node, + args=('AttributeError',)), + ): + self.checker.visit_raise(node) + + def test_finds_missing_raises_from_setter_google(self): + """Example of a setter having missing raises documentation in + the Google style docstring of the property + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''int: docstring + + Include a "Raises" section so that this is identified + as a Google docstring and not a Numpy docstring. + + Raises: + RuntimeError: Always + ''' + raise RuntimeError() + return 10 + + @foo.setter + def foo(self, value): + raises AttributeError() #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=property_node, + args=('AttributeError',)), + ): + self.checker.visit_raise(node) + + def test_finds_missing_raises_from_setter_numpy(self): + """Example of a setter having missing raises documentation in + the Numpy style docstring of the property + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''int: docstring + + Include a "Raises" section so that this is identified + as a Numpy docstring and not a Google docstring. + + Raises + ------ + RuntimeError + Always + ''' + raise RuntimeError() + return 10 + + @foo.setter + def foo(self, value): + raises AttributeError() #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=property_node, + args=('AttributeError',)), + ): + self.checker.visit_raise(node) + + def test_finds_missing_raises_in_setter_sphinx(self): + """Example of a setter having missing raises documentation in + its own Sphinx style docstring + """ + setter_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): + '''docstring ... + + :type: int + :raises RuntimeError: Always + ''' + raise RuntimeError() + return 10 + + @foo.setter + def foo(self, value): #@ + '''setter docstring ... + + :type: None + ''' + raise AttributeError() #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=setter_node, + args=('AttributeError',)), + ): + self.checker.visit_raise(node) + + def test_finds_missing_raises_from_setter_google(self): + """Example of a setter having missing raises documentation in + its own Google style docstring of the property + """ + setter_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): + '''int: docstring ... + + Raises: + RuntimeError: Always + ''' + raise RuntimeError() + return 10 + + @foo.setter + def foo(self, value): #@ + '''setter docstring ... + + Raises: + RuntimeError: Never + ''' + if True: + raise AttributeError() #@ + raise RuntimeError() + """) + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=setter_node, + args=('AttributeError',)), + ): + self.checker.visit_raise(node) + + def test_finds_missing_raises_from_setter_numpy(self): + """Example of a setter having missing raises documentation in + its own Numpy style docstring of the property + """ + setter_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): + '''int: docstring ... + + Raises + ------ + RuntimeError + Always + ''' + raise RuntimeError() + return 10 + + @foo.setter + def foo(self, value): #@ + '''setter docstring ... + + Raises + ------ + RuntimeError + Never + ''' + if True: + raise AttributeError() #@ + raise RuntimeError() + """) + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=setter_node, + args=('AttributeError',)), + ): + self.checker.visit_raise(node) + + def test_finds_property_return_type_sphinx(self): + """Example of a property having return documentation in + a Sphinx style docstring + """ + node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''docstring ... + + :type: int + ''' + return 10 + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_property_return_type_google(self): + """Example of a property having return documentation in + a Google style docstring + """ + node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''int: docstring ... + + Raises: + RuntimeError: Always + ''' + raise RuntimeError() + return 10 + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_property_return_type_numpy(self): + """Example of a property having return documentation in + a numpy style docstring + """ + node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''int: docstring ... + + Raises + ------ + RuntimeError + Always + ''' + raise RuntimeError() + return 10 + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_finds_annotation_property_return_type_sphinx(self): + """Example of a property having missing return documentation in + a Sphinx style docstring + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self) -> int: #@ + '''docstring ... + + :raises RuntimeError: Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertNoMessages(): + self.checker.visit_return(node) + + def test_finds_missing_property_return_type_sphinx(self): + """Example of a property having missing return documentation in + a Sphinx style docstring + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''docstring ... + + :raises RuntimeError: Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-return-type-doc', + node=property_node), + ): + self.checker.visit_return(node) + + def test_finds_annotation_property_return_type_google(self): + """Example of a property having return documentation in + a Google style docstring + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self) -> int: #@ + '''docstring ... + + Raises: + RuntimeError: Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertNoMessages(): + self.checker.visit_return(node) + + def test_finds_missing_property_return_type_google(self): + """Example of a property having return documentation in + a Google style docstring + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''docstring ... + + Raises: + RuntimeError: Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-return-type-doc', + node=property_node), + ): + self.checker.visit_return(node) + + def test_finds_missing_property_return_type_numpy(self): + """Example of a property having return documentation in + a numpy style docstring + """ + property_node, node = astroid.extract_node(""" + class Foo(object): + @property + def foo(self): #@ + '''docstring ... + + Raises + ------ + RuntimeError + Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-return-type-doc', + node=property_node), + ): + self.checker.visit_return(node) + + def test_ignores_non_property_return_type_sphinx(self): + """Example of a class function trying to use `type` as return + documentation in a Sphinx style docstring + """ + func_node, node = astroid.extract_node(""" + class Foo(object): + def foo(self): #@ + '''docstring ... + + :type: int + ''' + return 10 #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-return-doc', + node=func_node), + Message( + msg_id='missing-return-type-doc', + node=func_node), + ): + self.checker.visit_return(node) + + def test_ignores_non_property_return_type_google(self): + """Example of a class function trying to use `type` as return + documentation in a Google style docstring + """ + func_node, node = astroid.extract_node(""" + class Foo(object): + def foo(self): #@ + '''int: docstring ... + + Raises: + RuntimeError: Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-return-doc', + node=func_node), + Message( + msg_id='missing-return-type-doc', + node=func_node), + ): + self.checker.visit_return(node) + + def test_ignores_non_property_return_type_numpy(self): + """Example of a class function trying to use `type` as return + documentation in a numpy style docstring + """ + func_node, node = astroid.extract_node(""" + class Foo(object): + def foo(self): #@ + '''int: docstring ... + + Raises + ------ + RuntimeError + Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-return-doc', + node=func_node), + Message( + msg_id='missing-return-type-doc', + node=func_node), + ): + self.checker.visit_return(node) + + def test_non_property_annotation_return_type_numpy(self): + """Example of a class function trying to use `type` as return + documentation in a numpy style docstring + """ + func_node, node = astroid.extract_node(""" + class Foo(object): + def foo(self) -> int: #@ + '''int: docstring ... + + Raises + ------ + RuntimeError + Always + ''' + raise RuntimeError() + return 10 #@ + """) + with self.assertAddsMessages( + Message( + msg_id='missing-return-doc', + node=func_node), + ): + self.checker.visit_return(node) + + def test_ignores_return_in_abstract_method_sphinx(self): + """Example of an abstract method documenting the return type that an + implementation should return. + """ + node = astroid.extract_node(""" + import abc + class Foo(object): + @abc.abstractmethod + def foo(self): #@ + '''docstring ... + + :returns: Ten + :rtype: int + ''' + return 10 + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_return_in_abstract_method_google(self): + """Example of an abstract method documenting the return type that an + implementation should return. + """ + node = astroid.extract_node(""" + import abc + class Foo(object): + @abc.abstractmethod + def foo(self): #@ + '''docstring ... + + Returns: + int: Ten + ''' + return 10 + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_return_in_abstract_method_numpy(self): + """Example of an abstract method documenting the return type that an + implementation should return. + """ + node = astroid.extract_node(""" + import abc + class Foo(object): + @abc.abstractmethod + def foo(self): #@ + '''docstring ... + + Returns + ------- + int + Ten + ''' + return 10 + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_raise_notimplementederror_sphinx(self): + """Example of an abstract + """ + node = astroid.extract_node(""" + class Foo(object): + def foo(self, arg): #@ + '''docstring ... + + :param arg: An argument. + :type arg: int + ''' + raise NotImplementedError() + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_return_in_abstract_method_google(self): + """Example of a method documenting the return type that an + implementation should return. + """ + node = astroid.extract_node(""" + class Foo(object): + def foo(self, arg): #@ + '''docstring ... + + Args: + arg (int): An argument. + ''' + raise NotImplementedError() + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_return_in_abstract_method_numpy(self): + """Example of a method documenting the return type that an + implementation should return. + """ + node = astroid.extract_node(""" + class Foo(object): + def foo(self, arg): #@ + '''docstring ... + + Parameters + ---------- + arg : int + An argument. + ''' + raise NotImplementedError() + """) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_docs_utils.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_docs_utils.py new file mode 100644 index 0000000..28c9a05 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_docs_utils.py @@ -0,0 +1,112 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the pylint checkers in :mod:`pylint.extensions.check_docs`, +in particular the parameter documentation checker `DocstringChecker` +""" +from __future__ import division, print_function, absolute_import + +import pytest + +import astroid + +import pylint.extensions._check_docs_utils as utils + + +@pytest.mark.parametrize("string,count", [ + ('abc', 0), + ('', 0), + (' abc', 2), + ('\n abc', 0), + (' \n abc', 3), +]) +def test_space_indentation(string, count): + """Test for pylint_plugin.ParamDocChecker""" + assert utils.space_indentation(string) == count + + +@pytest.mark.parametrize("raise_node,expected", [ + (astroid.extract_node(''' + def my_func(): + raise NotImplementedError #@ + '''), {"NotImplementedError"}), + + (astroid.extract_node(''' + def my_func(): + raise NotImplementedError("Not implemented!") #@ + '''), {"NotImplementedError"}), + + (astroid.extract_node(''' + def my_func(): + try: + fake_func() + except RuntimeError: + raise #@ + '''), {"RuntimeError"}), + + (astroid.extract_node(''' + def my_func(): + try: + fake_func() + except RuntimeError: + if another_func(): + raise #@ + '''), {"RuntimeError"}), + + (astroid.extract_node(''' + def my_func(): + try: + fake_func() + except RuntimeError: + try: + another_func() + raise #@ + except NameError: + pass + '''), {"RuntimeError"}), + + (astroid.extract_node(''' + def my_func(): + try: + fake_func() + except RuntimeError: + try: + another_func() + except NameError: + raise #@ + '''), {"NameError"}), + + (astroid.extract_node(''' + def my_func(): + try: + fake_func() + except: + raise #@ + '''), set()), + + (astroid.extract_node(''' + def my_func(): + try: + fake_func() + except (RuntimeError, ValueError): + raise #@ + '''), {"RuntimeError", "ValueError"}), + + (astroid.extract_node(''' + import not_a_module + def my_func(): + try: + fake_func() + except not_a_module.Error: + raise #@ + '''), set()), + +]) +def test_exception(raise_node, expected): + found = utils.possible_exc_types(raise_node) + assert found == expected diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_mccabe.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_mccabe.py new file mode 100644 index 0000000..8ae42f5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_mccabe.py @@ -0,0 +1,63 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.check_mccabe +""" + +import os.path as osp + +import pytest + +from pylint.extensions import mccabe + +EXPECTED_MSGS = [ + "'f1' is too complex. The McCabe rating is 1", + "'f2' is too complex. The McCabe rating is 1", + "'f3' is too complex. The McCabe rating is 3", + "'f4' is too complex. The McCabe rating is 2", + "'f5' is too complex. The McCabe rating is 2", + "'f6' is too complex. The McCabe rating is 2", + "'f7' is too complex. The McCabe rating is 3", + "'f8' is too complex. The McCabe rating is 4", + "'f9' is too complex. The McCabe rating is 9", + "'method1' is too complex. The McCabe rating is 1", + "This 'for' is too complex. The McCabe rating is 4", + "'method3' is too complex. The McCabe rating is 2", + "'f10' is too complex. The McCabe rating is 11", + "'method2' is too complex. The McCabe rating is 18", +] + + +@pytest.fixture(scope="module") +def enable(enable): + return ['too-complex'] + + +@pytest.fixture(scope="module") +def disable(disable): + return ['all'] + + +@pytest.fixture(scope="module") +def register(register): + return mccabe.register + + +@pytest.fixture +def fname_mccabe_example(): + return osp.join(osp.dirname(osp.abspath(__file__)), 'data', 'mccabe.py') + + +@pytest.mark.parametrize("complexity, expected", [ + (0, EXPECTED_MSGS), + (9, EXPECTED_MSGS[-2:]), +]) +def test_max_mccabe_rate(linter, fname_mccabe_example, complexity, expected): + linter.global_set_option('max-complexity', complexity) + linter.check([fname_mccabe_example]) + real_msgs = [message.msg for message in linter.reporter.messages] + assert sorted(expected) == sorted(real_msgs) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_raise_docs.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_raise_docs.py new file mode 100644 index 0000000..5c7920d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_raise_docs.py @@ -0,0 +1,530 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2018 Adam Dangoor <adamdangoor@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the raised exception documentation checking in the +`DocstringChecker` in :mod:`pylint.extensions.check_docs` +""" +from __future__ import division, print_function, absolute_import + +import astroid +from pylint.testutils import CheckerTestCase, Message, set_config + +from pylint.extensions.docparams import DocstringParameterChecker + + +class TestDocstringCheckerRaise(CheckerTestCase): + """Tests for pylint_plugin.RaiseDocChecker""" + CHECKER_CLASS = DocstringParameterChecker + + def test_ignores_no_docstring(self): + raise_node = astroid.extract_node(''' + def my_func(self): + raise RuntimeError('hi') #@ + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_ignores_unknown_style(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring.""" + raise RuntimeError('hi') + ''') + raise_node = node.body[0] + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + @set_config(accept_no_raise_doc=False) + def test_warns_unknown_style(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring.""" + raise RuntimeError('hi') + ''') + raise_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_find_missing_sphinx_raises(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises NameError: Never + """ + raise RuntimeError('hi') + raise NameError('hi') + ''') + raise_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_find_missing_google_raises(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises: + NameError: Never + """ + raise RuntimeError('hi') + raise NameError('hi') + ''') + raise_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_find_missing_numpy_raises(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises + ------ + NameError + Never + """ + raise RuntimeError('hi') + raise NameError('hi') + ''') + raise_node = node.body[0] + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_ignore_spurious_sphinx_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises RuntimeError: Always + :except NameError: Never + :raise OSError: Never + :exception ValueError: Never + """ + raise RuntimeError('Blah') #@ + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_find_all_sphinx_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises RuntimeError: Always + :except NameError: Never + :raise OSError: Never + :exception ValueError: Never + """ + raise RuntimeError('hi') #@ + raise NameError('hi') + raise OSError(2, 'abort!') + raise ValueError('foo') + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_find_all_google_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises: + RuntimeError: Always + NameError: Never + """ + raise RuntimeError('hi') #@ + raise NameError('hi') + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_find_all_numpy_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises + ------ + RuntimeError + Always + NameError + Never + """ + raise RuntimeError('hi') #@ + raise NameError('hi') + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_finds_rethrown_sphinx_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises NameError: Sometimes + """ + try: + fake_func() + except RuntimeError: + raise #@ + + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_find_rethrown_google_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises: + NameError: Sometimes + """ + try: + fake_func() + except RuntimeError: + raise #@ + + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_find_rethrown_numpy_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises + ------ + NameError + Sometimes + """ + try: + fake_func() + except RuntimeError: + raise #@ + + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_finds_rethrown_sphinx_multiple_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises NameError: Sometimes + """ + try: + fake_func() + except (RuntimeError, ValueError): + raise #@ + + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError, ValueError', ))): + self.checker.visit_raise(raise_node) + + def test_find_rethrown_google_multiple_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises: + NameError: Sometimes + """ + try: + fake_func() + except (RuntimeError, ValueError): + raise #@ + + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError, ValueError', ))): + self.checker.visit_raise(raise_node) + + def test_find_rethrown_numpy_multiple_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises + ------ + NameError + Sometimes + """ + try: + fake_func() + except (RuntimeError, ValueError): + raise #@ + + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError, ValueError', ))): + self.checker.visit_raise(raise_node) + + def test_ignores_caught_sphinx_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises NameError: Sometimes + """ + try: + raise RuntimeError('hi') #@ + except RuntimeError: + pass + + raise NameError('hi') + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_ignores_caught_google_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises: + NameError: Sometimes + """ + try: + raise RuntimeError('hi') #@ + except RuntimeError: + pass + + raise NameError('hi') + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_ignores_caught_numpy_raises(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Raises + ------ + NameError + Sometimes + """ + try: + raise RuntimeError('hi') #@ + except RuntimeError: + pass + + raise NameError('hi') + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_find_missing_sphinx_raises_infer_from_instance(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises NameError: Never + """ + my_exception = RuntimeError('hi') + raise my_exception #@ + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_find_missing_sphinx_raises_infer_from_function(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises NameError: Never + """ + def ex_func(val): + return RuntimeError(val) + raise ex_func('hi') #@ + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + self.checker.visit_raise(raise_node) + + def test_ignores_raise_uninferable(self): + raise_node = astroid.extract_node(''' + from unknown import Unknown + + def my_func(self): + """This is a docstring. + + :raises NameError: Never + """ + raise Unknown('hi') #@ + raise NameError('hi') + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_ignores_returns_from_inner_functions(self): + raise_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :raises NameError: Never + """ + def ex_func(val): + def inner_func(value): + return OSError(value) + return RuntimeError(val) + raise ex_func('hi') #@ + raise NameError('hi') + ''') + node = raise_node.frame() + with self.assertAddsMessages( + Message( + msg_id='missing-raises-doc', + node=node, + args=('RuntimeError', ))): + # we do NOT expect a warning about the OSError in inner_func! + self.checker.visit_raise(raise_node) + + def test_ignores_returns_use_only_names(self): + raise_node = astroid.extract_node(''' + def myfunc(): + """This is a docstring + + :raises NameError: Never + """ + def inner_func(): + return 42 + + raise inner_func() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_ignores_returns_use_only_exception_instances(self): + raise_node = astroid.extract_node(''' + def myfunc(): + """This is a docstring + + :raises MyException: Never + """ + class MyException(Exception): + pass + def inner_func(): + return MyException + + raise inner_func() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_no_crash_when_inferring_handlers(self): + raise_node = astroid.extract_node(''' + import collections + + def test(): + """raises + + :raise U: pass + """ + try: + pass + except collections.U as exc: + raise #@ + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_no_crash_when_cant_find_exception(self): + raise_node = astroid.extract_node(''' + import collections + + def test(): + """raises + + :raise U: pass + """ + try: + pass + except U as exc: + raise #@ + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) + + def test_no_error_notimplemented_documented(self): + raise_node = astroid.extract_node(''' + def my_func(): + """ + Raises: + NotImplementedError: When called. + """ + raise NotImplementedError #@ + ''') + with self.assertNoMessages(): + self.checker.visit_raise(raise_node) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_return_docs.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_return_docs.py new file mode 100644 index 0000000..db44886 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_return_docs.py @@ -0,0 +1,600 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the return documentation checking in the +`DocstringChecker` in :mod:`pylint.extensions.check_docs` +""" +from __future__ import division, print_function, absolute_import + +import astroid +from pylint.testutils import CheckerTestCase, Message, set_config + +from pylint.extensions.docparams import DocstringParameterChecker + + +class TestDocstringCheckerReturn(CheckerTestCase): + """Tests for pylint_plugin.RaiseDocChecker""" + CHECKER_CLASS = DocstringParameterChecker + + def test_ignores_no_docstring(self): + return_node = astroid.extract_node(''' + def my_func(self): + return False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + @set_config(accept_no_return_doc=False) + def test_warns_no_docstring(self): + node = astroid.extract_node(''' + def my_func(self): + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node), + Message(msg_id='missing-return-type-doc', node=node)): + self.checker.visit_return(return_node) + + def test_ignores_unknown_style(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring.""" + return False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_warn_partial_sphinx_returns(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: Always False + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-type-doc', node=node)): + self.checker.visit_return(return_node) + + def test_sphinx_returns_annotations(self): + node = astroid.extract_node(''' + def my_func(self) -> bool: + """This is a docstring. + + :returns: Always False + """ + return False + ''') + return_node = node.body[0] + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_sphinx_missing_return_type_with_annotations(self): + node = astroid.extract_node(''' + def my_func(self) -> bool: + """This is a docstring. + + :returns: Always False + """ + return False + ''') + return_node = node.body[0] + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + + def test_warn_partial_sphinx_returns_type(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :rtype: bool + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warn_missing_sphinx_returns(self): + node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + :param doc_type: Sphinx + :type doc_type: str + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node), + Message(msg_id='missing-return-type-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warn_partial_google_returns(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + Always False + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-type-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warn_partial_google_returns_type(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + bool: + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warn_missing_google_returns(self): + node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + Parameters: + doc_type (str): Google + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node), + Message(msg_id='missing-return-type-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warn_partial_numpy_returns_type(self): + node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + Arguments + --------- + doc_type : str + Numpy + + Returns + ------- + bool + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warn_missing_numpy_returns(self): + node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + Arguments + --------- + doc_type : str + Numpy + """ + return False + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node), + Message(msg_id='missing-return-type-doc', node=node)): + self.checker.visit_return(return_node) + + def test_find_sphinx_returns(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :return: Always False + :rtype: bool + """ + return False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_find_google_returns(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + bool: Always False + """ + return False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_find_numpy_returns(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + bool + Always False + """ + return False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_ignores_sphinx_return_none(self): + return_node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + :param doc_type: Sphinx + :type doc_type: str + """ + return #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_ignores_google_return_none(self): + return_node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + Args: + doc_type (str): Google + """ + return #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_ignores_numpy_return_none(self): + return_node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + Arguments + --------- + doc_type : str + Numpy + """ + return #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_finds_sphinx_return_custom_class(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: An object + :rtype: :class:`mymodule.Class` + """ + return mymodule.Class() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_finds_google_return_custom_class(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + mymodule.Class: An object + """ + return mymodule.Class() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_finds_numpy_return_custom_class(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + mymodule.Class + An object + """ + return mymodule.Class() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_finds_sphinx_return_list_of_custom_class(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: An object + :rtype: list(:class:`mymodule.Class`) + """ + return [mymodule.Class()] #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_finds_google_return_list_of_custom_class(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + list(:class:`mymodule.Class`): An object + """ + return [mymodule.Class()] #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_finds_numpy_return_list_of_custom_class(self): + return_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + list(:class:`mymodule.Class`) + An object + """ + return [mymodule.Class()] #@ + ''') + with self.assertNoMessages(): + self.checker.visit_return(return_node) + + def test_warns_sphinx_return_list_of_custom_class_without_description(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :rtype: list(:class:`mymodule.Class`) + """ + return [mymodule.Class()] + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warns_google_return_list_of_custom_class_without_description(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + list(:class:`mymodule.Class`): + """ + return [mymodule.Class()] + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warns_numpy_return_list_of_custom_class_without_description(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + list(:class:`mymodule.Class`) + """ + return [mymodule.Class()] + ''') + return_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-return-doc', node=node)): + self.checker.visit_return(return_node) + + def test_warns_sphinx_redundant_return_doc(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: One + """ + return None + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_warns_sphinx_redundant_rtype_doc(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :rtype: int + """ + return None + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_warns_google_redundant_return_doc(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + One + """ + return None + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_warns_google_redundant_rtype_doc(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + int: + """ + return None + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_warns_numpy_redundant_return_doc(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + int + One + """ + return None + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_warns_numpy_redundant_rtype_doc(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + int + """ + return None + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_ignores_sphinx_redundant_return_doc_multiple_returns(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: One + :rtype: int + + :returns: None sometimes + :rtype: None + """ + if a_func(): + return None + return 1 + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_google_redundant_return_doc_multiple_returns(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + int or None: One, or sometimes None. + """ + if a_func(): + return None + return 1 + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_numpy_redundant_return_doc_multiple_returns(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + int + One + None + Sometimes + """ + if a_func(): + return None + return 1 + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignore_sphinx_redundant_return_doc_yield(self): + node = astroid.extract_node(''' + def my_func_with_yield(self): + """This is a docstring. + + :returns: One + :rtype: generator + """ + for value in range(3): + yield value + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_warns_google_redundant_return_doc_yield(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns: + int: One + """ + yield 1 + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_warns_numpy_redundant_return_doc_yield(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Returns + ------- + int + One + """ + yield 1 + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-returns-doc', node=node)): + self.checker.visit_functiondef(node) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_yields_docs.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_yields_docs.py new file mode 100644 index 0000000..0d800b7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_check_yields_docs.py @@ -0,0 +1,397 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the yield documentation checking in the +`DocstringChecker` in :mod:`pylint.extensions.check_docs` +""" +from __future__ import division, print_function, absolute_import + +import astroid +from pylint.testutils import CheckerTestCase, Message, set_config + +from pylint.extensions.docparams import DocstringParameterChecker + + +class TestDocstringCheckerYield(CheckerTestCase): + """Tests for pylint_plugin.RaiseDocChecker""" + CHECKER_CLASS = DocstringParameterChecker + + def test_ignores_no_docstring(self): + yield_node = astroid.extract_node(''' + def my_func(self): + yield False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + @set_config(accept_no_yields_doc=False) + def test_warns_no_docstring(self): + node = astroid.extract_node(''' + def my_func(self): + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node), + Message(msg_id='missing-yield-type-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_ignores_unknown_style(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring.""" + yield False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_warn_partial_sphinx_yields(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: Always False + """ + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-type-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warn_partial_sphinx_yields_type(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :rtype: bool + """ + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warn_missing_sphinx_yields(self): + node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + :param doc_type: Sphinx + :type doc_type: str + """ + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node), + Message(msg_id='missing-yield-type-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warn_partial_google_yields(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + Always False + """ + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-type-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warn_partial_google_yields_type(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + bool: + """ + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warn_missing_google_yields(self): + node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + Parameters: + doc_type (str): Google + """ + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node), + Message(msg_id='missing-yield-type-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warn_missing_numpy_yields(self): + node = astroid.extract_node(''' + def my_func(self, doc_type): + """This is a docstring. + + Arguments + --------- + doc_type : str + Numpy + """ + yield False + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node), + Message(msg_id='missing-yield-type-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_find_sphinx_yields(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :return: Always False + :rtype: bool + """ + yield False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_find_google_yields(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + bool: Always False + """ + yield False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_find_numpy_yields(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields + ------- + bool + Always False + """ + yield False #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_finds_sphinx_yield_custom_class(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: An object + :rtype: :class:`mymodule.Class` + """ + yield mymodule.Class() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_finds_google_yield_custom_class(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + mymodule.Class: An object + """ + yield mymodule.Class() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_finds_numpy_yield_custom_class(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields + ------- + mymodule.Class + An object + """ + yield mymodule.Class() #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_finds_sphinx_yield_list_of_custom_class(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :returns: An object + :rtype: list(:class:`mymodule.Class`) + """ + yield [mymodule.Class()] #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_finds_google_yield_list_of_custom_class(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + list(:class:`mymodule.Class`): An object + """ + yield [mymodule.Class()] #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_finds_numpy_yield_list_of_custom_class(self): + yield_node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields + ------- + list(:class:`mymodule.Class`) + An object + """ + yield [mymodule.Class()] #@ + ''') + with self.assertNoMessages(): + self.checker.visit_yield(yield_node) + + def test_warns_sphinx_yield_list_of_custom_class_without_description(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + :rtype: list(:class:`mymodule.Class`) + """ + yield [mymodule.Class()] + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warns_google_yield_list_of_custom_class_without_description(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + list(:class:`mymodule.Class`): + """ + yield [mymodule.Class()] + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node)): + self.checker.visit_yield(yield_node) + + def test_warns_numpy_yield_list_of_custom_class_without_description(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields + ------- + list(:class:`mymodule.Class`) + """ + yield [mymodule.Class()] + ''') + yield_node = node.body[0] + with self.assertAddsMessages( + Message(msg_id='missing-yield-doc', node=node)): + self.checker.visit_yield(yield_node) + + # No such thing as redundant yield documentation for sphinx because it + # doesn't support yield documentation + + def test_ignores_google_redundant_yield_doc_multiple_yields(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + int or None: One, or sometimes None. + """ + if a_func(): + yield None + yield 1 + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_ignores_numpy_redundant_yield_doc_multiple_yields(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields + ------- + int + One + None + Sometimes + """ + if a_func(): + yield None + yield 1 + ''') + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + # No such thing as redundant yield documentation for sphinx because it + # doesn't support yield documentation + + def test_warns_google_redundant_yield_doc_return(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields: + int: One + """ + return 1 + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-yields-doc', node=node)): + self.checker.visit_functiondef(node) + + def test_warns_numpy_redundant_yield_doc_return(self): + node = astroid.extract_node(''' + def my_func(self): + """This is a docstring. + + Yields + ------- + int + One + """ + return 1 + ''') + with self.assertAddsMessages( + Message(msg_id='redundant-yields-doc', node=node)): + self.checker.visit_functiondef(node) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_comparetozero.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_comparetozero.py new file mode 100644 index 0000000..efd206c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_comparetozero.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.emptystring +""" + +import os +import os.path as osp +import unittest + +from pylint import checkers +from pylint.extensions.comparetozero import CompareToZeroChecker +from pylint.lint import PyLinter +from pylint.reporters import BaseReporter + + +class CompareToZeroTestReporter(BaseReporter): + + def handle_message(self, msg): + self.messages.append(msg) + + def on_set_current_module(self, module, filepath): + self.messages = [] + + +class CompareToZeroUsedTC(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls._linter = PyLinter() + cls._linter.set_reporter(CompareToZeroTestReporter()) + checkers.initialize(cls._linter) + cls._linter.register_checker(CompareToZeroChecker(cls._linter)) + cls._linter.disable('I') + + def test_comparetozero_message(self): + elif_test = osp.join(osp.dirname(osp.abspath(__file__)), 'data', + 'compare_to_zero.py') + self._linter.check([elif_test]) + msgs = self._linter.reporter.messages + self.assertEqual(len(msgs), 6) + for msg in msgs: + self.assertEqual(msg.symbol, 'compare-to-zero') + self.assertEqual(msg.msg, 'Avoid comparisons to zero') + self.assertEqual(msgs[0].line, 6) + self.assertEqual(msgs[1].line, 9) + self.assertEqual(msgs[2].line, 12) + self.assertEqual(msgs[3].line, 15) + self.assertEqual(msgs[4].line, 18) + self.assertEqual(msgs[5].line, 24) + + +if __name__ == '__main__': + unittest.main() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_docstyle.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_docstyle.py new file mode 100644 index 0000000..7ced9a1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_docstyle.py @@ -0,0 +1,54 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Luis Escobar <lescobar@vauxoo.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.check_docstring +""" + +import os.path as osp + +import pytest + +from pylint.extensions.docstyle import DocStringStyleChecker + + +EXPECTED_MSGS = [ + 'First line empty in function docstring', + 'First line empty in class docstring', + 'First line empty in method docstring', + 'Bad docstring quotes in method, expected """, given \'\'\'', + 'Bad docstring quotes in method, expected """, given "', + 'Bad docstring quotes in method, expected """, given \'', + 'Bad docstring quotes in method, expected """, given \'', +] + +EXPECTED_SYMBOLS = [ + 'docstring-first-line-empty', + 'docstring-first-line-empty', + 'docstring-first-line-empty', + 'bad-docstring-quotes', + 'bad-docstring-quotes', + 'bad-docstring-quotes', + 'bad-docstring-quotes', +] + + +@pytest.fixture(scope="module") +def checker(checker): + return DocStringStyleChecker + + +def test_docstring_message(linter): + docstring_test = osp.join(osp.dirname(osp.abspath(__file__)), 'data', + 'docstring.py') + linter.check([docstring_test]) + msgs = linter.reporter.messages + assert len(msgs) == 7 + for msg, expected_symbol, expected_msg in zip(msgs, + EXPECTED_SYMBOLS, + EXPECTED_MSGS): + assert msg.symbol == expected_symbol + assert msg.msg == expected_msg diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_elseif_used.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_elseif_used.py new file mode 100644 index 0000000..4492668 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_elseif_used.py @@ -0,0 +1,33 @@ +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.check_elif +""" + +import os.path as osp + +import pytest + +from pylint.extensions.check_elif import ElseifUsedChecker + + +@pytest.fixture(scope="module") +def checker(checker): + return ElseifUsedChecker + + +def test_elseif_message(linter): + elif_test = osp.join(osp.dirname(osp.abspath(__file__)), 'data', + 'elif.py') + linter.check([elif_test]) + msgs = linter.reporter.messages + assert len(msgs) == 2 + for msg in msgs: + assert msg.symbol == 'else-if-used' + assert msg.msg == 'Consider using "elif" instead of "else if"' + assert msgs[0].line == 9 + assert msgs[1].line == 21 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_emptystring.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_emptystring.py new file mode 100644 index 0000000..c935b3b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_emptystring.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2017 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.emptystring +""" + +import os.path as osp +import pytest + +from pylint.extensions.emptystring import CompareToEmptyStringChecker + + +@pytest.fixture(scope='module') +def checker(checker): + return CompareToEmptyStringChecker + + +@pytest.fixture(scope='module') +def disable(disable): + return ['I'] + + +def test_emptystring_message(linter): + elif_test = osp.join(osp.dirname(osp.abspath(__file__)), 'data', + 'empty_string_comparison.py') + linter.check([elif_test]) + msgs = linter.reporter.messages + expected_lineno = [6, 9, 12, 15] + assert len(msgs) == len(expected_lineno) + for msg, lineno in zip(msgs, expected_lineno): + assert msg.symbol == 'compare-to-empty-string' + assert msg.msg == 'Avoid comparisons to empty string' + assert msg.line == lineno diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_overlapping_exceptions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_overlapping_exceptions.py new file mode 100644 index 0000000..44b9851 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_overlapping_exceptions.py @@ -0,0 +1,69 @@ +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.overlapping_exceptions +""" + +from sys import version_info +from os.path import join, dirname + +from pylint.extensions.overlapping_exceptions import OverlappingExceptionsChecker + +import pytest + + +@pytest.fixture(scope='module') +def checker(checker): + return OverlappingExceptionsChecker + + +@pytest.fixture(scope='module') +def disable(disable): + return ['I'] + + +def test_overlapping_exceptions(linter): + test = join(dirname(__file__), 'data', 'overlapping_exceptions.py') + linter.check([test]) + msgs = linter.reporter.messages + + expected = [ + (13, 'Overlapping exceptions (SomeException and SomeException are the same)'), + (18, 'Overlapping exceptions (SomeException is an ancestor class of SubclassException)'), + (23, 'Overlapping exceptions (SomeException and AliasException are the same)'), + (28, 'Overlapping exceptions (AliasException is an ancestor class of SubclassException)'), + (34, 'Overlapping exceptions (SomeException and AliasException are the same)'), + (34, 'Overlapping exceptions (SomeException is an ancestor class of SubclassException)'), + (34, 'Overlapping exceptions (AliasException is an ancestor class of SubclassException)'), + (39, 'Overlapping exceptions (ArithmeticError is an ancestor class of FloatingPointError)'), + (44, 'Overlapping exceptions (ValueError is an ancestor class of UnicodeDecodeError)') + ] + + assert len(msgs) == len(expected) + for msg, exp in zip(msgs, expected): + assert msg.msg_id == 'W0714' + assert msg.symbol == 'overlapping-except' + assert msg.category == 'warning' + assert (msg.line, msg.msg) == exp + + +@pytest.mark.skipif(version_info < (3, 3), + reason="not relevant to Python version") +def test_overlapping_exceptions_py33(linter): + """From Python 3.3 both IOError and socket.error are aliases for OSError.""" + test = join(dirname(__file__), 'data', 'overlapping_exceptions_py33.py') + linter.check([test]) + msgs = linter.reporter.messages + + expected = [ + (7, 'Overlapping exceptions (IOError and OSError are the same)'), + (12, 'Overlapping exceptions (socket.error and OSError are the same)'), + (17, 'Overlapping exceptions (socket.error is an ancestor class of ConnectionError)'), + ] + + assert len(msgs) == len(expected) + for msg, exp in zip(msgs, expected): + assert msg.msg_id == 'W0714' + assert msg.symbol == 'overlapping-except' + assert msg.category == 'warning' + assert (msg.line, msg.msg) == exp diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_redefined.py b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_redefined.py new file mode 100644 index 0000000..f4e2c79 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/extensions/test_redefined.py @@ -0,0 +1,50 @@ +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint checker in :mod:`pylint.extensions.check_elif +""" + +import os.path as osp + +import pytest + +from pylint.extensions.redefined_variable_type import MultipleTypesChecker +from pylint.lint import fix_import_path + + +EXPECTED = [ + 'Redefinition of self.var1 type from int to float', + 'Redefinition of var type from int to str', + 'Redefinition of myint type from int to bool', + 'Redefinition of _OK type from bool to str', + 'Redefinition of instance type from redefined.MyClass to bool', + 'Redefinition of SOME_FLOAT type from float to int', + 'Redefinition of var3 type from str to int', + 'Redefinition of var type from bool to int', + 'Redefinition of var4 type from float to str', +] + + +@pytest.fixture(scope="module") +def checker(checker): + return MultipleTypesChecker + + +@pytest.fixture(scope="module") +def disable(disable): + return ['I'] + + +def test_types_redefined(linter): + elif_test = osp.join(osp.dirname(osp.abspath(__file__)), 'data', + 'redefined.py') + with fix_import_path([elif_test]): + linter.check([elif_test]) + msgs = sorted(linter.reporter.messages, key=lambda item: item.line) + assert len(msgs) == 9 + for msg, expected in zip(msgs, EXPECTED): + assert msg.symbol == 'redefined-variable-type' + assert msg.msg == expected diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..385f37e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_abc_methods.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_abc_methods.cpython-37.pyc new file mode 100644 index 0000000..a4c39b2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_abc_methods.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_in_class.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_in_class.cpython-37.pyc new file mode 100644 index 0000000..1d4d9bc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_in_class.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py2.cpython-37.pyc new file mode 100644 index 0000000..1a3c94a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py3.cpython-37.pyc new file mode 100644 index 0000000..8b39e2e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py34.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py34.cpython-37.pyc new file mode 100644 index 0000000..51bc169 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_class_instantiated_py34.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_method_py2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_method_py2.cpython-37.pyc new file mode 100644 index 0000000..50abba1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_method_py2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_method_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_method_py3.cpython-37.pyc new file mode 100644 index 0000000..d8d84b9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/abstract_method_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_member_before_definition.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_member_before_definition.cpython-37.pyc new file mode 100644 index 0000000..a67655f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_member_before_definition.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_to__name__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_to__name__.cpython-37.pyc new file mode 100644 index 0000000..6dff0cd Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_to__name__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_to_protected_members.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_to_protected_members.cpython-37.pyc new file mode 100644 index 0000000..57d1081 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/access_to_protected_members.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/anomalous_unicode_escape_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/anomalous_unicode_escape_py3.cpython-37.pyc new file mode 100644 index 0000000..8d8dd25 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/anomalous_unicode_escape_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments.cpython-37.pyc new file mode 100644 index 0000000..229b266 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments_differ.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments_differ.cpython-37.pyc new file mode 100644 index 0000000..064c27f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments_differ.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments_differ_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments_differ_py3.cpython-37.pyc new file mode 100644 index 0000000..c029925 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/arguments_differ_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assert_on_tuple.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assert_on_tuple.cpython-37.pyc new file mode 100644 index 0000000..b44ae33 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assert_on_tuple.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assigning_non_slot.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assigning_non_slot.cpython-37.pyc new file mode 100644 index 0000000..68caf0a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assigning_non_slot.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return.cpython-37.pyc new file mode 100644 index 0000000..e2b6f4d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return_py3.cpython-37.pyc new file mode 100644 index 0000000..4a70b3e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/assignment_from_no_return_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/attribute_defined_outside_init.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/attribute_defined_outside_init.cpython-37.pyc new file mode 100644 index 0000000..d2f2a9d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/attribute_defined_outside_init.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation.cpython-37.pyc new file mode 100644 index 0000000..4c0239a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation_py36.cpython-37.pyc new file mode 100644 index 0000000..cfdf1c6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation_tabs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation_tabs.cpython-37.pyc new file mode 100644 index 0000000..154c04c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_continuation_tabs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_exception_context.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_exception_context.cpython-37.pyc new file mode 100644 index 0000000..f4488ca Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_exception_context.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_indentation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_indentation.cpython-37.pyc new file mode 100644 index 0000000..c78aa12 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_indentation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_inline_option.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_inline_option.cpython-37.pyc new file mode 100644 index 0000000..8cfc40d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_inline_option.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_open_mode.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_open_mode.cpython-37.pyc new file mode 100644 index 0000000..1f4afe3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_open_mode.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_open_mode_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_open_mode_py3.cpython-37.pyc new file mode 100644 index 0000000..5eab39b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_open_mode_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_reversed_sequence.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_reversed_sequence.cpython-37.pyc new file mode 100644 index 0000000..51877ad Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_reversed_sequence.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_staticmethod_argument.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_staticmethod_argument.cpython-37.pyc new file mode 100644 index 0000000..805846d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_staticmethod_argument.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_thread_instantiation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_thread_instantiation.cpython-37.pyc new file mode 100644 index 0000000..8a8f9a4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_thread_instantiation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_whitespace.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_whitespace.cpython-37.pyc new file mode 100644 index 0000000..ded9668 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bad_whitespace.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bare_except.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bare_except.cpython-37.pyc new file mode 100644 index 0000000..a6c243f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bare_except.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/blacklisted_name.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/blacklisted_name.cpython-37.pyc new file mode 100644 index 0000000..3525ded Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/blacklisted_name.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/boolean_datetime.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/boolean_datetime.cpython-37.pyc new file mode 100644 index 0000000..b18a65d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/boolean_datetime.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/broad_except.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/broad_except.cpython-37.pyc new file mode 100644 index 0000000..5dbf4e4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/broad_except.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bugfix_local_scope_metaclass_1177.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bugfix_local_scope_metaclass_1177.cpython-37.pyc new file mode 100644 index 0000000..08ebb96 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/bugfix_local_scope_metaclass_1177.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/cellvar_escaping_loop.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/cellvar_escaping_loop.cpython-37.pyc new file mode 100644 index 0000000..d429714 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/cellvar_escaping_loop.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/class_members_py30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/class_members_py30.cpython-37.pyc new file mode 100644 index 0000000..e250581 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/class_members_py30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/class_scope.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/class_scope.cpython-37.pyc new file mode 100644 index 0000000..9837761 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/class_scope.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/comparison_with_callable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/comparison_with_callable.cpython-37.pyc new file mode 100644 index 0000000..ff6ff6f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/comparison_with_callable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/confidence_filter.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/confidence_filter.cpython-37.pyc new file mode 100644 index 0000000..c27266b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/confidence_filter.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/confusing_with_statement.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/confusing_with_statement.cpython-37.pyc new file mode 100644 index 0000000..e461841 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/confusing_with_statement.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_iterating_dictionary.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_iterating_dictionary.cpython-37.pyc new file mode 100644 index 0000000..3078880 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_iterating_dictionary.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_join.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_join.cpython-37.pyc new file mode 100644 index 0000000..31425bb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_join.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_merging_isinstance.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_merging_isinstance.cpython-37.pyc new file mode 100644 index 0000000..bb8dbcb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_merging_isinstance.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_swap_variables.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_swap_variables.cpython-37.pyc new file mode 100644 index 0000000..20d4fb6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_swap_variables.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_dict_comprehension.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_dict_comprehension.cpython-37.pyc new file mode 100644 index 0000000..565c09a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_dict_comprehension.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_enumerate.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_enumerate.cpython-37.pyc new file mode 100644 index 0000000..0994ed6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_enumerate.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_get.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_get.cpython-37.pyc new file mode 100644 index 0000000..74f540a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_get.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_in.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_in.cpython-37.pyc new file mode 100644 index 0000000..0eb1009 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_in.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_set_comprehension.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_set_comprehension.cpython-37.pyc new file mode 100644 index 0000000..a2d3dd4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/consider_using_set_comprehension.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/control_pragmas.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/control_pragmas.cpython-37.pyc new file mode 100644 index 0000000..834055d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/control_pragmas.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/crash_missing_module_type.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/crash_missing_module_type.cpython-37.pyc new file mode 100644 index 0000000..5d446ef Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/crash_missing_module_type.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ctor_arguments.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ctor_arguments.cpython-37.pyc new file mode 100644 index 0000000..581d905 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ctor_arguments.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/dangerous_default_value.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/dangerous_default_value.cpython-37.pyc new file mode 100644 index 0000000..59b6c88 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/dangerous_default_value.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/dangerous_default_value_py30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/dangerous_default_value_py30.cpython-37.pyc new file mode 100644 index 0000000..6f09a11 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/dangerous_default_value_py30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/defined_and_used_on_same_line.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/defined_and_used_on_same_line.cpython-37.pyc new file mode 100644 index 0000000..830b56a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/defined_and_used_on_same_line.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_lambda.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_lambda.cpython-37.pyc new file mode 100644 index 0000000..78c2f9c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_lambda.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_method_getmoduleinfo.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_method_getmoduleinfo.cpython-37.pyc new file mode 100644 index 0000000..c599122 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_method_getmoduleinfo.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py2.cpython-37.pyc new file mode 100644 index 0000000..ee5362a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py3.cpython-37.pyc new file mode 100644 index 0000000..1df47d2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py36.cpython-37.pyc new file mode 100644 index 0000000..f997cb6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_methods_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py2.cpython-37.pyc new file mode 100644 index 0000000..b02cffd Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py3.cpython-37.pyc new file mode 100644 index 0000000..daa3693 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py36.cpython-37.pyc new file mode 100644 index 0000000..7076170 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py4.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py4.cpython-37.pyc new file mode 100644 index 0000000..8fd493b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_py4.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_uninstalled.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_uninstalled.cpython-37.pyc new file mode 100644 index 0000000..6e70870 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/deprecated_module_uninstalled.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_msg_github_issue_1389.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_msg_github_issue_1389.cpython-37.pyc new file mode 100644 index 0000000..2dfa1c6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_msg_github_issue_1389.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_ungrouped_imports.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_ungrouped_imports.cpython-37.pyc new file mode 100644 index 0000000..4970057 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_ungrouped_imports.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_order.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_order.cpython-37.pyc new file mode 100644 index 0000000..f9c8886 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_order.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_position.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_position.cpython-37.pyc new file mode 100644 index 0000000..f2fe6e7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/disable_wrong_import_position.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/docstrings.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/docstrings.cpython-37.pyc new file mode 100644 index 0000000..f6c1ab7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/docstrings.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_bases.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_bases.cpython-37.pyc new file mode 100644 index 0000000..b799ddf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_bases.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_dict_literal_key.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_dict_literal_key.cpython-37.pyc new file mode 100644 index 0000000..198e7a9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_dict_literal_key.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_except.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_except.cpython-37.pyc new file mode 100644 index 0000000..9f27b4f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_except.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_string_formatting_argument.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_string_formatting_argument.cpython-37.pyc new file mode 100644 index 0000000..997c5c6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/duplicate_string_formatting_argument.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/eval_used.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/eval_used.cpython-37.pyc new file mode 100644 index 0000000..280dd80 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/eval_used.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exception_is_binary_op.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exception_is_binary_op.cpython-37.pyc new file mode 100644 index 0000000..e1caabf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exception_is_binary_op.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exception_message.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exception_message.cpython-37.pyc new file mode 100644 index 0000000..56bdb37 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exception_message.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exec_used_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exec_used_py3.cpython-37.pyc new file mode 100644 index 0000000..ef042d9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/exec_used_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fallback_import_disabled.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fallback_import_disabled.cpython-37.pyc new file mode 100644 index 0000000..20332ea Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fallback_import_disabled.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fallback_import_enabled.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fallback_import_enabled.cpython-37.pyc new file mode 100644 index 0000000..e0f0f13 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fallback_import_enabled.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fixme.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fixme.cpython-37.pyc new file mode 100644 index 0000000..d548d82 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fixme.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fixme_bad_formatting_1139.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fixme_bad_formatting_1139.cpython-37.pyc new file mode 100644 index 0000000..7548281 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/fixme_bad_formatting_1139.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/formatted_string_literal_with_if_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/formatted_string_literal_with_if_py36.cpython-37.pyc new file mode 100644 index 0000000..4fef6b5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/formatted_string_literal_with_if_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/function_redefined.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/function_redefined.cpython-37.pyc new file mode 100644 index 0000000..023e049 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/function_redefined.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/future_import.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/future_import.cpython-37.pyc new file mode 100644 index 0000000..f7978d3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/future_import.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/future_unicode_literals.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/future_unicode_literals.cpython-37.pyc new file mode 100644 index 0000000..c32c904 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/future_unicode_literals.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/generated_members.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/generated_members.cpython-37.pyc new file mode 100644 index 0000000..5551f00 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/generated_members.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/genexp_in_class_scope.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/genexp_in_class_scope.cpython-37.pyc new file mode 100644 index 0000000..3ac0973 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/genexp_in_class_scope.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/genexpr_variable_scope.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/genexpr_variable_scope.cpython-37.pyc new file mode 100644 index 0000000..a032efc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/genexpr_variable_scope.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/globals.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/globals.cpython-37.pyc new file mode 100644 index 0000000..0faa624 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/globals.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence.cpython-37.pyc new file mode 100644 index 0000000..c4e6809 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_latin1.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_latin1.cpython-37.pyc new file mode 100644 index 0000000..f9f3d4a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_latin1.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_utf8.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_utf8.cpython-37.pyc new file mode 100644 index 0000000..4119e87 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/implicit_str_concat_in_sequence_utf8.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/import_error.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/import_error.cpython-37.pyc new file mode 100644 index 0000000..41ae87d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/import_error.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inconsistent_mro.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inconsistent_mro.cpython-37.pyc new file mode 100644 index 0000000..9c24856 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inconsistent_mro.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inconsistent_returns.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inconsistent_returns.cpython-37.pyc new file mode 100644 index 0000000..b4ff411 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inconsistent_returns.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/indexing_exception.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/indexing_exception.cpython-37.pyc new file mode 100644 index 0000000..ea3887d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/indexing_exception.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inherit_non_class.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inherit_non_class.cpython-37.pyc new file mode 100644 index 0000000..b824e6c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/inherit_non_class.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_is_generator.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_is_generator.cpython-37.pyc new file mode 100644 index 0000000..9b081dc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_is_generator.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_not_called.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_not_called.cpython-37.pyc new file mode 100644 index 0000000..98b93fa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_not_called.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_subclass_classmethod_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_subclass_classmethod_py36.cpython-37.pyc new file mode 100644 index 0000000..8b49c11 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/init_subclass_classmethod_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_all_object.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_all_object.cpython-37.pyc new file mode 100644 index 0000000..d647c35 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_all_object.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_encoding_py27.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_encoding_py27.cpython-37.pyc new file mode 100644 index 0000000..d396c06 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_encoding_py27.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_envvar_value.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_envvar_value.cpython-37.pyc new file mode 100644 index 0000000..d9bfb7a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_envvar_value.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_caught.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_caught.cpython-37.pyc new file mode 100644 index 0000000..0bea5ef Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_caught.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_raised.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_raised.cpython-37.pyc new file mode 100644 index 0000000..b7a5e8b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_exceptions_raised.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_length_returned.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_length_returned.cpython-37.pyc new file mode 100644 index 0000000..647e99f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_length_returned.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_metaclass.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_metaclass.cpython-37.pyc new file mode 100644 index 0000000..81c1965 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_metaclass.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_metaclass_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_metaclass_py3.cpython-37.pyc new file mode 100644 index 0000000..1acde25 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_metaclass_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_name.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_name.cpython-37.pyc new file mode 100644 index 0000000..e9b7302 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_name.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_sequence_index.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_sequence_index.cpython-37.pyc new file mode 100644 index 0000000..2a1c32e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_sequence_index.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_slice_index.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_slice_index.cpython-37.pyc new file mode 100644 index 0000000..e76993b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_slice_index.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_unary_operand_type.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_unary_operand_type.cpython-37.pyc new file mode 100644 index 0000000..e0b2f6c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/invalid_unary_operand_type.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context.cpython-37.pyc new file mode 100644 index 0000000..8aa3633 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context_py3.cpython-37.pyc new file mode 100644 index 0000000..e745d79 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context_py36.cpython-37.pyc new file mode 100644 index 0000000..a098240 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/iterable_context_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/keyword_arg_before_vararg.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/keyword_arg_before_vararg.cpython-37.pyc new file mode 100644 index 0000000..0dc9317 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/keyword_arg_before_vararg.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/len_checks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/len_checks.cpython-37.pyc new file mode 100644 index 0000000..6c7a5ec Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/len_checks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_endings.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_endings.cpython-37.pyc new file mode 100644 index 0000000..f1e1158 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_endings.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_too_long.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_too_long.cpython-37.pyc new file mode 100644 index 0000000..bf6652b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_too_long.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_too_long_end_of_module.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_too_long_end_of_module.cpython-37.pyc new file mode 100644 index 0000000..5538e65 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/line_too_long_end_of_module.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/literal_comparison.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/literal_comparison.cpython-37.pyc new file mode 100644 index 0000000..72c4490 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/literal_comparison.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation.cpython-37.pyc new file mode 100644 index 0000000..19819ea Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation_py36.cpython-37.pyc new file mode 100644 index 0000000..5cd0988 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_format_interpolation_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_fstring_interpolation_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_fstring_interpolation_py36.cpython-37.pyc new file mode 100644 index 0000000..ffe3119 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_fstring_interpolation_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_not_lazy.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_not_lazy.cpython-37.pyc new file mode 100644 index 0000000..3f79e1c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logging_not_lazy.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logical_tautology.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logical_tautology.cpython-37.pyc new file mode 100644 index 0000000..4669710 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/logical_tautology.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/long_lines_with_utf8.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/long_lines_with_utf8.cpython-37.pyc new file mode 100644 index 0000000..c09bc34 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/long_lines_with_utf8.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/long_utf8_lines.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/long_utf8_lines.cpython-37.pyc new file mode 100644 index 0000000..5069f42 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/long_utf8_lines.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/lost_exception.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/lost_exception.cpython-37.pyc new file mode 100644 index 0000000..1efcfa2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/lost_exception.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context.cpython-37.pyc new file mode 100644 index 0000000..c42f5a9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context_py2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context_py2.cpython-37.pyc new file mode 100644 index 0000000..a3e15c4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context_py2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context_py3.cpython-37.pyc new file mode 100644 index 0000000..6c15918 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mapping_context_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks.cpython-37.pyc new file mode 100644 index 0000000..6f07812 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_hints.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_hints.cpython-37.pyc new file mode 100644 index 0000000..90b69c2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_hints.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_ignore_none.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_ignore_none.cpython-37.pyc new file mode 100644 index 0000000..4be7538 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_ignore_none.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_no_hints.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_no_hints.cpython-37.pyc new file mode 100644 index 0000000..031e611 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_no_hints.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_opaque.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_opaque.cpython-37.pyc new file mode 100644 index 0000000..32725ad Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_opaque.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_py37.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_py37.cpython-37.pyc new file mode 100644 index 0000000..96d11ba Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/member_checks_py37.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol.cpython-37.pyc new file mode 100644 index 0000000..8462f0e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol_py2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol_py2.cpython-37.pyc new file mode 100644 index 0000000..6884539 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol_py2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol_py3.cpython-37.pyc new file mode 100644 index 0000000..f65b422 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/membership_protocol_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/messages_managed_by_id.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/messages_managed_by_id.cpython-37.pyc new file mode 100644 index 0000000..78296ca Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/messages_managed_by_id.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/method_hidden.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/method_hidden.cpython-37.pyc new file mode 100644 index 0000000..8c1b2e2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/method_hidden.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_bare_raise.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_bare_raise.cpython-37.pyc new file mode 100644 index 0000000..82d10ee Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_bare_raise.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_comparison_constant.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_comparison_constant.cpython-37.pyc new file mode 100644 index 0000000..d2d62f4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_comparison_constant.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_format_function.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_format_function.cpython-37.pyc new file mode 100644 index 0000000..f05ff70 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/misplaced_format_function.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_docstring.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_docstring.cpython-37.pyc new file mode 100644 index 0000000..95d8ee2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_docstring.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_final_newline.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_final_newline.cpython-37.pyc new file mode 100644 index 0000000..9c886c5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_final_newline.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_kwoa_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_kwoa_py3.cpython-37.pyc new file mode 100644 index 0000000..9bd2b21 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_kwoa_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_self_argument.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_self_argument.cpython-37.pyc new file mode 100644 index 0000000..be9ecca Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/missing_self_argument.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mixed_indentation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mixed_indentation.cpython-37.pyc new file mode 100644 index 0000000..a486a7a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/mixed_indentation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/monkeypatch_method.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/monkeypatch_method.cpython-37.pyc new file mode 100644 index 0000000..0cf104d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/monkeypatch_method.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/multiple_imports.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/multiple_imports.cpython-37.pyc new file mode 100644 index 0000000..f615c3a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/multiple_imports.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/namePresetCamelCase.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/namePresetCamelCase.cpython-37.pyc new file mode 100644 index 0000000..5136ed5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/namePresetCamelCase.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/name_preset_snake_case.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/name_preset_snake_case.cpython-37.pyc new file mode 100644 index 0000000..97ad21b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/name_preset_snake_case.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/name_styles.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/name_styles.cpython-37.pyc new file mode 100644 index 0000000..49dfb2c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/name_styles.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/namedtuple_member_inference.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/namedtuple_member_inference.cpython-37.pyc new file mode 100644 index 0000000..17c0702 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/namedtuple_member_inference.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/names_in__all__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/names_in__all__.cpython-37.pyc new file mode 100644 index 0000000..2ccdc73 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/names_in__all__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/nested_blocks_issue1088.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/nested_blocks_issue1088.cpython-37.pyc new file mode 100644 index 0000000..7814bc1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/nested_blocks_issue1088.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_classmethod_decorator.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_classmethod_decorator.cpython-37.pyc new file mode 100644 index 0000000..a39cadc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_classmethod_decorator.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_else_return.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_else_return.cpython-37.pyc new file mode 100644 index 0000000..09b0509 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_else_return.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_name_in_module.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_name_in_module.cpython-37.pyc new file mode 100644 index 0000000..4ffd48e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_name_in_module.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_self_use.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_self_use.cpython-37.pyc new file mode 100644 index 0000000..4fa8727 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_self_use.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_self_use_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_self_use_py3.cpython-37.pyc new file mode 100644 index 0000000..f5fe63e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_self_use_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_staticmethod_decorator.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_staticmethod_decorator.cpython-37.pyc new file mode 100644 index 0000000..ec982ea Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/no_staticmethod_decorator.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/non_iterator_returned.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/non_iterator_returned.cpython-37.pyc new file mode 100644 index 0000000..0fdcc1b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/non_iterator_returned.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/none_dunder_protocols_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/none_dunder_protocols_py36.cpython-37.pyc new file mode 100644 index 0000000..6d4487c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/none_dunder_protocols_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/nonexistent_operator.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/nonexistent_operator.cpython-37.pyc new file mode 100644 index 0000000..3850f9b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/nonexistent_operator.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_async_context_manager.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_async_context_manager.cpython-37.pyc new file mode 100644 index 0000000..fa1ac52 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_async_context_manager.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_callable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_callable.cpython-37.pyc new file mode 100644 index 0000000..2abde92 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_callable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_context_manager.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_context_manager.cpython-37.pyc new file mode 100644 index 0000000..31e746f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/not_context_manager.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_activated.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_activated.cpython-37.pyc new file mode 100644 index 0000000..f59d9ef Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_activated.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_not_activated.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_not_activated.cpython-37.pyc new file mode 100644 index 0000000..fd5fc78 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/postponed_evaluation_not_activated.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/protected_access_access_different_scopes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/protected_access_access_different_scopes.cpython-37.pyc new file mode 100644 index 0000000..1c90d43 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/protected_access_access_different_scopes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_format_tuple.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_format_tuple.cpython-37.pyc new file mode 100644 index 0000000..4bfb6d0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_format_tuple.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_non_exception_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_non_exception_py3.cpython-37.pyc new file mode 100644 index 0000000..f88356f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_non_exception_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_self.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_self.cpython-37.pyc new file mode 100644 index 0000000..ba77aa7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/raising_self.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/recursion_error_940.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/recursion_error_940.cpython-37.pyc new file mode 100644 index 0000000..c54777f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/recursion_error_940.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redefined_argument_from_local.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redefined_argument_from_local.cpython-37.pyc new file mode 100644 index 0000000..ffb6b2a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redefined_argument_from_local.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redefined_builtin.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redefined_builtin.cpython-37.pyc new file mode 100644 index 0000000..47d9b93 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redefined_builtin.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redundant_unittest_assert.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redundant_unittest_assert.cpython-37.pyc new file mode 100644 index 0000000..5991404 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/redundant_unittest_assert.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/regression_1326_crash_uninferable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/regression_1326_crash_uninferable.cpython-37.pyc new file mode 100644 index 0000000..05304d3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/regression_1326_crash_uninferable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/regression_no_value_for_parameter.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/regression_no_value_for_parameter.cpython-37.pyc new file mode 100644 index 0000000..f0058f1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/regression_no_value_for_parameter.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reimported.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reimported.cpython-37.pyc new file mode 100644 index 0000000..906ec72 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reimported.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/repeated_keyword.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/repeated_keyword.cpython-37.pyc new file mode 100644 index 0000000..004a148 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/repeated_keyword.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/return_in_init.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/return_in_init.cpython-37.pyc new file mode 100644 index 0000000..d9310b5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/return_in_init.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable.cpython-37.pyc new file mode 100644 index 0000000..8927ae7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable_py3.cpython-37.pyc new file mode 100644 index 0000000..049ff58 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/reused_outer_loop_variable_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/self_cls_assignment.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/self_cls_assignment.cpython-37.pyc new file mode 100644 index 0000000..7fbd4d6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/self_cls_assignment.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/signature_differs.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/signature_differs.cpython-37.pyc new file mode 100644 index 0000000..d90b686 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/signature_differs.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplifiable_if_expression.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplifiable_if_expression.cpython-37.pyc new file mode 100644 index 0000000..d362c16 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplifiable_if_expression.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplifiable_if_statement.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplifiable_if_statement.cpython-37.pyc new file mode 100644 index 0000000..a4ff334 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplifiable_if_statement.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplify_chained_comparison.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplify_chained_comparison.cpython-37.pyc new file mode 100644 index 0000000..cd017d4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/simplify_chained_comparison.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singledispatch_functions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singledispatch_functions.cpython-37.pyc new file mode 100644 index 0000000..c2697ae Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singledispatch_functions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singledispatch_functions_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singledispatch_functions_py3.cpython-37.pyc new file mode 100644 index 0000000..8adb094 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singledispatch_functions_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singleton_comparison.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singleton_comparison.cpython-37.pyc new file mode 100644 index 0000000..f9a2a25 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/singleton_comparison.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/slots_checks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/slots_checks.cpython-37.pyc new file mode 100644 index 0000000..fc7c2d6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/slots_checks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/socketerror_import.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/socketerror_import.cpython-37.pyc new file mode 100644 index 0000000..ea6e957 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/socketerror_import.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/statement_without_effect.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/statement_without_effect.cpython-37.pyc new file mode 100644 index 0000000..2e45795 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/statement_without_effect.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/statement_without_effect_py36.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/statement_without_effect_py36.cpython-37.pyc new file mode 100644 index 0000000..8c37728 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/statement_without_effect_py36.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/stop_iteration_inside_generator.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/stop_iteration_inside_generator.cpython-37.pyc new file mode 100644 index 0000000..387a1cd Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/stop_iteration_inside_generator.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting.cpython-37.pyc new file mode 100644 index 0000000..583adb4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_disable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_disable.cpython-37.pyc new file mode 100644 index 0000000..a66c552 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_disable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_failed_inference.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_failed_inference.cpython-37.pyc new file mode 100644 index 0000000..9f425f1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_failed_inference.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_py27.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_py27.cpython-37.pyc new file mode 100644 index 0000000..e7324d1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_py27.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_py3.cpython-37.pyc new file mode 100644 index 0000000..347b14c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/string_formatting_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/subprocess_popen_preexec_fn.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/subprocess_popen_preexec_fn.cpython-37.pyc new file mode 100644 index 0000000..8667916 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/subprocess_popen_preexec_fn.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/super_checks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/super_checks.cpython-37.pyc new file mode 100644 index 0000000..fc4f158 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/super_checks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/superfluous_parens.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/superfluous_parens.cpython-37.pyc new file mode 100644 index 0000000..150ef18 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/superfluous_parens.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call.cpython-37.pyc new file mode 100644 index 0000000..086fddb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call_py3.cpython-37.pyc new file mode 100644 index 0000000..425094a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/suspicious_str_strip_call_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/sys_stream_regression_1004.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/sys_stream_regression_1004.cpython-37.pyc new file mode 100644 index 0000000..09343c6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/sys_stream_regression_1004.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ternary.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ternary.cpython-37.pyc new file mode 100644 index 0000000..d55d51e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ternary.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/test_compile.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/test_compile.cpython-37.pyc new file mode 100644 index 0000000..331e4c7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/test_compile.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/tokenize_error.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/tokenize_error.cpython-37.pyc new file mode 100644 index 0000000..46f912d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/tokenize_error.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/tokenize_error_jython.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/tokenize_error_jython.cpython-37.pyc new file mode 100644 index 0000000..3a9bf87 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/tokenize_error_jython.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_few_public_methods.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_few_public_methods.cpython-37.pyc new file mode 100644 index 0000000..f328ec9 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_few_public_methods.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_few_public_methods_37.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_few_public_methods_37.cpython-37.pyc new file mode 100644 index 0000000..487f4ed Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_few_public_methods_37.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_ancestors.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_ancestors.cpython-37.pyc new file mode 100644 index 0000000..ec81f73 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_ancestors.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_arguments.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_arguments.cpython-37.pyc new file mode 100644 index 0000000..ef3f668 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_arguments.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_arguments_issue_1045.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_arguments_issue_1045.cpython-37.pyc new file mode 100644 index 0000000..3d4697f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_arguments_issue_1045.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_boolean_expressions.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_boolean_expressions.cpython-37.pyc new file mode 100644 index 0000000..c744404 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_boolean_expressions.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_branches.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_branches.cpython-37.pyc new file mode 100644 index 0000000..0269d26 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_branches.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_instance_attributes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_instance_attributes.cpython-37.pyc new file mode 100644 index 0000000..a07e318 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_instance_attributes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_lines.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_lines.cpython-37.pyc new file mode 100644 index 0000000..278ac9e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_lines.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_lines_disabled.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_lines_disabled.cpython-37.pyc new file mode 100644 index 0000000..152672c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_lines_disabled.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_locals.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_locals.cpython-37.pyc new file mode 100644 index 0000000..6f7ce26 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_locals.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_nested_blocks.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_nested_blocks.cpython-37.pyc new file mode 100644 index 0000000..c4dfb7f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_nested_blocks.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_public_methods.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_public_methods.cpython-37.pyc new file mode 100644 index 0000000..9f503c8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_public_methods.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_return_statements.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_return_statements.cpython-37.pyc new file mode 100644 index 0000000..a00b9a3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_return_statements.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_statements.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_statements.cpython-37.pyc new file mode 100644 index 0000000..a7085cf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/too_many_statements.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_comma_tuple.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_comma_tuple.cpython-37.pyc new file mode 100644 index 0000000..2e9ed93 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_comma_tuple.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_newlines.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_newlines.cpython-37.pyc new file mode 100644 index 0000000..0145702 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_newlines.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_whitespaces.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_whitespaces.cpython-37.pyc new file mode 100644 index 0000000..f4f28b3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/trailing_whitespaces.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking.cpython-37.pyc new file mode 100644 index 0000000..67d0650 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking_py30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking_py30.cpython-37.pyc new file mode 100644 index 0000000..831bf4f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unbalanced_tuple_unpacking_py30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_loop_variable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_loop_variable.cpython-37.pyc new file mode 100644 index 0000000..2ddb281 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_loop_variable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_variable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_variable.cpython-37.pyc new file mode 100644 index 0000000..0577caa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_variable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_variable_py30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_variable_py30.cpython-37.pyc new file mode 100644 index 0000000..8b405b4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/undefined_variable_py30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unexpected_special_method_signature.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unexpected_special_method_signature.cpython-37.pyc new file mode 100644 index 0000000..3c270d4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unexpected_special_method_signature.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ungrouped_imports.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ungrouped_imports.cpython-37.pyc new file mode 100644 index 0000000..08fbcdc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/ungrouped_imports.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unhashable_dict_key.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unhashable_dict_key.cpython-37.pyc new file mode 100644 index 0000000..eb626f6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unhashable_dict_key.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unidiomatic_typecheck.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unidiomatic_typecheck.cpython-37.pyc new file mode 100644 index 0000000..ddadb63 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unidiomatic_typecheck.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/uninferable_all_object.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/uninferable_all_object.cpython-37.pyc new file mode 100644 index 0000000..b41d907 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/uninferable_all_object.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unnecessary_lambda.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unnecessary_lambda.cpython-37.pyc new file mode 100644 index 0000000..218ed6a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unnecessary_lambda.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unnecessary_pass.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unnecessary_pass.cpython-37.pyc new file mode 100644 index 0000000..27fe5a0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unnecessary_pass.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unneeded_not.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unneeded_not.cpython-37.pyc new file mode 100644 index 0000000..065eb24 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unneeded_not.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking.cpython-37.pyc new file mode 100644 index 0000000..251a5b3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking_generalizations.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking_generalizations.cpython-37.pyc new file mode 100644 index 0000000..433e519 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking_generalizations.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking_non_sequence.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking_non_sequence.cpython-37.pyc new file mode 100644 index 0000000..ba44ab7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unpacking_non_sequence.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unreachable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unreachable.cpython-37.pyc new file mode 100644 index 0000000..91fb81c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unreachable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unrecognized_inline_option.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unrecognized_inline_option.cpython-37.pyc new file mode 100644 index 0000000..5fd2f7b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unrecognized_inline_option.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsubscriptable_value.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsubscriptable_value.cpython-37.pyc new file mode 100644 index 0000000..ea72dbf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsubscriptable_value.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_assignment_operation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_assignment_operation.cpython-37.pyc new file mode 100644 index 0000000..b4c1931 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_assignment_operation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_binary_operation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_binary_operation.cpython-37.pyc new file mode 100644 index 0000000..fd25b8d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_binary_operation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_delete_operation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_delete_operation.cpython-37.pyc new file mode 100644 index 0000000..0c5558d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unsupported_delete_operation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_argument.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_argument.cpython-37.pyc new file mode 100644 index 0000000..cb3bb47 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_argument.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_argument_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_argument_py3.cpython-37.pyc new file mode 100644 index 0000000..3cd446f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_argument_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable1.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable1.cpython-37.pyc new file mode 100644 index 0000000..563e951 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable1.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable2.cpython-37.pyc new file mode 100644 index 0000000..3fc763d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable3.cpython-37.pyc new file mode 100644 index 0000000..9cbdf0e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable4.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable4.cpython-37.pyc new file mode 100644 index 0000000..5a644be Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_global_variable4.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_import.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_import.cpython-37.pyc new file mode 100644 index 0000000..3782031 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_import.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_import_assigned_to.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_import_assigned_to.cpython-37.pyc new file mode 100644 index 0000000..5d5d631 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_import_assigned_to.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_typing_imports.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_typing_imports.cpython-37.pyc new file mode 100644 index 0000000..d25f1f7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_typing_imports.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_variable.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_variable.cpython-37.pyc new file mode 100644 index 0000000..e4780a6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/unused_variable.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_488.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_488.cpython-37.pyc new file mode 100644 index 0000000..b3f2313 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_488.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue1081.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue1081.cpython-37.pyc new file mode 100644 index 0000000..76c4eef Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue1081.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue853.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue853.cpython-37.pyc new file mode 100644 index 0000000..6f0351c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_issue853.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_nonlocal.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_nonlocal.cpython-37.pyc new file mode 100644 index 0000000..f59040d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/used_before_assignment_nonlocal.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless-import-alias.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless-import-alias.cpython-37.pyc new file mode 100644 index 0000000..f455e27 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless-import-alias.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_else_on_loop.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_else_on_loop.cpython-37.pyc new file mode 100644 index 0000000..5ccb224 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_else_on_loop.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_object_inheritance.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_object_inheritance.cpython-37.pyc new file mode 100644 index 0000000..07bd334 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_object_inheritance.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_return.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_return.cpython-37.pyc new file mode 100644 index 0000000..9ee6ded Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_return.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation.cpython-37.pyc new file mode 100644 index 0000000..dab5fce Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py3.cpython-37.pyc new file mode 100644 index 0000000..83830b6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py35.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py35.cpython-37.pyc new file mode 100644 index 0000000..22f8369 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/useless_super_delegation_py35.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/using_constant_test.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/using_constant_test.cpython-37.pyc new file mode 100644 index 0000000..c11490d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/using_constant_test.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wildcard_import.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wildcard_import.cpython-37.pyc new file mode 100644 index 0000000..0b2602d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wildcard_import.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wildcard_import_allowed.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wildcard_import_allowed.cpython-37.pyc new file mode 100644 index 0000000..a8f13fe Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wildcard_import_allowed.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/with_used_before_assign.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/with_used_before_assign.cpython-37.pyc new file mode 100644 index 0000000..85365cc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/with_used_before_assign.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/with_using_generator.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/with_using_generator.cpython-37.pyc new file mode 100644 index 0000000..b27775a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/with_using_generator.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_order.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_order.cpython-37.pyc new file mode 100644 index 0000000..d1b7ddc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_order.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_order2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_order2.cpython-37.pyc new file mode 100644 index 0000000..2e7cd8a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_order2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position.cpython-37.pyc new file mode 100644 index 0000000..513966f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position10.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position10.cpython-37.pyc new file mode 100644 index 0000000..92d3644 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position10.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position11.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position11.cpython-37.pyc new file mode 100644 index 0000000..0831571 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position11.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position12.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position12.cpython-37.pyc new file mode 100644 index 0000000..cbde8ab Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position12.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position13.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position13.cpython-37.pyc new file mode 100644 index 0000000..bb24fb4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position13.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position14.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position14.cpython-37.pyc new file mode 100644 index 0000000..6688924 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position14.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position15.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position15.cpython-37.pyc new file mode 100644 index 0000000..b65908b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position15.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position2.cpython-37.pyc new file mode 100644 index 0000000..860729d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position3.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position3.cpython-37.pyc new file mode 100644 index 0000000..9161f0a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position3.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position4.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position4.cpython-37.pyc new file mode 100644 index 0000000..420bfd2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position4.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position5.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position5.cpython-37.pyc new file mode 100644 index 0000000..4ff009b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position5.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position6.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position6.cpython-37.pyc new file mode 100644 index 0000000..36f5b7d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position6.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position7.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position7.cpython-37.pyc new file mode 100644 index 0000000..e21c9af Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position7.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position8.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position8.cpython-37.pyc new file mode 100644 index 0000000..33c2af6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position8.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position9.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position9.cpython-37.pyc new file mode 100644 index 0000000..f60d582 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position9.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position_exclude_dunder_main.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position_exclude_dunder_main.cpython-37.pyc new file mode 100644 index 0000000..653cec6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/wrong_import_position_exclude_dunder_main.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/yield_from_iterable_py33.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/yield_from_iterable_py33.cpython-37.pyc new file mode 100644 index 0000000..2a72d6b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/__pycache__/yield_from_iterable_py33.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_abc_methods.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_abc_methods.py new file mode 100644 index 0000000..47c241a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_abc_methods.py @@ -0,0 +1,17 @@ +""" This should not warn about `prop` being abstract in Child """ +# pylint: disable=too-few-public-methods, no-absolute-import,metaclass-assignment, useless-object-inheritance + +import abc + +class Parent(object): + """Abstract Base Class """ + __metaclass__ = abc.ABCMeta + + @property + @abc.abstractmethod + def prop(self): + """ Abstract """ + +class Child(Parent): + """ No warning for the following. """ + prop = property(lambda self: 1) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_in_class.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_in_class.py new file mode 100644 index 0000000..e22c837 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_in_class.py @@ -0,0 +1,20 @@ +"""Don't warn if the class is instantiated in its own body.""" +# pylint: disable=missing-docstring, useless-object-inheritance + + +import abc + +import six + + +@six.add_metaclass(abc.ABCMeta) +class Ala(object): + + @abc.abstractmethod + def bala(self): + pass + + @classmethod + def portocala(cls): + instance = cls() + return instance diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.py new file mode 100644 index 0000000..ba34d26 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.py @@ -0,0 +1,82 @@ +"""Check that instantiating a class with +`abc.ABCMeta` as metaclass fails if it defines +abstract methods. +""" + +# pylint: disable=too-few-public-methods, missing-docstring, useless-object-inheritance +# pylint: disable=no-absolute-import, metaclass-assignment +# pylint: disable=abstract-method, import-error, wildcard-import + +import abc +from abc import ABCMeta +from lala import Bala + + +class GoodClass(object): + __metaclass__ = abc.ABCMeta + +class SecondGoodClass(object): + __metaclass__ = abc.ABCMeta + + def test(self): + """ do nothing. """ + +class ThirdGoodClass(object): + __metaclass__ = abc.ABCMeta + + def test(self): + raise NotImplementedError() + +class FourthGoodClass(object): + __metaclass__ = ABCMeta + +class BadClass(object): + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def test(self): + """ do nothing. """ + +class SecondBadClass(object): + __metaclass__ = abc.ABCMeta + + @property + @abc.abstractmethod + def test(self): + """ do nothing. """ + +class ThirdBadClass(object): + __metaclass__ = ABCMeta + + @abc.abstractmethod + def test(self): + pass + +class FourthBadClass(ThirdBadClass): + pass + + +class SomeMetaclass(object): + __metaclass__ = ABCMeta + + @abc.abstractmethod + def prop(self): + pass + +class FifthGoodClass(SomeMetaclass): + """Don't consider this abstract if some attributes are + there, but can't be inferred. + """ + prop = Bala # missing + + +def main(): + """ do nothing """ + GoodClass() + SecondGoodClass() + ThirdGoodClass() + FourthGoodClass() + BadClass() # [abstract-class-instantiated] + SecondBadClass() # [abstract-class-instantiated] + ThirdBadClass() # [abstract-class-instantiated] + FourthBadClass() # [abstract-class-instantiated] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.rc new file mode 100644 index 0000000..b11e16d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.txt new file mode 100644 index 0000000..8ab4b55 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py2.txt @@ -0,0 +1,4 @@ +abstract-class-instantiated:79:main:Abstract class 'BadClass' with abstract methods instantiated +abstract-class-instantiated:80:main:Abstract class 'SecondBadClass' with abstract methods instantiated +abstract-class-instantiated:81:main:Abstract class 'ThirdBadClass' with abstract methods instantiated +abstract-class-instantiated:82:main:Abstract class 'FourthBadClass' with abstract methods instantiated diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.py new file mode 100644 index 0000000..c027833 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.py @@ -0,0 +1,128 @@ +"""Check that instantiating a class with +`abc.ABCMeta` as metaclass fails if it defines +abstract methods. +""" + +# pylint: disable=too-few-public-methods, missing-docstring +# pylint: disable=abstract-method, import-error, useless-object-inheritance + +import abc +import weakref +from lala import Bala + + +class GoodClass(object, metaclass=abc.ABCMeta): + pass + +class SecondGoodClass(object, metaclass=abc.ABCMeta): + def test(self): + """ do nothing. """ + +class ThirdGoodClass(object, metaclass=abc.ABCMeta): + """ This should not raise the warning. """ + def test(self): + raise NotImplementedError() + +class BadClass(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def test(self): + """ do nothing. """ + +class SecondBadClass(object, metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def test(self): + """ do nothing. """ + +class ThirdBadClass(SecondBadClass): + pass + + +class Structure(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __iter__(self): + pass + @abc.abstractmethod + def __len__(self): + pass + @abc.abstractmethod + def __contains__(self, _): + pass + @abc.abstractmethod + def __hash__(self): + pass + +class Container(Structure): + def __contains__(self, _): + pass + +class Sizable(Structure): + def __len__(self): + pass + +class Hashable(Structure): + __hash__ = 42 + + +class Iterator(Structure): + def keys(self): # pylint: disable=no-self-use + return iter([1, 2, 3]) + + __iter__ = keys + +class AbstractSizable(Structure): + @abc.abstractmethod + def length(self): + pass + __len__ = length + +class NoMroAbstractMethods(Container, Iterator, Sizable, Hashable): + pass + +class BadMroAbstractMethods(Container, Iterator, AbstractSizable): + pass + +class SomeMetaclass(metaclass=abc.ABCMeta): + + @abc.abstractmethod + def prop(self): + pass + +class FourthGoodClass(SomeMetaclass): + """Don't consider this abstract if some attributes are + there, but can't be inferred. + """ + prop = Bala # missing + + +def main(): + """ do nothing """ + GoodClass() + SecondGoodClass() + ThirdGoodClass() + FourthGoodClass() + weakref.WeakKeyDictionary() + weakref.WeakValueDictionary() + NoMroAbstractMethods() + + BadMroAbstractMethods() # [abstract-class-instantiated] + BadClass() # [abstract-class-instantiated] + SecondBadClass() # [abstract-class-instantiated] + ThirdBadClass() # [abstract-class-instantiated] + + +if 1: # pylint: disable=using-constant-test + class FourthBadClass(object, metaclass=abc.ABCMeta): + + def test(self): + pass +else: + class FourthBadClass(object, metaclass=abc.ABCMeta): + + @abc.abstractmethod + def test(self): + pass + + +def main2(): + FourthBadClass() # [abstract-class-instantiated] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.txt new file mode 100644 index 0000000..1464337 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py3.txt @@ -0,0 +1,5 @@ +abstract-class-instantiated:108:main:Abstract class 'BadMroAbstractMethods' with abstract methods instantiated +abstract-class-instantiated:109:main:Abstract class 'BadClass' with abstract methods instantiated +abstract-class-instantiated:110:main:Abstract class 'SecondBadClass' with abstract methods instantiated +abstract-class-instantiated:111:main:Abstract class 'ThirdBadClass' with abstract methods instantiated +abstract-class-instantiated:128:main2:Abstract class 'FourthBadClass' with abstract methods instantiated diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.py new file mode 100644 index 0000000..c22be36 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.py @@ -0,0 +1,19 @@ +""" +Check that instantiating a class with `abc.ABCMeta` as ancestor fails if it +defines abstract methods. +""" + +# pylint: disable=too-few-public-methods, missing-docstring, no-init + +import abc + + + +class BadClass(abc.ABC): + @abc.abstractmethod + def test(self): + pass + +def main(): + """ do nothing """ + BadClass() # [abstract-class-instantiated] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.rc new file mode 100644 index 0000000..1fb7b87 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.4 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.txt new file mode 100644 index 0000000..14ffda4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_class_instantiated_py34.txt @@ -0,0 +1 @@ +abstract-class-instantiated:19:main:Abstract class 'BadClass' with abstract methods instantiated diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.py new file mode 100644 index 0000000..54fd1f9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.py @@ -0,0 +1,90 @@ +"""Test abstract-method warning.""" +from __future__ import print_function + +# pylint: disable=missing-docstring, no-init, no-self-use +# pylint: disable=too-few-public-methods, useless-object-inheritance +import abc + +class Abstract(object): + def aaaa(self): + """should be overridden in concrete class""" + raise NotImplementedError() + + def bbbb(self): + """should be overridden in concrete class""" + raise NotImplementedError() + + +class AbstractB(Abstract): + """Abstract class. + + this class is checking that it does not output an error msg for + unimplemeted methods in abstract classes + """ + def cccc(self): + """should be overridden in concrete class""" + raise NotImplementedError() + +class Concrete(Abstract): # [abstract-method] + """Concrete class""" + + def aaaa(self): + """overidden form Abstract""" + + +class Structure(object): + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def __iter__(self): + pass + @abc.abstractmethod + def __len__(self): + pass + @abc.abstractmethod + def __contains__(self, _): + pass + @abc.abstractmethod + def __hash__(self): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Container(Structure): + def __contains__(self, _): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Sizable(Structure): + def __len__(self): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Hashable(Structure): + __hash__ = 42 + + +# +1: [abstract-method, abstract-method, abstract-method] +class Iterator(Structure): + def keys(self): + return iter([1, 2, 3]) + + __iter__ = keys + + +class AbstractSizable(Structure): + @abc.abstractmethod + def length(self): + pass + __len__ = length + + +class GoodComplexMRO(Container, Iterator, Sizable, Hashable): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class BadComplexMro(Container, Iterator, AbstractSizable): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.rc new file mode 100644 index 0000000..b11e16d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.txt new file mode 100644 index 0000000..61b2dbb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py2.txt @@ -0,0 +1,16 @@ +abstract-method:28:Concrete:"Method 'bbbb' is abstract in class 'Abstract' but is not overridden" +abstract-method:53:Container:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:53:Container:"Method '__iter__' is abstract in class 'Structure' but is not overridden" +abstract-method:53:Container:"Method '__len__' is abstract in class 'Structure' but is not overridden" +abstract-method:59:Sizable:"Method '__contains__' is abstract in class 'Structure' but is not overridden" +abstract-method:59:Sizable:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:59:Sizable:"Method '__iter__' is abstract in class 'Structure' but is not overridden" +abstract-method:65:Hashable:"Method '__contains__' is abstract in class 'Structure' but is not overridden" +abstract-method:65:Hashable:"Method '__iter__' is abstract in class 'Structure' but is not overridden" +abstract-method:65:Hashable:"Method '__len__' is abstract in class 'Structure' but is not overridden" +abstract-method:70:Iterator:"Method '__contains__' is abstract in class 'Structure' but is not overridden" +abstract-method:70:Iterator:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:70:Iterator:"Method '__len__' is abstract in class 'Structure' but is not overridden" +abstract-method:89:BadComplexMro:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:89:BadComplexMro:"Method '__len__' is abstract in class 'AbstractSizable' but is not overridden" +abstract-method:89:BadComplexMro:"Method 'length' is abstract in class 'AbstractSizable' but is not overridden" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.py new file mode 100644 index 0000000..f4e3dd5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.py @@ -0,0 +1,88 @@ +"""Test abstract-method warning.""" +from __future__ import print_function + +# pylint: disable=missing-docstring, no-init, no-self-use +# pylint: disable=too-few-public-methods, useless-object-inheritance +import abc + +class Abstract(object): + def aaaa(self): + """should be overridden in concrete class""" + raise NotImplementedError() + + def bbbb(self): + """should be overridden in concrete class""" + raise NotImplementedError() + + +class AbstractB(Abstract): + """Abstract class. + + this class is checking that it does not output an error msg for + unimplemeted methods in abstract classes + """ + def cccc(self): + """should be overridden in concrete class""" + raise NotImplementedError() + +class Concrete(Abstract): # [abstract-method] + """Concrete class""" + + def aaaa(self): + """overidden form Abstract""" + + +class Structure(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __iter__(self): + pass + @abc.abstractmethod + def __len__(self): + pass + @abc.abstractmethod + def __contains__(self, _): + pass + @abc.abstractmethod + def __hash__(self): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Container(Structure): + def __contains__(self, _): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Sizable(Structure): + def __len__(self): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class Hashable(Structure): + __hash__ = 42 + + +# +1: [abstract-method, abstract-method, abstract-method] +class Iterator(Structure): + def keys(self): + return iter([1, 2, 3]) + + __iter__ = keys + + +class AbstractSizable(Structure): + @abc.abstractmethod + def length(self): + pass + __len__ = length + + +class GoodComplexMRO(Container, Iterator, Sizable, Hashable): + pass + + +# +1: [abstract-method, abstract-method, abstract-method] +class BadComplexMro(Container, Iterator, AbstractSizable): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.txt new file mode 100644 index 0000000..65de6e9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/abstract_method_py3.txt @@ -0,0 +1,16 @@ +abstract-method:28:Concrete:"Method 'bbbb' is abstract in class 'Abstract' but is not overridden" +abstract-method:51:Container:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:51:Container:"Method '__iter__' is abstract in class 'Structure' but is not overridden" +abstract-method:51:Container:"Method '__len__' is abstract in class 'Structure' but is not overridden" +abstract-method:57:Sizable:"Method '__contains__' is abstract in class 'Structure' but is not overridden" +abstract-method:57:Sizable:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:57:Sizable:"Method '__iter__' is abstract in class 'Structure' but is not overridden" +abstract-method:63:Hashable:"Method '__contains__' is abstract in class 'Structure' but is not overridden" +abstract-method:63:Hashable:"Method '__iter__' is abstract in class 'Structure' but is not overridden" +abstract-method:63:Hashable:"Method '__len__' is abstract in class 'Structure' but is not overridden" +abstract-method:68:Iterator:"Method '__contains__' is abstract in class 'Structure' but is not overridden" +abstract-method:68:Iterator:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:68:Iterator:"Method '__len__' is abstract in class 'Structure' but is not overridden" +abstract-method:87:BadComplexMro:"Method '__hash__' is abstract in class 'Structure' but is not overridden" +abstract-method:87:BadComplexMro:"Method '__len__' is abstract in class 'AbstractSizable' but is not overridden" +abstract-method:87:BadComplexMro:"Method 'length' is abstract in class 'AbstractSizable' but is not overridden" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_member_before_definition.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_member_before_definition.py new file mode 100644 index 0000000..d8a97b4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_member_before_definition.py @@ -0,0 +1,40 @@ +# pylint: disable=missing-docstring,too-few-public-methods,invalid-name +# pylint: disable=attribute-defined-outside-init, useless-object-inheritance + +class Aaaa(object): + """class with attributes defined in wrong order""" + + def __init__(self): + var1 = self._var2 # [access-member-before-definition] + self._var2 = 3 + self._var3 = var1 + + +class Bbbb(object): + A = 23 + B = A + + def __getattr__(self, attr): + try: + return self.__repo + except AttributeError: + self.__repo = attr + return attr + + + def catchme(self, attr): + """no AttributeError catched""" + try: + return self._repo # [access-member-before-definition] + except ValueError: + self._repo = attr + return attr + + +class Mixin(object): + + def test_mixin(self): + """Don't emit access-member-before-definition for mixin classes.""" + if self.already_defined: + # pylint: disable=attribute-defined-outside-init + self.already_defined = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_member_before_definition.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_member_before_definition.txt new file mode 100644 index 0000000..8186044 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_member_before_definition.txt @@ -0,0 +1,2 @@ +access-member-before-definition:8:Aaaa.__init__:Access to member '_var2' before its definition line 9 +access-member-before-definition:28:Bbbb.catchme:Access to member '_repo' before its definition line 30 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to__name__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to__name__.py new file mode 100644 index 0000000..82dcdbe --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to__name__.py @@ -0,0 +1,21 @@ +# pylint: disable=too-few-public-methods, print-statement, useless-object-inheritance +"""test access to __name__ gives undefined member on new/old class instances +but not on new/old class object +""" +from __future__ import print_function + +class Aaaa: + """old class""" + def __init__(self): + print(self.__name__) # [no-member] + print(self.__class__.__name__) + +class NewClass(object): + """new class""" + + def __new__(cls, *args, **kwargs): + print('new', cls.__name__) + return object.__new__(cls, *args, **kwargs) + + def __init__(self): + print('init', self.__name__) # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to__name__.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to__name__.txt new file mode 100644 index 0000000..29ec889 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to__name__.txt @@ -0,0 +1,2 @@ +no-member:10:Aaaa.__init__:Instance of 'Aaaa' has no '__name__' member:INFERENCE +no-member:21:NewClass.__init__:Instance of 'NewClass' has no '__name__' member:INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to_protected_members.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to_protected_members.py new file mode 100644 index 0000000..1c97a3b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to_protected_members.py @@ -0,0 +1,59 @@ +# pylint: disable=too-few-public-methods, W0231, print-statement, useless-object-inheritance +# pylint: disable=no-classmethod-decorator +"""Test external access to protected class members.""" +from __future__ import print_function + +class MyClass(object): + """Class with protected members.""" + _cls_protected = 5 + + def __init__(self, other): + MyClass._cls_protected = 6 + self._protected = 1 + self.public = other + self.attr = 0 + + def test(self): + """Docstring.""" + self._protected += self._cls_protected + print(self.public._haha) # [protected-access] + + def clsmeth(cls): + """Docstring.""" + cls._cls_protected += 1 + print(cls._cls_protected) + clsmeth = classmethod(clsmeth) + + def _private_method(self): + """Doing nothing.""" + + +class Subclass(MyClass): + """Subclass with protected members.""" + + def __init__(self): + MyClass._protected = 5 + super(Subclass, self)._private_method() + +INST = Subclass() +INST.attr = 1 +print(INST.attr) +INST._protected = 2 # [protected-access] +print(INST._protected) # [protected-access] +INST._cls_protected = 3 # [protected-access] +print(INST._cls_protected) # [protected-access] + + +class Issue1031(object): + """Test for GitHub issue 1031""" + _attr = 1 + + def correct_access(self): + """Demonstrates correct access""" + return type(self)._attr + + def incorrect_access(self): + """Demonstrates incorrect access""" + if self._attr == 1: + return type(INST)._protected # [protected-access] + return None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to_protected_members.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to_protected_members.txt new file mode 100644 index 0000000..fb5c152 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/access_to_protected_members.txt @@ -0,0 +1,6 @@ +protected-access:19:MyClass.test:Access to a protected member _haha of a client class +protected-access:41::Access to a protected member _protected of a client class +protected-access:42::Access to a protected member _protected of a client class +protected-access:43::Access to a protected member _cls_protected of a client class +protected-access:44::Access to a protected member _cls_protected of a client class +protected-access:58:Issue1031.incorrect_access:Access to a protected member _protected of a client class diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.py new file mode 100644 index 0000000..8f304fa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.py @@ -0,0 +1,20 @@ +# pylint:disable=W0105, W0511 +"""Test for backslash escapes in byte vs unicode strings""" + +# Would be valid in Unicode, but probably not what you want otherwise +BAD_UNICODE = b'\u0042' # [anomalous-unicode-escape-in-string] +BAD_LONG_UNICODE = b'\U00000042' # [anomalous-unicode-escape-in-string] +# +1:[anomalous-unicode-escape-in-string] +BAD_NAMED_UNICODE = b'\N{GREEK SMALL LETTER ALPHA}' + +GOOD_UNICODE = u'\u0042' +GOOD_LONG_UNICODE = u'\U00000042' +GOOD_NAMED_UNICODE = u'\N{GREEK SMALL LETTER ALPHA}' + + +# Valid raw strings +RAW_BACKSLASHES = r'raw' +RAW_UNICODE = ur"\u0062\n" + +# In a comment you can have whatever you want: \ \\ \n \m +# even things that look like bad strings: "C:\Program Files" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.rc new file mode 100644 index 0000000..b11e16d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.txt new file mode 100644 index 0000000..c242cb9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py2.txt @@ -0,0 +1,3 @@ +anomalous-unicode-escape-in-string:5::"Anomalous Unicode escape in byte string: '\u'. String constant might be missing an r or u prefix." +anomalous-unicode-escape-in-string:6::"Anomalous Unicode escape in byte string: '\U'. String constant might be missing an r or u prefix." +anomalous-unicode-escape-in-string:8::"Anomalous Unicode escape in byte string: '\N'. String constant might be missing an r or u prefix." diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.py new file mode 100644 index 0000000..b8bfd0a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.py @@ -0,0 +1,19 @@ +# pylint:disable=W0105, W0511 +"""Test for backslash escapes in byte vs unicode strings""" + +# Would be valid in Unicode, but probably not what you want otherwise +BAD_UNICODE = b'\u0042' # [anomalous-unicode-escape-in-string] +BAD_LONG_UNICODE = b'\U00000042' # [anomalous-unicode-escape-in-string] +# +1:[anomalous-unicode-escape-in-string] +BAD_NAMED_UNICODE = b'\N{GREEK SMALL LETTER ALPHA}' + +GOOD_UNICODE = u'\u0042' +GOOD_LONG_UNICODE = u'\U00000042' +GOOD_NAMED_UNICODE = u'\N{GREEK SMALL LETTER ALPHA}' + + +# Valid raw strings +RAW_BACKSLASHES = r'raw' + +# In a comment you can have whatever you want: \ \\ \n \m +# even things that look like bad strings: "C:\Program Files" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.txt new file mode 100644 index 0000000..d2c5d10 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/anomalous_unicode_escape_py3.txt @@ -0,0 +1,3 @@ +anomalous-unicode-escape-in-string:5::"Anomalous Unicode escape in byte string: '\u'. String constant might be missing an r or u prefix." +anomalous-unicode-escape-in-string:6::"Anomalous Unicode escape in byte string: '\U'. String constant might be missing an r or u prefix." +anomalous-unicode-escape-in-string:8::"Anomalous Unicode escape in byte string: '\N'. String constant might be missing an r or u prefix." \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments.py new file mode 100644 index 0000000..ea833eb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments.py @@ -0,0 +1,217 @@ +# pylint: disable=too-few-public-methods, no-absolute-import,missing-docstring,import-error,wrong-import-position +# pylint: disable=wrong-import-order, useless-object-inheritance + +def decorator(fun): + """Decorator""" + return fun + + +class DemoClass(object): + """Test class for method invocations.""" + + @staticmethod + def static_method(arg): + """static method.""" + return arg + arg + + @classmethod + def class_method(cls, arg): + """class method""" + return arg + arg + + def method(self, arg): + """method.""" + return (self, arg) + + @decorator + def decorated_method(self, arg): + """decorated method.""" + return (self, arg) + + +def function_1_arg(first_argument): + """one argument function""" + return first_argument + +def function_3_args(first_argument, second_argument, third_argument): + """three arguments function""" + return first_argument, second_argument, third_argument + +def function_default_arg(one=1, two=2): + """fonction with default value""" + return two, one + + +function_1_arg(420) +function_1_arg() # [no-value-for-parameter] +function_1_arg(1337, 347) # [too-many-function-args] + +function_3_args(420, 789) # [no-value-for-parameter] +# +1:[no-value-for-parameter,no-value-for-parameter,no-value-for-parameter] +function_3_args() +function_3_args(1337, 347, 456) +function_3_args('bab', 'bebe', None, 5.6) # [too-many-function-args] + +function_default_arg(1, two=5) +function_default_arg(two=5) + +function_1_arg(bob=4) # [unexpected-keyword-arg,no-value-for-parameter] +function_default_arg(1, 4, coin="hello") # [unexpected-keyword-arg] + +function_default_arg(1, one=5) # [redundant-keyword-arg] + +# Remaining tests are for coverage of correct names in messages. +LAMBDA = lambda arg: 1 + +LAMBDA() # [no-value-for-parameter] + +def method_tests(): + """Method invocations.""" + demo = DemoClass() + demo.static_method() # [no-value-for-parameter] + DemoClass.static_method() # [no-value-for-parameter] + + demo.class_method() # [no-value-for-parameter] + DemoClass.class_method() # [no-value-for-parameter] + + demo.method() # [no-value-for-parameter] + DemoClass.method(demo) # [no-value-for-parameter] + + demo.decorated_method() # [no-value-for-parameter] + DemoClass.decorated_method(demo) # [no-value-for-parameter] + +# Test a regression (issue #234) +import sys + +class Text(object): + """ Regression """ + + if sys.version_info > (3,): + def __new__(cls): + """ empty """ + return object.__new__(cls) + else: + def __new__(cls): + """ empty """ + return object.__new__(cls) + +Text() + +class TestStaticMethod(object): + + @staticmethod + def test(first, second=None, **kwargs): + return first, second, kwargs + + def func(self): + self.test(42) + self.test(42, second=34) + self.test(42, 42) + self.test() # [no-value-for-parameter] + self.test(42, 42, 42) # [too-many-function-args] + + +class TypeCheckConstructor(object): + def __init__(self, first, second): + self.first = first + self.second = second + def test(self): + type(self)(1, 2, 3) # [too-many-function-args] + # +1: [no-value-for-parameter,no-value-for-parameter] + type(self)() + type(self)(1, lala=2) # [no-value-for-parameter,unexpected-keyword-arg] + type(self)(1, 2) + type(self)(first=1, second=2) + + +class Test(object): + """ lambda needs Test instance as first argument """ + lam = lambda self, icon: (self, icon) + + def test(self): + self.lam(42) + self.lam() # [no-value-for-parameter] + self.lam(1, 2, 3) # [too-many-function-args] + +Test().lam() # [no-value-for-parameter] + +# Don't emit a redundant-keyword-arg for this example, +# it's perfectly valid + +class Issue642(object): + attr = 0 + def __str__(self): + return "{self.attr}".format(self=self) + +# These should not emit anything regarding the number of arguments, +# since they have something invalid. +from ala_bala_portocola import unknown + +# pylint: disable=not-a-mapping,not-an-iterable + +function_1_arg(*unknown) +function_1_arg(1, *2) +function_1_arg(1, 2, 3, **unknown) +function_1_arg(4, 5, **1) +function_1_arg(5, 6, **{unknown: 1}) +function_1_arg(**{object: 1}) +function_1_arg(**{1: 2}) + +def no_context_but_redefined(*args): + args = [1] + #+1: [no-value-for-parameter, no-value-for-parameter] + expect_three(*list(args)) + +def no_context_one_elem(*args): + expect_three(args) # [no-value-for-parameter, no-value-for-parameter] + +# Don't emit no-value-for-parameter for this, since we +# don't have the context at our disposal. +def expect_three(one, two, three): + return one + two + three + + +def no_context(*args): + expect_three(*args) + +def no_context_two(*args): + expect_three(*list(args)) + +def no_context_three(*args): + expect_three(*set(args)) + +def compare_prices(arg): + return set((arg, )) + +def find_problems2(prob_dates): + for fff in range(10): + prob_dates |= compare_prices(fff) + + +from collections import namedtuple + + +def namedtuple_replace_issue_1036(): + cls = namedtuple('cls', 'a b c') + new_instance = cls(1, 2, 3)._replace( + a=24, + b=24, + c=42 + ) + # +1:[unexpected-keyword-arg,unexpected-keyword-arg] + new_bad_instance = cls(1, 2, 3)._replace(d=24, e=32) + return new_instance, new_bad_instance + + +from functools import partial + +def some_func(first, second, third): + return first + second + third + + +partial(some_func, 1, 2)(3) +partial(some_func, third=1, second=2)(3) +partial(some_func, 1, third=2)(second=3) +partial(some_func, 1)(1) # [no-value-for-parameter] +partial(some_func, 1)(third=1) # [no-value-for-parameter] +partial(some_func, 1, 2)(third=1, fourth=4) # [unexpected-keyword-arg] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments.txt new file mode 100644 index 0000000..03132ef --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments.txt @@ -0,0 +1,39 @@ +no-value-for-parameter:46::No value for argument 'first_argument' in function call +too-many-function-args:47::Too many positional arguments for function call +no-value-for-parameter:49::No value for argument 'third_argument' in function call +no-value-for-parameter:51::No value for argument 'first_argument' in function call +no-value-for-parameter:51::No value for argument 'second_argument' in function call +no-value-for-parameter:51::No value for argument 'third_argument' in function call +too-many-function-args:53::Too many positional arguments for function call +no-value-for-parameter:58::No value for argument 'first_argument' in function call +unexpected-keyword-arg:58::Unexpected keyword argument 'bob' in function call +unexpected-keyword-arg:59::Unexpected keyword argument 'coin' in function call +redundant-keyword-arg:61::Argument 'one' passed by position and keyword in function call +no-value-for-parameter:66::No value for argument 'arg' in lambda call +no-value-for-parameter:71:method_tests:No value for argument 'arg' in staticmethod call +no-value-for-parameter:72:method_tests:No value for argument 'arg' in staticmethod call +no-value-for-parameter:74:method_tests:No value for argument 'arg' in classmethod call +no-value-for-parameter:75:method_tests:No value for argument 'arg' in classmethod call +no-value-for-parameter:77:method_tests:No value for argument 'arg' in method call +no-value-for-parameter:78:method_tests:No value for argument 'arg' in unbound method call +no-value-for-parameter:80:method_tests:No value for argument 'arg' in method call +no-value-for-parameter:81:method_tests:No value for argument 'arg' in unbound method call +no-value-for-parameter:110:TestStaticMethod.func:No value for argument 'first' in staticmethod call +too-many-function-args:111:TestStaticMethod.func:Too many positional arguments for staticmethod call +too-many-function-args:119:TypeCheckConstructor.test:Too many positional arguments for constructor call +no-value-for-parameter:121:TypeCheckConstructor.test:No value for argument 'first' in constructor call +no-value-for-parameter:121:TypeCheckConstructor.test:No value for argument 'second' in constructor call +no-value-for-parameter:122:TypeCheckConstructor.test:No value for argument 'second' in constructor call +unexpected-keyword-arg:122:TypeCheckConstructor.test:Unexpected keyword argument 'lala' in constructor call +no-value-for-parameter:133:Test.test:No value for argument 'icon' in method call +too-many-function-args:134:Test.test:Too many positional arguments for method call +no-value-for-parameter:136::No value for argument 'icon' in method call +no-value-for-parameter:163:no_context_but_redefined:No value for argument 'three' in function call +no-value-for-parameter:163:no_context_but_redefined:No value for argument 'two' in function call +no-value-for-parameter:166:no_context_one_elem:No value for argument 'three' in function call +no-value-for-parameter:166:no_context_one_elem:No value for argument 'two' in function call +unexpected-keyword-arg:202:namedtuple_replace_issue_1036:Unexpected keyword argument 'd' in method call +unexpected-keyword-arg:202:namedtuple_replace_issue_1036:Unexpected keyword argument 'e' in method call +no-value-for-parameter:215::No value for argument 'third' in function call +no-value-for-parameter:216::No value for argument 'second' in function call +unexpected-keyword-arg:217::Unexpected keyword argument 'fourth' in function call \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ.py new file mode 100644 index 0000000..1e78be6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ.py @@ -0,0 +1,210 @@ +"""Test that we are emitting arguments-differ when the arguments are different.""" +# pylint: disable=missing-docstring, too-few-public-methods, unused-argument,useless-super-delegation, useless-object-inheritance + +class Parent(object): + + def test(self): + pass + + +class Child(Parent): + + def test(self, arg): # [arguments-differ] + pass + + +class ParentDefaults(object): + + def test(self, arg=None, barg=None): + pass + +class ChildDefaults(ParentDefaults): + + def test(self, arg=None): # [arguments-differ] + pass + + +class Classmethod(object): + + @classmethod + def func(cls, data): + return data + + @classmethod + def func1(cls): + return cls + + +class ClassmethodChild(Classmethod): + + @staticmethod + def func(): # [arguments-differ] + pass + + @classmethod + def func1(cls): + return cls() + + +class Builtins(dict): + """Ignore for builtins, for which we don't know the number of required args.""" + + @classmethod + def fromkeys(cls, arg, arg1): + pass + + +class Varargs(object): + + def has_kwargs(self, arg, **kwargs): + pass + + def no_kwargs(self, args): + pass + + +class VarargsChild(Varargs): + + def has_kwargs(self, arg): # [arguments-differ] + "Not okay to lose capabilities." + + def no_kwargs(self, arg, **kwargs): # [arguments-differ] + "Not okay to add extra capabilities." + + +class Super(object): + def __init__(self): + pass + + def __private(self): + pass + + def __private2_(self): + pass + + def ___private3(self): + pass + + def method(self, param): + raise NotImplementedError + + +class Sub(Super): + + # pylint: disable=unused-argument + def __init__(self, arg): + super(Sub, self).__init__() + + def __private(self, arg): + pass + + def __private2_(self, arg): + pass + + def ___private3(self, arg): + pass + + def method(self, param='abc'): + pass + + +class Staticmethod(object): + + @staticmethod + def func(data): + return data + + +class StaticmethodChild(Staticmethod): + + @classmethod + def func(cls, data): + return data + + +class Property(object): + + @property + def close(self): + pass + +class PropertySetter(Property): + + @property + def close(self): + pass + + @close.setter + def close(self, attr): + return attr + + +class StaticmethodChild2(Staticmethod): + + def func(self, data): + super(StaticmethodChild2, self).func(data) + + +class SuperClass(object): + + @staticmethod + def impl(arg1, arg2, **kwargs): + return arg1 + arg2 + + +class MyClass(SuperClass): + + def impl(self, *args, **kwargs): # [arguments-differ] + + super(MyClass, self).impl(*args, **kwargs) + + +class FirstHasArgs(object): + + def test(self, *args): + pass + + +class SecondChangesArgs(FirstHasArgs): + + def test(self, first, second, *args): # [arguments-differ] + pass + +class Positional(object): + + def test(self, first, second): + pass + + +class PositionalChild(Positional): + + def test(self, *args): # [arguments-differ] + """Accepts too many. + + Why subclassing in the first case if the behavior is different? + """ + super(PositionalChild, self).test(args[0], args[1]) + + +class HasSpecialMethod(object): + + def __getitem__(self, key): + return key + + +class OverridesSpecialMethod(HasSpecialMethod): + + def __getitem__(self, cheie): + return cheie + 1 + + +class ParentClass(object): + + def meth(self, arg, arg1): + raise NotImplementedError + + +class ChildClass(ParentClass): + + def meth(self, _arg, dummy): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ.txt new file mode 100644 index 0000000..22f71d6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ.txt @@ -0,0 +1,8 @@ +arguments-differ:12:Child.test:Parameters differ from overridden 'test' method +arguments-differ:23:ChildDefaults.test:Parameters differ from overridden 'test' method +arguments-differ:41:ClassmethodChild.func:Parameters differ from overridden 'func' method +arguments-differ:68:VarargsChild.has_kwargs:Parameters differ from overridden 'has_kwargs' method +arguments-differ:71:VarargsChild.no_kwargs:Parameters differ from overridden 'no_kwargs' method +arguments-differ:157:MyClass.impl:Parameters differ from overridden 'impl' method +arguments-differ:170:SecondChangesArgs.test:Parameters differ from overridden 'test' method +arguments-differ:181:PositionalChild.test:Parameters differ from overridden 'test' method \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.py new file mode 100644 index 0000000..0e07131 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.py @@ -0,0 +1,36 @@ +# pylint: disable=missing-docstring,too-few-public-methods +class AbstractFoo: + + def kwonly_1(self, first, *, second, third): + "Normal positional with two positional only params." + + def kwonly_2(self, *, first, second): + "Two positional only parameter." + + def kwonly_3(self, *, first, second): + "Two positional only params." + + def kwonly_4(self, *, first, second=None): + "One positional only and another with a default." + + def kwonly_5(self, *, first, **kwargs): + "Keyword only and keyword variadics." + + +class Foo(AbstractFoo): + + def kwonly_1(self, first, *, second): # [arguments-differ] + "One positional and only one positional only param." + + def kwonly_2(self, first): # [arguments-differ] + "Only one positional parameter instead of two positional only parameters." + + def kwonly_3(self, first, second): # [arguments-differ] + "Two positional params." + + def kwonly_4(self, first, second): # [arguments-differ] + "Two positional params." + + def kwonly_5(self, *, first): # [arguments-differ] + "Keyword only, but no variadics." + \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.txt new file mode 100644 index 0000000..d494a50 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/arguments_differ_py3.txt @@ -0,0 +1,5 @@ +arguments-differ:22:Foo.kwonly_1:Parameters differ from overridden 'kwonly_1' method +arguments-differ:25:Foo.kwonly_2:Parameters differ from overridden 'kwonly_2' method +arguments-differ:28:Foo.kwonly_3:Parameters differ from overridden 'kwonly_3' method +arguments-differ:31:Foo.kwonly_4:Parameters differ from overridden 'kwonly_4' method +arguments-differ:34:Foo.kwonly_5:Parameters differ from overridden 'kwonly_5' method diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assert_on_tuple.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assert_on_tuple.py new file mode 100644 index 0000000..e360737 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assert_on_tuple.py @@ -0,0 +1,11 @@ +'''Assert check example''' + +# pylint: disable=misplaced-comparison-constant, comparison-with-itself +assert (1 == 1, 2 == 2), "no error" +assert (1 == 1, 2 == 2) # [assert-on-tuple] +assert 1 == 1, "no error" +assert (1 == 1, ), "no error" +assert (1 == 1, ) +assert (1 == 1, 2 == 2, 3 == 5), "no error" +assert () +assert (True, 'error msg') # [assert-on-tuple] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assert_on_tuple.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assert_on_tuple.txt new file mode 100644 index 0000000..52d1ca5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assert_on_tuple.txt @@ -0,0 +1,2 @@ +assert-on-tuple:5::Assert called on a 2-uple. Did you mean 'assert x,y'? +assert-on-tuple:11::Assert called on a 2-uple. Did you mean 'assert x,y'? diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assigning_non_slot.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assigning_non_slot.py new file mode 100644 index 0000000..a57a8b3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assigning_non_slot.py @@ -0,0 +1,150 @@ +""" Checks assigning attributes not found in class slots +will trigger assigning-non-slot warning. +""" +# pylint: disable=too-few-public-methods, no-init, missing-docstring, no-absolute-import, import-error, useless-object-inheritance +from collections import deque + +from missing import Unknown + +class Empty(object): + """ empty """ + +class Bad(object): + """ missing not in slots. """ + + __slots__ = ['member'] + + def __init__(self): + self.missing = 42 # [assigning-non-slot] + +class Bad2(object): + """ missing not in slots """ + __slots__ = [deque.__name__, 'member'] + + def __init__(self): + self.deque = 42 + self.missing = 42 # [assigning-non-slot] + +class Bad3(Bad): + """ missing not found in slots """ + + __slots__ = ['component'] + + def __init__(self): + self.component = 42 + self.member = 24 + self.missing = 42 # [assigning-non-slot] + super(Bad3, self).__init__() + +class Good(Empty): + """ missing not in slots, but Empty doesn't + specify __slots__. + """ + __slots__ = ['a'] + + def __init__(self): + self.missing = 42 + +class Good2(object): + """ Using __dict__ in slots will be safe. """ + + __slots__ = ['__dict__', 'comp'] + + def __init__(self): + self.comp = 4 + self.missing = 5 + +class PropertyGood(object): + """ Using properties is safe. """ + + __slots__ = ['tmp', '_value'] + + @property + def test(self): + return self._value + + @test.setter + def test(self, value): + # pylint: disable=attribute-defined-outside-init + self._value = value + + def __init__(self): + self.test = 42 + +class PropertyGood2(object): + """ Using properties in the body of the class is safe. """ + __slots__ = ['_value'] + + def _getter(self): + return self._value + + def _setter(self, value): + # pylint: disable=attribute-defined-outside-init + self._value = value + + test = property(_getter, _setter) + + def __init__(self): + self.test = 24 + +class UnicodeSlots(object): + """Using unicode objects in __slots__ is okay. + + On Python 3.3 onward, u'' is equivalent to '', + so this test should be safe for both versions. + """ + __slots__ = (u'first', u'second') + + def __init__(self): + self.first = 42 + self.second = 24 + + +class DataDescriptor(object): + def __init__(self, name, default=''): + self.__name = name + self.__default = default + + def __get__(self, inst, cls): + return getattr(inst, self.__name, self.__default) + + def __set__(self, inst, value): + setattr(inst, self.__name, value) + + +class NonDataDescriptor(object): + def __get__(self, inst, cls): + return 42 + + +class SlotsWithDescriptor(object): + __slots__ = ['_err'] + data_descriptor = DataDescriptor('_err') + non_data_descriptor = NonDataDescriptor() + missing_descriptor = Unknown() + + +def dont_emit_for_descriptors(): + inst = SlotsWithDescriptor() + # This should not emit, because attr is + # a data descriptor + inst.data_descriptor = 'foo' + inst.non_data_descriptor = 'lala' # [assigning-non-slot] + + +class ClassWithSlots(object): + __slots__ = ['foobar'] + + +class ClassReassigningDunderClass(object): + __slots__ = ['foobar'] + + def release(self): + self.__class__ = ClassWithSlots + + +class ClassReassingingInvalidLayoutClass(object): + __slots__ = [] + + def release(self): + self.__class__ = ClassWithSlots # [assigning-non-slot] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assigning_non_slot.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assigning_non_slot.txt new file mode 100644 index 0000000..4946e0f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assigning_non_slot.txt @@ -0,0 +1,5 @@ +assigning-non-slot:18:Bad.__init__:Assigning to attribute 'missing' not defined in class slots +assigning-non-slot:26:Bad2.__init__:Assigning to attribute 'missing' not defined in class slots +assigning-non-slot:36:Bad3.__init__:Assigning to attribute 'missing' not defined in class slots +assigning-non-slot:132:dont_emit_for_descriptors:Assigning to attribute 'non_data_descriptor' not defined in class slots +assigning-non-slot:150:ClassReassingingInvalidLayoutClass.release:Assigning to attribute '__class__' not defined in class slots \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return.py new file mode 100644 index 0000000..6991fe5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return.py @@ -0,0 +1,31 @@ +# pylint: disable=missing-docstring + + +def some_func(): + pass + + +def decorate(func): + """Decorate *fn* to return ``self`` to enable chained method calls.""" + def wrapper(self, *args, **kw): + func(self, *args, **kw) + return 42 + return wrapper + + +class Class: + + def some_method(self): + pass + + @decorate + def some_other_decorated_method(self): + pass + + def some_other_method(self): + value = self.some_method() # [assignment-from-no-return] + other_value = self.some_other_decorated_method() + return value + other_value + + +VALUE = some_func() # [assignment-from-no-return] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return.txt new file mode 100644 index 0000000..1972103 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return.txt @@ -0,0 +1,2 @@ +assignment-from-no-return:26:Class.some_other_method:Assigning result of a function call, where the function has no return +assignment-from-no-return:31::Assigning result of a function call, where the function has no return \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.py new file mode 100644 index 0000000..2339706 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.py @@ -0,0 +1,28 @@ +# pylint: disable=missing-docstring + +import asyncio + + +async def bla1(): + await asyncio.sleep(1) + + +async def bla2(): + await asyncio.sleep(2) + + +async def combining_coroutine1(): + await bla1() + await bla2() + + +async def combining_coroutine2(): + future1 = bla1() + future2 = bla2() + await asyncio.gather(future1, future2) + + +def do_stuff(): + loop = asyncio.get_event_loop() + loop.run_until_complete(combining_coroutine1()) + loop.run_until_complete(combining_coroutine2()) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.rc new file mode 100644 index 0000000..1450ccc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/assignment_from_no_return_py3.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.py new file mode 100644 index 0000000..2f2252d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.py @@ -0,0 +1,63 @@ +"""Check that Python 3.5's async functions are properly analyzed by Pylint.""" +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods +# pylint: disable=using-constant-test, useless-object-inheritance + +async def next(): # [redefined-builtin] + pass + +async def some_function(arg1, arg2): # [unused-argument] + await arg1 + + +class OtherClass(object): + + @staticmethod + def test(): + return 42 + + +class Class(object): + + async def some_method(self): + super(OtherClass, self).test() # [bad-super-call] + + +# +1: [too-many-arguments,too-many-return-statements, too-many-branches] +async def complex_function(this, function, has, more, arguments, than, + one, _, should, have): + if 1: + return this + if 1: + return function + if 1: + return has + if 1: + return more + if 1: + return arguments + if 1: + return than + try: + return one + finally: + pass + if 2: + return should + while True: + pass + if 1: + return have + if 2: + return function + if 3: + pass + + +# +1: [duplicate-argument-name, duplicate-argument-name, dangerous-default-value] +async def func(a, a, b=[]): + return a, b + + +# +1: [empty-docstring, blacklisted-name] +async def foo(): + "" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.rc new file mode 100644 index 0000000..03004f2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.txt new file mode 100644 index 0000000..e00c5bb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/async_functions.txt @@ -0,0 +1,11 @@ +redefined-builtin:5:next:"Redefining built-in 'next'" +unused-argument:8:some_function:"Unused argument 'arg2'" +bad-super-call:22:Class.some_method:"Bad first argument 'OtherClass' given to super()" +too-many-arguments:26:complex_function:Too many arguments (10/5) +too-many-branches:26:complex_function:Too many branches (13/12) +too-many-return-statements:26:complex_function:Too many return statements (10/6) +dangerous-default-value:57:func:Dangerous default value [] as argument +duplicate-argument-name:57:func:Duplicate argument name a in function definition +duplicate-argument-name:57:func:Duplicate argument name a in function definition +blacklisted-name:62:foo:Black listed name "foo" +empty-docstring:62:foo:Empty function docstring \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/attribute_defined_outside_init.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/attribute_defined_outside_init.py new file mode 100644 index 0000000..826b5d6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/attribute_defined_outside_init.py @@ -0,0 +1,62 @@ +# pylint: disable=missing-docstring,too-few-public-methods,invalid-name, useless-object-inheritance + +class A(object): + + def __init__(self): + self.x = 0 + self.setUp() + + def set_y(self, y): + self.y = y + + def set_x(self, x): + self.x = x + + def set_z(self, z): + self.z = z # [attribute-defined-outside-init] + + def setUp(self): + self.x = 0 + self.y = 0 + + +class B(A): + + def test(self): + self.z = 44 # [attribute-defined-outside-init] + + +class C(object): + + def __init__(self): + self._init() + + def _init(self): + self.z = 44 + + +class D(object): + + def setUp(self): + self.set_z() + + def set_z(self): + self.z = 42 + + +class E(object): + + def __init__(self): + i = self._init + i() + + def _init(self): + self.z = 44 + + +class Mixin(object): + + def test_mixin(self): + """Don't emit attribute-defined-outside-init for mixin classes.""" + if self.defined_already: # pylint: disable=access-member-before-definition + self.defined_already = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/attribute_defined_outside_init.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/attribute_defined_outside_init.txt new file mode 100644 index 0000000..51456e3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/attribute_defined_outside_init.txt @@ -0,0 +1,2 @@ +attribute-defined-outside-init:16:A.set_z:Attribute 'z' defined outside __init__ +attribute-defined-outside-init:26:B.test:Attribute 'z' defined outside __init__ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation.py new file mode 100644 index 0000000..1c73a11 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation.py @@ -0,0 +1,232 @@ +"""Regression test case for bad-continuation.""" +# pylint: disable=print-statement,implicit-str-concat-in-sequence,using-constant-test,missing-docstring,wrong-import-position +# Various alignment for brackets +from __future__ import print_function + +LIST0 = [ + 1, 2, 3 +] +LIST1 = [ + 1, 2, 3 + ] +LIST2 = [ + 1, 2, 3 + ] # [bad-continuation] + +# Alignment inside literals +W0 = [1, 2, 3, + 4, 5, 6, + 7, # [bad-continuation] + 8, 9, 10, + 11, 12, 13, + # and a comment + 14, 15, 16] + +W1 = { + 'a': 1, + 'b': 2, # [bad-continuation] + 'c': 3, + } + +W2 = { + 'a': 1, + 'b': 2, # [bad-continuation] + 'c': 3, + } + +W2 = ['some', 'contents' # with a continued comment that may be aligned + # under the previous comment (optionally) + 'and', + 'more', # but this + # [bad-continuation] is not accepted + 'contents', # [bad-continuation] nor this. + ] + +# Values in dictionaries should be indented 4 spaces further if they are on a +# different line than their key +W4 = { + 'key1': + 'value1', # Grandfather in the old style + 'key2': + 'value2', # [bad-continuation] + 'key3': + 'value3', # Comma here + } + +# And should follow the same rules as continuations within parens +W5 = { + 'key1': 'long value' + 'long continuation', + 'key2': 'breaking' + 'wrong', # [bad-continuation] + 'key3': 2*( + 2+2), + 'key4': ('parenthesis', + 'continuation') # No comma here + } + +# Allow values to line up with their keys when the key is next to the brace +W6 = {'key1': + 'value1', + 'key2': + 'value2', + } + +# Or allow them to be indented +W7 = {'key1': + 'value1', + 'key2': + 'value2' + } + +# Bug that caused a warning on the previous two cases permitted these odd +# incorrect indentations +W8 = {'key1': +'value1', # [bad-continuation] + } + +W9 = {'key1': + 'value1', # [bad-continuation] + } + +# Alignment of arguments in function definitions +def continue1(some_arg, + some_other_arg): + """A function with well-aligned arguments.""" + print(some_arg, some_other_arg) + + +def continue2( + some_arg, + some_other_arg): + """A function with well-aligned arguments.""" + print(some_arg, some_other_arg) + +def continue3( + some_arg, # [bad-continuation] + some_other_arg): # [bad-continuation] + """A function with misaligned arguments""" + print(some_arg, some_other_arg) + +def continue4( # pylint:disable=missing-docstring + arg1, + arg2): print(arg1, arg2) + + +def callee(*args): + """noop""" + print(args) + + +callee( + "a", + "b" + ) + +callee("a", + "b") # [bad-continuation] + +callee(5, {'a': 'b', + 'c': 'd'}) + +if ( + 1 + ): pass + +if ( + 1 +): pass +if ( + 1 + ): pass # [bad-continuation] + +if (1 and + 2): # [bad-continuation] + pass + +while (1 and + 2): + pass + +while (1 and + 2 and # [bad-continuation] + 3): + pass + +if ( + 2): pass # [bad-continuation] + +if (1 or + 2 or + 3): pass + +if (1 or + 2 or # [bad-continuation] + 3): print(1, 2) + +if (1 and + 2): pass # [bad-continuation] + +if ( + 2): pass + +if ( + 2): # [bad-continuation] + pass + +L1 = (lambda a, + b: a + b) + +if not (1 and + 2): + print(3) + +if not (1 and + 2): # [bad-continuation] + print(3) + +continue2("foo", + some_other_arg="this " + "is " + "fine") + +from contextlib import contextmanager +@contextmanager +def mycontext(*args): + yield args + +with mycontext( + "this is", + "great stuff", + "mane"): + pass + +# pylint: disable=using-constant-test +# More indentation included to distinguish this from the rest. +def long_function_name( + var_one, var_two, var_three, + var_four): + print(var_one, var_two, var_three, var_four) + + +def short_func_name(first, second, third): + # Add some extra indentation on the conditional continuation line. + if (first + and second == first == 'some_big_long_statement_that_should_not_trigger'): + third() + + +# Some normal multi-line statements with double-indented continuation lines. +LARGE_COLLECTION = [ + "spam", + "eggs", + "beans", + ] + +long_function_name( + "1", "2", "3", "4") + +CONCATENATED_TEXT = ( + "spam" + "eggs" + "beans") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation.txt new file mode 100644 index 0000000..672f0af --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation.txt @@ -0,0 +1,63 @@ +bad-continuation:14::"Wrong hanging indentation. + ] # [bad-continuation] +| ^|" +bad-continuation:19::"Wrong continued indentation (remove 3 spaces). + 7, # [bad-continuation] + | ^" +bad-continuation:27::"Wrong hanging indentation (add 1 space). + 'b': 2, # [bad-continuation] + ^|" +bad-continuation:33::"Wrong hanging indentation (add 1 space). + 'b': 2, # [bad-continuation] + ^|" +bad-continuation:41::"Wrong continued indentation. + # [bad-continuation] is not accepted + | | ^" +bad-continuation:42::"Wrong continued indentation (remove 20 spaces). + 'contents', # [bad-continuation] nor this. + | ^" +bad-continuation:51::"Wrong hanging indentation in dict value. + 'value2', # [bad-continuation] + | ^ |" +bad-continuation:61::"Wrong continued indentation (add 4 spaces). + 'wrong', # [bad-continuation] + ^ |" +bad-continuation:85::"Wrong hanging indentation in dict value. +'value1', # [bad-continuation] +^ | |" +bad-continuation:89::"Wrong hanging indentation in dict value. + 'value1', # [bad-continuation] + ^ | |" +bad-continuation:106::"Wrong hanging indentation before block (add 4 spaces). + some_arg, # [bad-continuation] + ^ |" +bad-continuation:107::"Wrong hanging indentation before block (add 4 spaces). + some_other_arg): # [bad-continuation] + ^ |" +bad-continuation:127::"Wrong continued indentation (add 3 spaces). + ""b"") # [bad-continuation] + ^ |" +bad-continuation:141::"Wrong hanging indentation before block. + ): pass # [bad-continuation] +| ^|" +bad-continuation:144::"Wrong continued indentation before block (add 4 spaces). + 2): # [bad-continuation] + ^ |" +bad-continuation:152::"Wrong continued indentation (remove 2 spaces). + 2 and # [bad-continuation] + | ^" +bad-continuation:157::"Wrong hanging indentation before block. + 2): pass # [bad-continuation] + ^ | |" +bad-continuation:164::"Wrong continued indentation before block. + 2 or # [bad-continuation] + |^ |" +bad-continuation:168::"Wrong continued indentation before block. + 2): pass # [bad-continuation] + ^ | |" +bad-continuation:174::"Wrong hanging indentation before block. + 2): # [bad-continuation] + ^ | |" +bad-continuation:185::"Wrong continued indentation (add 4 spaces). + 2): # [bad-continuation] + ^ |" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_py36.py new file mode 100644 index 0000000..172a9c5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_py36.py @@ -0,0 +1,8 @@ +# pylint: disable=missing-docstring, unused-argument + +async def upload_post( + content: bytes, + source: str, + tags: dict) -> dict: + # regression test for https://github.com/PyCQA/pylint/issues/1415 + raise NotImplementedError('Not implemented') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_py36.rc new file mode 100644 index 0000000..1450ccc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.py new file mode 100644 index 0000000..a668dc7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.py @@ -0,0 +1,52 @@ +"""Regression test case for bad-continuation with tabs""" +# pylint: disable=too-few-public-methods,missing-docstring,invalid-name,unused-variable, useless-object-inheritance +# Various alignment for brackets + +# Issue 638 +TEST1 = ["foo", + "bar", + "baz" + ] + +MY_LIST = [ + 1, 2, 3, + 4, 5, 6 + ] + +# Issue 1148 +class Abc(object): + def b(self, c): + # bock indentation + self.d( + c) # (is: tabs only) + + def d(self, e): + # bad hanging indentation + self.b( + e) # [bad-continuation] (is: 2 tabs + 7 spaces) + + def f(self): + # block indentiation (is: all tabs only) + return [ + self.b, + self.d + ] + + def g(self): + # bad hanging indentation + # the closing ] requires 7 - 8 more spcaes; see h(), i() + return [self.b, + self.d # (is: 2 tabs + 8 spaces) + ] # [bad-continuation] (is: tabs only) + + def h(self): + # hanging indentation: all lined up with first token 'self.b' + return [self.b, + self.d # (is: 2 tabs + 8 spaces) + ] # (is: 2 tabs + 8 spaces) + + def i(self): + # hangin identation: closing ] lined up with opening [ + return [self.b, + self.d # (2 tabs + 8 spaces) + ] # (2 tabs + 7 spaces) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.rc new file mode 100644 index 0000000..bebda38 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.rc @@ -0,0 +1,3 @@ +[FORMAT] +indent-string='\t' +indent-after-paren=1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.txt new file mode 100644 index 0000000..8fff7bb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_continuation_tabs.txt @@ -0,0 +1,6 @@ +bad-continuation:26::"Wrong hanging indentation (add 1 space). + e) # [bad-continuation] (is: 2 tabs + 7 spaces) + ^|" +bad-continuation:40::"Wrong continued indentation. + ] # [bad-continuation] (is: tabs only) + ^ ||" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_except_order.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_except_order.py new file mode 100644 index 0000000..4f2fa3e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_except_order.py @@ -0,0 +1,45 @@ +# pylint: disable=missing-docstring, bare-except, broad-except + +__revision__ = 1 + +try: + __revision__ += 1 +except Exception: + __revision__ = 0 +except TypeError: # [bad-except-order] + __revision__ = 0 + +try: + __revision__ += 1 +except LookupError: + __revision__ = 0 +except IndexError: # [bad-except-order] + __revision__ = 0 + +try: + __revision__ += 1 +except (LookupError, NameError): + __revision__ = 0 +except (IndexError, UnboundLocalError): # [bad-except-order, bad-except-order] + __revision__ = 0 + +try: # [bad-except-order] + __revision__ += 1 +except: + pass +except Exception: + pass + +try: + __revision__ += 1 +except TypeError: + __revision__ = 0 +except: + __revision__ = 0 + +try: + __revision__ += 1 +except Exception: + pass +except: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_except_order.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_except_order.txt new file mode 100644 index 0000000..1199d67 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_except_order.txt @@ -0,0 +1,5 @@ +bad-except-order:9::Bad except clauses order (Exception is an ancestor class of TypeError) +bad-except-order:16::Bad except clauses order (LookupError is an ancestor class of IndexError) +bad-except-order:23::Bad except clauses order (LookupError is an ancestor class of IndexError) +bad-except-order:23::Bad except clauses order (NameError is an ancestor class of UnboundLocalError) +bad-except-order:26::Bad except clauses order (empty except clause should always appear last) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.py new file mode 100644 index 0000000..af3e4fb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.py @@ -0,0 +1,24 @@ +"""Check that raise ... from .. uses a proper exception context """ + +# pylint: disable=unreachable, import-error, multiple-imports + +import socket, unknown + +__revision__ = 0 + +class ExceptionSubclass(Exception): + """ subclass """ + +def test(): + """ docstring """ + raise IndexError from 1 # [bad-exception-context] + raise IndexError from None + raise IndexError from ZeroDivisionError + raise IndexError from object() # [bad-exception-context] + raise IndexError from ExceptionSubclass + raise IndexError from socket.error + raise IndexError() from None + raise IndexError() from ZeroDivisionError + raise IndexError() from ZeroDivisionError() + raise IndexError() from object() # [bad-exception-context] + raise IndexError() from unknown diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.txt new file mode 100644 index 0000000..1410755 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_exception_context.txt @@ -0,0 +1,3 @@ +bad-exception-context:14:test:Exception context set to something which is not an exception, nor None +bad-exception-context:17:test:Exception context set to something which is not an exception, nor None +bad-exception-context:23:test:Exception context set to something which is not an exception, nor None \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_indentation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_indentation.py new file mode 100644 index 0000000..4c50eae --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_indentation.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring, pointless-statement +from __future__ import print_function + + +def totoo(): + print('malindented') # [bad-indentation] + +def tutuu(): + print('good indentation') + +def titii(): + 1 # and this. # [bad-indentation] + +def tataa(kdict): + for key in ['1', '2', '3']: + key = key.lower() + + if key in kdict: + del kdict[key] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_indentation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_indentation.txt new file mode 100644 index 0000000..c5c00bb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_indentation.txt @@ -0,0 +1,2 @@ +bad-indentation:6::Bad indentation. Found 1 spaces, expected 4 +bad-indentation:12::Bad indentation. Found 5 spaces, expected 4 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.py new file mode 100644 index 0000000..be6e240 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.py @@ -0,0 +1,5 @@ +"""errors-only is not usable as an inline option""" +# +1: [bad-inline-option] +# pylint: errors-only + +CONST = "This is not a pylint: inline option." diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.rc new file mode 100644 index 0000000..b211d72 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.rc @@ -0,0 +1,2 @@ +[Messages Control] +enable=I diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.txt new file mode 100644 index 0000000..91ac1af --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_inline_option.txt @@ -0,0 +1 @@ +bad-inline-option:3::Unable to consider inline option 'errors-only' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.py new file mode 100644 index 0000000..6b749de --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.py @@ -0,0 +1,37 @@ +"""Warnings for using open() with an invalid mode string.""" + +open('foo.bar', 'w', 2) +open('foo.bar', 'rw') # [bad-open-mode] +open(name='foo.bar', buffering=10, mode='rw') # [bad-open-mode] +open(mode='rw', name='foo.bar') # [bad-open-mode] +open('foo.bar', 'U+') +open('foo.bar', 'rb+') +open('foo.bar', 'Uw') # [bad-open-mode] +open('foo.bar', 2) # [bad-open-mode] +open('foo.bar', buffering=2) +WRITE_MODE = 'w' +open('foo.bar', 'U' + WRITE_MODE + 'z') # [bad-open-mode] +open('foo.bar', 'br') # [bad-open-mode] +open('foo.bar', 'wU') # [bad-open-mode] +open('foo.bar', 'r+b') +open('foo.bar', 'r+') +open('foo.bar', 'w+') +open('foo.bar', 'xb') # [bad-open-mode] +open('foo.bar', 'rx') # [bad-open-mode] +open('foo.bar', 'Ur') +open('foo.bar', 'rU') +open('foo.bar', 'rUb') +open('foo.bar', 'rUb+') +open('foo.bar', 'rU+b') +open('foo.bar', 'r+Ub') +open('foo.bar', '+rUb') # [bad-open-mode] +open('foo.bar', 'ab+') +open('foo.bar', 'a+b') +open('foo.bar', 'aU') # [bad-open-mode] +open('foo.bar', 'U+b') +open('foo.bar', '+Ub') +open('foo.bar', 'b+U') +open('foo.bar', 'Urb+') +open('foo.bar', 'Ur+b') +open('foo.bar', 'Ubr') # [bad-open-mode] +open('foo.bar', 'Ut') # [bad-open-mode] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.txt new file mode 100644 index 0000000..b022286 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode.txt @@ -0,0 +1,14 @@ +bad-open-mode:4::"""rw"" is not a valid mode for open." +bad-open-mode:5::"""rw"" is not a valid mode for open." +bad-open-mode:6::"""rw"" is not a valid mode for open." +bad-open-mode:9::"""Uw"" is not a valid mode for open." +bad-open-mode:10::"""2"" is not a valid mode for open." +bad-open-mode:13::"""Uwz"" is not a valid mode for open." +bad-open-mode:14::"""br"" is not a valid mode for open." +bad-open-mode:15::"""wU"" is not a valid mode for open." +bad-open-mode:19::"""xb"" is not a valid mode for open." +bad-open-mode:20::"""rx"" is not a valid mode for open." +bad-open-mode:27::"""+rUb"" is not a valid mode for open." +bad-open-mode:30::"""aU"" is not a valid mode for open." +bad-open-mode:36::"""Ubr"" is not a valid mode for open." +bad-open-mode:37::"""Ut"" is not a valid mode for open." diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.py new file mode 100644 index 0000000..93fcd06 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.py @@ -0,0 +1,23 @@ +"""Warnings for using open() with an invalid mode string.""" + +NAME = "foo.bar" +open(NAME, "wb") +open(NAME, "w") +open(NAME, "rb") +open(NAME, "x") +open(NAME, "br") +open(NAME, "+r") +open(NAME, "xb") +open(NAME, "rwx") # [bad-open-mode] +open(NAME, "rr") # [bad-open-mode] +open(NAME, "+") # [bad-open-mode] +open(NAME, "xw") # [bad-open-mode] +open(NAME, "ab+") +open(NAME, "a+b") +open(NAME, "+ab") +open(NAME, "+rUb") +open(NAME, "x+b") +open(NAME, "Ua") # [bad-open-mode] +open(NAME, "Ur++") # [bad-open-mode] +open(NAME, "Ut") +open(NAME, "Ubr") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.rc new file mode 100644 index 0000000..504d932 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.0 +except_implementations=PyPy \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.txt new file mode 100644 index 0000000..2539737 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_open_mode_py3.txt @@ -0,0 +1,6 @@ +bad-open-mode:11::"""rwx"" is not a valid mode for open." +bad-open-mode:12::"""rr"" is not a valid mode for open." +bad-open-mode:13::"""+"" is not a valid mode for open." +bad-open-mode:14::"""xw"" is not a valid mode for open." +bad-open-mode:20::"""Ua"" is not a valid mode for open." +bad-open-mode:21::"""Ur++"" is not a valid mode for open." diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_reversed_sequence.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_reversed_sequence.py new file mode 100644 index 0000000..fd90f40 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_reversed_sequence.py @@ -0,0 +1,71 @@ +""" Checks that reversed() receive proper argument """ +# pylint: disable=missing-docstring, useless-object-inheritance +# pylint: disable=too-few-public-methods,no-self-use,no-absolute-import +from collections import deque + +__revision__ = 0 + +class GoodReversed(object): + """ Implements __reversed__ """ + def __reversed__(self): + return [1, 2, 3] + +class SecondGoodReversed(object): + """ Implements __len__ and __getitem__ """ + def __len__(self): + return 3 + + def __getitem__(self, index): + return index + +class BadReversed(object): + """ implements only len() """ + def __len__(self): + return 3 + +class SecondBadReversed(object): + """ implements only __getitem__ """ + def __getitem__(self, index): + return index + +class ThirdBadReversed(dict): + """ dict subclass """ + +def uninferable(seq): + """ This can't be infered at this moment, + make sure we don't have a false positive. + """ + return reversed(seq) + +def test(path): + """ test function """ + seq = reversed() # No argument given + seq = reversed(None) # [bad-reversed-sequence] + seq = reversed([1, 2, 3]) + seq = reversed((1, 2, 3)) + seq = reversed(set()) # [bad-reversed-sequence] + seq = reversed({'a': 1, 'b': 2}) # [bad-reversed-sequence] + seq = reversed(iter([1, 2, 3])) # [bad-reversed-sequence] + seq = reversed(GoodReversed()) + seq = reversed(SecondGoodReversed()) + seq = reversed(BadReversed()) # [bad-reversed-sequence] + seq = reversed(SecondBadReversed()) # [bad-reversed-sequence] + seq = reversed(range(100)) + seq = reversed(ThirdBadReversed()) # [bad-reversed-sequence] + seq = reversed(lambda: None) # [bad-reversed-sequence] + seq = reversed(deque([])) + seq = reversed("123") + seq = uninferable([1, 2, 3]) + seq = reversed(path.split("/")) + return seq + +def test_dict_ancestor_and_reversed(): + """Don't emit for subclasses of dict, with __reversed__ implemented.""" + from collections import OrderedDict + + class Child(dict): + def __reversed__(self): + return reversed(range(10)) + + seq = reversed(OrderedDict()) + return reversed(Child()), seq diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_reversed_sequence.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_reversed_sequence.txt new file mode 100644 index 0000000..19c51a1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_reversed_sequence.txt @@ -0,0 +1,8 @@ +bad-reversed-sequence:43:test:The first reversed() argument is not a sequence +bad-reversed-sequence:46:test:The first reversed() argument is not a sequence +bad-reversed-sequence:47:test:The first reversed() argument is not a sequence +bad-reversed-sequence:48:test:The first reversed() argument is not a sequence +bad-reversed-sequence:51:test:The first reversed() argument is not a sequence +bad-reversed-sequence:52:test:The first reversed() argument is not a sequence +bad-reversed-sequence:54:test:The first reversed() argument is not a sequence +bad-reversed-sequence:55:test:The first reversed() argument is not a sequence diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_staticmethod_argument.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_staticmethod_argument.py new file mode 100644 index 0000000..e73bf3d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_staticmethod_argument.py @@ -0,0 +1,16 @@ +# pylint: disable=missing-docstring, no-staticmethod-decorator, useless-object-inheritance + +class Abcd(object): + + def method1(self): # [bad-staticmethod-argument] + pass + + method1 = staticmethod(method1) + + def method2(cls): # [bad-staticmethod-argument] + pass + + method2 = staticmethod(method2) + + def __init__(self): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_staticmethod_argument.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_staticmethod_argument.txt new file mode 100644 index 0000000..a9d5b46 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_staticmethod_argument.txt @@ -0,0 +1,2 @@ +bad-staticmethod-argument:5:Abcd.method1:Static method with 'self' as first argument +bad-staticmethod-argument:10:Abcd.method2:Static method with 'cls' as first argument \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_thread_instantiation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_thread_instantiation.py new file mode 100644 index 0000000..e7e02ea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_thread_instantiation.py @@ -0,0 +1,8 @@ +# pylint: disable=missing-docstring +import threading + + +threading.Thread(lambda: None).run() # [bad-thread-instantiation] +threading.Thread(None, lambda: None) +threading.Thread(group=None, target=lambda: None).run() +threading.Thread() # [bad-thread-instantiation] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_thread_instantiation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_thread_instantiation.txt new file mode 100644 index 0000000..81fb840 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_thread_instantiation.txt @@ -0,0 +1,2 @@ +bad-thread-instantiation:5::threading.Thread needs the target function +bad-thread-instantiation:8::threading.Thread needs the target function diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_whitespace.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_whitespace.py new file mode 100644 index 0000000..9b32087 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_whitespace.py @@ -0,0 +1,7 @@ +# pylint: disable = invalid-name,missing-docstring,unused-variable,unused-argument +def function(hello): + x, y, z = (1,2,3,) # [bad-whitespace, bad-whitespace] + +AAA =1 # [bad-whitespace] +BBB = 2 # [bad-whitespace] +CCC= 1 # [bad-whitespace] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_whitespace.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_whitespace.txt new file mode 100644 index 0000000..14431c0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bad_whitespace.txt @@ -0,0 +1,15 @@ +bad-whitespace:3::"Exactly one space required after comma + x, y, z = (1,2,3,) # [bad-whitespace, bad-whitespace] + ^" +bad-whitespace:3::"Exactly one space required after comma + x, y, z = (1,2,3,) # [bad-whitespace, bad-whitespace] + ^" +bad-whitespace:5::"Exactly one space required after assignment +AAA =1 # [bad-whitespace] + ^" +bad-whitespace:6::"Exactly one space required after assignment +BBB = 2 # [bad-whitespace] + ^" +bad-whitespace:7::"Exactly one space required before assignment +CCC= 1 # [bad-whitespace] + ^" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bare_except.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bare_except.py new file mode 100644 index 0000000..47a2079 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bare_except.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring, import-error + +try: + 1 + "2" +except: # [bare-except] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bare_except.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bare_except.txt new file mode 100644 index 0000000..ccb7ba9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bare_except.txt @@ -0,0 +1 @@ +bare-except:5::No exception type(s) specified \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/blacklisted_name.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/blacklisted_name.py new file mode 100644 index 0000000..b62c6d2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/blacklisted_name.py @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring + +def baz(): # [blacklisted-name] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/blacklisted_name.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/blacklisted_name.txt new file mode 100644 index 0000000..f0fc9c2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/blacklisted_name.txt @@ -0,0 +1 @@ +blacklisted-name:3:baz:Black listed name "baz" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.py new file mode 100644 index 0000000..c1c953f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.py @@ -0,0 +1,30 @@ +""" Checks for boolean uses of datetime.time. """ +# pylint: disable=superfluous-parens,print-statement,no-absolute-import,consider-using-ternary,simplifiable-if-expression +import datetime + +if datetime.time(0, 0, 0): # [boolean-datetime] + print("datetime.time(0,0,0) is not a bug!") +else: + print("datetime.time(0,0,0) is a bug!") + +if not datetime.time(0, 0, 1): # [boolean-datetime] + print("datetime.time(0,0,1) is not a bug!") +else: + print("datetime.time(0,0,1) is a bug!") + +DATA = not datetime.time(0, 0, 0) # [boolean-datetime] +DATA1 = True if datetime.time(0, 0, 0) else False # [boolean-datetime] +DATA2 = datetime.time(0, 0, 0) or True # [boolean-datetime] +DATA3 = datetime.time(0, 0, 0) and True # [boolean-datetime] +DATA4 = False or True or datetime.time(0, 0, 0) # [boolean-datetime] +DATA5 = False and datetime.time(0, 0, 0) or True # [boolean-datetime] + + +def cant_infer(data): + """ Can't infer what data is """ + hophop = not data + troptrop = True if data else False + toptop = data or True + return hophop, troptrop, toptop + +cant_infer(datetime.time(0, 0, 0)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.rc new file mode 100644 index 0000000..abe8fdf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.5 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.txt new file mode 100644 index 0000000..f3287d4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/boolean_datetime.txt @@ -0,0 +1,8 @@ +boolean-datetime:5::Using datetime.time in a boolean context. +boolean-datetime:10::Using datetime.time in a boolean context. +boolean-datetime:15::Using datetime.time in a boolean context. +boolean-datetime:16::Using datetime.time in a boolean context. +boolean-datetime:17::Using datetime.time in a boolean context. +boolean-datetime:18::Using datetime.time in a boolean context. +boolean-datetime:19::Using datetime.time in a boolean context. +boolean-datetime:20::Using datetime.time in a boolean context. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/broad_except.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/broad_except.py new file mode 100644 index 0000000..f71431e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/broad_except.py @@ -0,0 +1,8 @@ +# pylint: disable=missing-docstring +from __future__ import print_function +__revision__ = 0 + +try: + __revision__ += 1 +except Exception: # [broad-except] + print('error') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/broad_except.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/broad_except.txt new file mode 100644 index 0000000..bb44550 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/broad_except.txt @@ -0,0 +1 @@ +broad-except:7::Catching too general exception Exception \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.py new file mode 100644 index 0000000..8904f6f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.py @@ -0,0 +1,56 @@ +# pylint: disable=missing-docstring,too-few-public-methods,import-error +from UNINFERABLE import ImportedMetaclass + + +class Meta(type): + pass + + +class Class(metaclass=Meta): + pass + + +def func_scope(): + class Meta2(type): + pass + + class Class2(metaclass=Meta2): + pass + + return Class2 + + +class ClassScope: + class Meta3(type): + pass + + class Class3(metaclass=Meta3): + pass + + instance = Class3() + + +def mixed_scopes(): + class ClassM(metaclass=Meta): + pass + + return ClassM + + +def imported_and_nested_scope1(): + class ClassImp1(metaclass=ImportedMetaclass): + pass + + class ClassImp2(metaclass=ImportedMetaclass): + pass + + return ClassImp1, ClassImp2 + + +def imported_and_nested_scope2(): + from UNINFERABLE import ImportedMetaclass2 + + class ClassImp3(metaclass=ImportedMetaclass2): + pass + + return ClassImp3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/bugfix_local_scope_metaclass_1177.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/cellvar_escaping_loop.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/cellvar_escaping_loop.py new file mode 100644 index 0000000..23c6b4b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/cellvar_escaping_loop.py @@ -0,0 +1,120 @@ +# pylint: disable=print-statement +"""Tests for loopvar-in-closure.""" +from __future__ import print_function + +def good_case(): + """No problems here.""" + lst = [] + for i in range(10): + lst.append(i) + + +def good_case2(): + """No problems here.""" + return [i for i in range(10)] + + +def good_case3(): + """No problems here.""" + lst = [] + for i in range(10): + lst.append(lambda i=i: i) + + +def good_case4(): + """No problems here.""" + lst = [] + for i in range(10): + print(i) + lst.append(lambda i: i) + + +def good_case5(): + """No problems here.""" + return (i for i in range(10)) + + +def good_case6(): + """Accept use of the variable inside return.""" + for i in range(10): + if i == 8: + return lambda: i + return lambda: -1 + + +def good_case7(): + """Lambda defined and called in loop.""" + for i in range(10): + print((lambda x: i + x)(1)) + + +def good_case8(): + """Another eager binding of the cell variable.""" + funs = [] + for i in range(10): + def func(bound_i=i): + """Ignore.""" + return bound_i + funs.append(func) + return funs + + +def bad_case(): + """Closing over a loop variable.""" + lst = [] + for i in range(10): + print(i) + lst.append(lambda: i) # [cell-var-from-loop] + + +def bad_case2(): + """Closing over a loop variable.""" + return [lambda: i for i in range(10)] # [cell-var-from-loop] + + +def bad_case3(): + """Closing over variable defined in loop.""" + lst = [] + for i in range(10): + j = i * i + lst.append(lambda: j) # [cell-var-from-loop] + return lst + + +def bad_case4(): + """Closing over variable defined in loop.""" + lst = [] + for i in range(10): + def nested(): + """Nested function.""" + return i**2 # [cell-var-from-loop] + lst.append(nested) + return lst + + +def bad_case5(): + """Problematic case. + + If this function is used as + + >>> [x() for x in bad_case5()] + + it behaves 'as expected', i.e. the result is range(10). + + If it's used with + + >>> lst = list(bad_case5()) + >>> [x() for x in lst] + + the result is [9] * 10 again. + """ + return (lambda: i for i in range(10)) # [cell-var-from-loop] + + +def bad_case6(): + """Closing over variable defined in loop.""" + lst = [] + for i, j in zip(range(10), range(10, 20)): + print(j) + lst.append(lambda: i) # [cell-var-from-loop] + return lst diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/cellvar_escaping_loop.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/cellvar_escaping_loop.txt new file mode 100644 index 0000000..2ac0b58 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/cellvar_escaping_loop.txt @@ -0,0 +1,6 @@ +cell-var-from-loop:67:bad_case.<lambda>:Cell variable i defined in loop +cell-var-from-loop:72:bad_case2.<lambda>:Cell variable i defined in loop +cell-var-from-loop:80:bad_case3.<lambda>:Cell variable j defined in loop +cell-var-from-loop:90:bad_case4.nested:Cell variable i defined in loop +cell-var-from-loop:111:bad_case5.<lambda>:Cell variable i defined in loop +cell-var-from-loop:119:bad_case6.<lambda>:Cell variable i defined in loop diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.py new file mode 100644 index 0000000..bbcbb02 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.py @@ -0,0 +1,70 @@ +""" Various tests for class members access. """ +# pylint: disable=R0903,print-statement,no-absolute-import, metaclass-assignment,import-error,no-init,missing-docstring, wrong-import-order,wrong-import-position, useless-object-inheritance +from missing import Missing +class MyClass(object): + """class docstring""" + + def __init__(self): + """init""" + self.correct = 1 + + def test(self): + """test""" + self.correct += 2 + self.incorrect += 2 # [no-member] + del self.havenot # [no-member] + self.nonexistent1.truc() # [no-member] + self.nonexistent2[1] = 'hehe' # [no-member] + +class XYZMixin(object): + """access to undefined members should be ignored in mixin classes by + default + """ + def __init__(self): + print self.nonexistent + + +class NewClass(object): + """use object.__setattr__""" + def __init__(self): + self.__setattr__('toto', 'tutu') + +from abc import ABCMeta + +class TestMetaclass(object): + """ Test attribute access for metaclasses. """ + __metaclass__ = ABCMeta + +class Metaclass(type): + """ metaclass """ + @classmethod + def test(cls): + """ classmethod """ + +class UsingMetaclass(object): + """ empty """ + __metaclass__ = Metaclass + +TestMetaclass.register(int) +UsingMetaclass.test() +TestMetaclass().register(int) # [no-member] +UsingMetaclass().test() # [no-member] + + +class NoKnownBases(Missing): + """Don't emit no-member if we don't know the bases of a class.""" + +NoKnownBases().lalala() + + +class MetaClass(object): + """Look some methods in the implicit metaclass.""" + + @classmethod + def whatever(cls): + return cls.mro() + cls.missing() # [no-member] + +from collections import namedtuple + +Tuple = namedtuple("Tuple", "field other") +Tuple.field.__doc__ = "A doc for the field." diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.rc new file mode 100644 index 0000000..c4f2e66 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=2.7 +max_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.txt new file mode 100644 index 0000000..3a3be0e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py27.txt @@ -0,0 +1,7 @@ +no-member:14:MyClass.test:Instance of 'MyClass' has no 'incorrect' member:INFERENCE +no-member:15:MyClass.test:Instance of 'MyClass' has no 'havenot' member:INFERENCE +no-member:16:MyClass.test:Instance of 'MyClass' has no 'nonexistent1' member:INFERENCE +no-member:17:MyClass.test:Instance of 'MyClass' has no 'nonexistent2' member:INFERENCE +no-member:50::Instance of 'TestMetaclass' has no 'register' member:INFERENCE +no-member:51::Instance of 'UsingMetaclass' has no 'test' member:INFERENCE +no-member:65:MetaClass.whatever:Class 'MetaClass' has no 'missing' member:INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.py new file mode 100644 index 0000000..50280b9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.py @@ -0,0 +1,68 @@ +""" Various tests for class members access. """ +# pylint: disable=R0903,import-error,no-init,missing-docstring, wrong-import-position,wrong-import-order, useless-object-inheritance +from missing import Missing +class MyClass(object): + """class docstring""" + + def __init__(self): + """init""" + self.correct = 1 + + def test(self): + """test""" + self.correct += 2 + self.incorrect += 2 # [no-member] + del self.havenot # [no-member] + self.nonexistent1.truc() # [no-member] + self.nonexistent2[1] = 'hehe' # [no-member] + +class XYZMixin(object): + """access to undefined members should be ignored in mixin classes by + default + """ + def __init__(self): + print(self.nonexistent) + + +class NewClass(object): + """use object.__setattr__""" + def __init__(self): + self.__setattr__('toto', 'tutu') + +from abc import ABCMeta + +class TestMetaclass(object, metaclass=ABCMeta): + """ Test attribute access for metaclasses. """ + +class Metaclass(type): + """ metaclass """ + @classmethod + def test(cls): + """ classmethod """ + +class UsingMetaclass(object, metaclass=Metaclass): + """ empty """ + +TestMetaclass.register(int) +UsingMetaclass.test() +TestMetaclass().register(int) # [no-member] +UsingMetaclass().test() # [no-member] + + +class NoKnownBases(Missing): + """Don't emit no-member if we don't know the bases of a class.""" + +NoKnownBases().lalala() + + +class MetaClass(object): + """Look some methods in the implicit metaclass.""" + + @classmethod + def whatever(cls): + return cls.mro() + cls.missing() # [no-member] + +from collections import namedtuple + +Tuple = namedtuple("Tuple", "field other") +Tuple.field.__doc__ = "A doc for the field." diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.txt new file mode 100644 index 0000000..b6d369f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_members_py30.txt @@ -0,0 +1,7 @@ +no-member:14:MyClass.test:Instance of 'MyClass' has no 'incorrect' member:INFERENCE +no-member:15:MyClass.test:Instance of 'MyClass' has no 'havenot' member:INFERENCE +no-member:16:MyClass.test:Instance of 'MyClass' has no 'nonexistent1' member:INFERENCE +no-member:17:MyClass.test:Instance of 'MyClass' has no 'nonexistent2' member:INFERENCE +no-member:48::Instance of 'TestMetaclass' has no 'register' member:INFERENCE +no-member:49::Instance of 'UsingMetaclass' has no 'test' member:INFERENCE +no-member:63:MetaClass.whatever:Class 'MetaClass' has no 'missing' member:INFERENCE \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_scope.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_scope.py new file mode 100644 index 0000000..309ebd6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_scope.py @@ -0,0 +1,22 @@ +# pylint: disable=R0903,W0232, useless-object-inheritance +"""check for scope problems""" + +__revision__ = None + +class Well(object): + """well""" + attr = 42 + get_attr = lambda arg=attr: arg * 24 + # +1: [used-before-assignment] + get_attr_bad = lambda arg=revattr: revattr * 42 + revattr = 24 + bad_lambda = lambda: get_attr_bad # [undefined-variable] + + class Data(object): + """base hidden class""" + class Sub(Data): + """whaou, is Data found???""" + attr = Data() # [undefined-variable] + def func(self): + """check Sub is not defined here""" + return Sub(), self # [undefined-variable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_scope.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_scope.txt new file mode 100644 index 0000000..ea6c45a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/class_scope.txt @@ -0,0 +1,4 @@ +used-before-assignment:11:Well.<lambda>:Using variable 'revattr' before assignment +undefined-variable:13:Well.<lambda>:Undefined variable 'get_attr_bad' +undefined-variable:19:Well.Sub:Undefined variable 'Data' +undefined-variable:22:Well.func:Undefined variable 'Sub' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/comparison_with_callable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/comparison_with_callable.py new file mode 100644 index 0000000..ea7024c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/comparison_with_callable.py @@ -0,0 +1,60 @@ +# pylint: disable = blacklisted-name, missing-docstring, useless-return, misplaced-comparison-constant, invalid-name, no-self-use, line-too-long, useless-object-inheritance +def foo(): + return None + +def goo(): + return None + +if foo == 786: # [comparison-with-callable] + pass + +if 666 == goo: # [comparison-with-callable] + pass + +if foo == goo: + pass + +if foo() == goo(): + pass + + +class FakeClass(object): + def __init__(self): + self._fake_prop = 'fake it till you make it!!' + + def fake_method(self): + return '666 - The Number of the Beast' + + @property + def fake_property(self): + return self._fake_prop + + @fake_property.setter + def fake_property(self, prop): + self._fake_prop = prop + +obj1 = FakeClass() +obj2 = FakeClass() + +if obj1.fake_method == obj2.fake_method: + pass + +if obj1.fake_property != obj2.fake_property: # property although is function but is called without parenthesis + pass + +if obj1.fake_method != foo: + pass + +if obj1.fake_method != 786: # [comparison-with-callable] + pass + +if obj1.fake_method != obj2.fake_property: # [comparison-with-callable] + pass + +if 666 == 786: + pass + +a = 666 +b = 786 +if a == b: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/comparison_with_callable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/comparison_with_callable.txt new file mode 100644 index 0000000..87eefb1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/comparison_with_callable.txt @@ -0,0 +1,5 @@ +comparison-with-callable:8::Comparing against a callable, did you omit the parenthesis? +comparison-with-callable:11::Comparing against a callable, did you omit the parenthesis? +comparison-with-callable:45::Comparing against a callable, did you omit the parenthesis? +comparison-with-callable:48::Comparing against a callable, did you omit the parenthesis? +comparison-with-callable:51::Comparing against a callable, did you omit the parenthesis? diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.py new file mode 100644 index 0000000..4235199 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.py @@ -0,0 +1,16 @@ +"""Test for the confidence filter.""" +from __future__ import print_function +# pylint: disable=useless-object-inheritance + +class Client(object): + """use provider class""" + + def __init__(self): + self.set_later = 0 + + def set_set_later(self, value): + """set set_later attribute (introduce an inference ambiguity)""" + self.set_later = value + +print(Client().set_later.lower()) +print(Client().foo) # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.rc new file mode 100644 index 0000000..74953b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.rc @@ -0,0 +1,3 @@ +[Messages Control] +disable=no-init,too-few-public-methods,undefined-variable,print-statement +confidence=INFERENCE,HIGH,UNDEFINED diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.txt new file mode 100644 index 0000000..3dbb2ea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confidence_filter.txt @@ -0,0 +1 @@ +no-member:16::Instance of 'Client' has no 'foo' member:INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confusing_with_statement.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confusing_with_statement.py new file mode 100644 index 0000000..7b8d494 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confusing_with_statement.py @@ -0,0 +1,27 @@ +# pylint: disable=undefined-variable,not-context-manager,missing-docstring + +# both context managers are named +with one as first, two as second: + pass + +# first matched as tuple; this is ok +with one as (first, second), third: + pass + +# the first context manager doesn't have as name +with one, two as second: + pass + +# the second is a function call; this is ok +with one as first, two(): + pass + +# nested with statements; make sure no message is emitted +# this could be a false positive on Py2 +with one as first: + with two: + pass + +# ambiguous looking with statement +with one as first, two: # [confusing-with-statement] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confusing_with_statement.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confusing_with_statement.txt new file mode 100644 index 0000000..750ad71 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/confusing_with_statement.txt @@ -0,0 +1 @@ +confusing-with-statement:26::Following "as" with another context manager looks like a tuple. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_iterating_dictionary.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_iterating_dictionary.py new file mode 100644 index 0000000..180ee3b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_iterating_dictionary.py @@ -0,0 +1,38 @@ +# pylint: disable=missing-docstring, expression-not-assigned, too-few-public-methods, no-member, import-error, no-self-use, line-too-long, useless-object-inheritance + +from unknown import Unknown + + +class CustomClass(object): + def keys(self): + return [] + +for key in Unknown().keys(): + pass +for key in Unknown.keys(): + pass +for key in dict.keys(): + pass +for key in {}.values(): + pass +for key in {}.key(): + pass +for key in CustomClass().keys(): + pass + +[key for key in {}.keys()] # [consider-iterating-dictionary] +(key for key in {}.keys()) # [consider-iterating-dictionary] +{key for key in {}.keys()} # [consider-iterating-dictionary] +{key: key for key in {}.keys()} # [consider-iterating-dictionary] +COMP1 = [key for key in {}.keys()] # [consider-iterating-dictionary] +COMP2 = (key for key in {}.keys()) # [consider-iterating-dictionary] +COMP3 = {key for key in {}.keys()} # [consider-iterating-dictionary] +COMP4 = {key: key for key in {}.keys()} # [consider-iterating-dictionary] +for key in {}.keys(): # [consider-iterating-dictionary] + pass + +# Issue #1247 +DICT = {'a': 1, 'b': 2} +COMP1 = [k * 2 for k in DICT.keys()] + [k * 3 for k in DICT.keys()] # [consider-iterating-dictionary,consider-iterating-dictionary] +COMP2, COMP3 = [k * 2 for k in DICT.keys()], [k * 3 for k in DICT.keys()] # [consider-iterating-dictionary,consider-iterating-dictionary] +SOME_TUPLE = ([k * 2 for k in DICT.keys()], [k * 3 for k in DICT.keys()]) # [consider-iterating-dictionary,consider-iterating-dictionary] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_iterating_dictionary.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_iterating_dictionary.txt new file mode 100644 index 0000000..bd596eb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_iterating_dictionary.txt @@ -0,0 +1,15 @@ +consider-iterating-dictionary:23::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:24::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:25::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:26::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:27::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:28::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:29::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:30::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:31::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:36::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:36::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:37::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:37::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:38::Consider iterating the dictionary directly instead of calling .keys() +consider-iterating-dictionary:38::Consider iterating the dictionary directly instead of calling .keys() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_join.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_join.py new file mode 100644 index 0000000..24cd6dd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_join.py @@ -0,0 +1,126 @@ +# pylint: disable=missing-docstring,invalid-name,undefined-variable,multiple-statements + +# Variations of 'result' +result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = 'header' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = another_result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +another_result = result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = 0 # result is not a string +for number in ['1', '2', '3']: + result += number + +RESULT = '' # wrong name / initial variable missing +for number in ['1', '2', '3']: + result += [number] + +string_variable = '' +result = string_variable # type of 'result' not obviously a string +for number in ['1', '2', '3']: + result += number + +result = '' +another_result = '' # result defined too early +for number in ['1', '2', '3']: + result += [number] + +for number in ['1', '2', '3']: # 'result'-definition missing + result += number + + +# Variations of 'number' +result = '' # no concatenation (iterator-name differs) +for name in ['1', '2', '3']: + result += number + +result = '' # no concatenation (iterator-name differs) +for _ in ['1', '2', '3']: + result += number +# 'exprlist' is not a single name +for index, number in ['1', '2', '3']: + result += number + + +# Variations of 'iterable' +result = '' +for number in []: + result += number # [consider-using-join] + +result = '' +for number in "a text": + result += number # [consider-using-join] + +result = '' +for number in [1, 2, 3]: + result += number # [consider-using-join] + +a_list = [1, 2, 3] +result = '' +for number in a_list: + result += number # [consider-using-join] + +result = '' +for number in ['1', '2', '3']: + result += number # [consider-using-join] + +result = '' +for number in undefined_iterable: + result += number # [consider-using-join] + + +# Variations of loop-body +result = '' # addition is not the only part of the body +for number in ['1', '2', '3']: + print(number) + result += number + +result = '' # addition is not the only part of the body +for number in ['1', '2', '3']: + result += number + print(number) + +result = '' # augmented addition is not a simple one +for number in ['1', '2', '3']: + result += '4' + number + +result = '' # assignment is not augmented +for number in ['1', '2', '3']: + result = number + +result = '' # augmented assignment is not an addition +for number in ['1', '2', '3']: + result -= number + +result = '' # addition is not the 'number'-iterable +for number in ['1', '2', '3']: + result += another_number + +result = '' +for number in ['1', '2', '3']: result += number # [consider-using-join] + +result = '' +for number in ['1']: + result.result += number + +# Does not emit if the body is more complex +result = {'context': 1} +result['context'] = 0 +for number in ['1']: + result1 = 42 + int(number) + result['context'] += result1 * 24 + +# Does not crash if the previous sibling does not have AssignNames +result['context'] = 0 +for number in ['1']: + result['context'] += 24 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_join.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_join.txt new file mode 100644 index 0000000..e550b2b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_join.txt @@ -0,0 +1,11 @@ +consider-using-join:6::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:10::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:14::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:18::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:58::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:62::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:66::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:71::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:75::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:79::Consider using str.join(sequence) for concatenating strings from an iterable +consider-using-join:110::Consider using str.join(sequence) for concatenating strings from an iterable \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_merging_isinstance.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_merging_isinstance.py new file mode 100644 index 0000000..34068d9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_merging_isinstance.py @@ -0,0 +1,37 @@ +"""Checks use of consider-merging-isinstance""" +# pylint:disable=line-too-long + + +def isinstances(): + "Examples of isinstances" + var = range(10) + + # merged + if isinstance(var[1], (int, float)): + pass + result = isinstance(var[2], (int, float)) + + # not merged + if isinstance(var[3], int) or isinstance(var[3], float) or isinstance(var[3], list) and True: # [consider-merging-isinstance] + pass + result = isinstance(var[4], int) or isinstance(var[4], float) or isinstance(var[5], list) and False # [consider-merging-isinstance] + + result = isinstance(var[5], int) or True or isinstance(var[5], float) # [consider-merging-isinstance] + + infered_isinstance = isinstance + result = infered_isinstance(var[6], int) or infered_isinstance(var[6], float) or infered_isinstance(var[6], list) and False # [consider-merging-isinstance] + result = isinstance(var[10], str) or isinstance(var[10], int) and var[8] * 14 or isinstance(var[10], float) and var[5] * 14.4 or isinstance(var[10], list) # [consider-merging-isinstance] + result = isinstance(var[11], int) or isinstance(var[11], int) or isinstance(var[11], float) # [consider-merging-isinstance] + + result = isinstance(var[20]) + result = isinstance() + + # Combination merged and not merged + result = isinstance(var[12], (int, float)) or isinstance(var[12], list) # [consider-merging-isinstance] + + # not merged but valid + result = isinstance(var[5], int) and var[5] * 14 or isinstance(var[5], float) and var[5] * 14.4 + result = isinstance(var[7], int) or not isinstance(var[7], float) + result = isinstance(var[6], int) or isinstance(var[7], float) + result = isinstance(var[6], int) or isinstance(var[7], int) + return result diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_merging_isinstance.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_merging_isinstance.txt new file mode 100644 index 0000000..a2c5338 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_merging_isinstance.txt @@ -0,0 +1,7 @@ +consider-merging-isinstance:15:isinstances:Consider merging these isinstance calls to isinstance(var[3], (float, int)) +consider-merging-isinstance:17:isinstances:Consider merging these isinstance calls to isinstance(var[4], (float, int)) +consider-merging-isinstance:19:isinstances:Consider merging these isinstance calls to isinstance(var[5], (float, int)) +consider-merging-isinstance:22:isinstances:Consider merging these isinstance calls to isinstance(var[6], (float, int)) +consider-merging-isinstance:23:isinstances:Consider merging these isinstance calls to isinstance(var[10], (list, str)) +consider-merging-isinstance:24:isinstances:Consider merging these isinstance calls to isinstance(var[11], (float, int)) +consider-merging-isinstance:30:isinstances:Consider merging these isinstance calls to isinstance(var[12], (float, int, list)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_swap_variables.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_swap_variables.py new file mode 100644 index 0000000..e332077 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_swap_variables.py @@ -0,0 +1,25 @@ +# pylint: disable=missing-docstring,invalid-name,using-constant-test + +a, b, c, d = 'a b c d'.split() + +temp = a # [consider-swap-variables] +a = b +b = temp + +temp = a # only simple swaps are reported +a = b +if True: + b = a + +temp = a # this is no swap +a = b +b = a + +temp = a, b # complex swaps are ignored +a, b = c, d +c, d = temp + +temp = a # [consider-swap-variables] +a = b # longer swap circles are only reported once +b = temp +temp = a diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_swap_variables.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_swap_variables.txt new file mode 100644 index 0000000..3a232fd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_swap_variables.txt @@ -0,0 +1,2 @@ +consider-swap-variables:5::Consider using tuple unpacking for swapping variables +consider-swap-variables:22::Consider using tuple unpacking for swapping variables \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_dict_comprehension.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_dict_comprehension.py new file mode 100644 index 0000000..3a1538c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_dict_comprehension.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring, invalid-name + +numbers = [1, 2, 3, 4, 5, 6] + +dict() + +dict([]) + +dict([(number, number*2) for number in numbers]) # [consider-using-dict-comprehension] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_dict_comprehension.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_dict_comprehension.txt new file mode 100644 index 0000000..206351e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_dict_comprehension.txt @@ -0,0 +1 @@ +consider-using-dict-comprehension:9::Consider using a dictionary comprehension \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_enumerate.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_enumerate.py new file mode 100644 index 0000000..c7800b8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_enumerate.py @@ -0,0 +1,67 @@ +"""Emit a message for iteration through range and len is encountered.""" + +# pylint: disable=missing-docstring, import-error, useless-object-inheritance, unsubscriptable-object, too-few-public-methods + +def bad(): + iterable = [1, 2, 3] + for obj in range(len(iterable)): # [consider-using-enumerate] + yield iterable[obj] + for obj in range(0, len(iterable)): # [consider-using-enumerate] + yield iterable[obj] + + +class Bad(object): + + def __iter__(self): + iterable = [1, 2, 3] + for i in range(len(iterable)): # [consider-using-enumerate] + yield iterable[i] + + def test(self): + for i in range(len(self)): # [consider-using-enumerate] + yield self[i] + + +def good(): + iterable = other_obj = [1, 2, 3] + total = 0 + for obj in range(len(iterable)): + total += obj + yield total + yield iterable[obj + 1: 2] + yield iterable[len(obj)] + for obj in iterable: + yield iterable[obj - 1] + + for index, obj in enumerate(iterable): + yield iterable[index] + for index in range(0, 10): + yield iterable[index + 1] + for index in range(10): + yield iterable[index] + for index in range(len([1, 2, 3, 4])): + yield index + for index in range(1, len(iterable)): + yield index + for index in range(len(iterable)): + yield [1, 2, 3][index] + yield len([1, 2, 3]) + for index in range(len(iterable)): + yield other_obj[index] + + from unknown import unknown + for index in range(unknown(iterable)): + yield iterable[index] + + for index in range(len(iterable)): + def test(iterable): + return iterable[index] + yield test([1, 2, 3]) + + +class Good(object): + + def __iter__(self): + # Should not suggest enumerate on self + for i in range(len(self)): + yield self[i] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_enumerate.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_enumerate.txt new file mode 100644 index 0000000..9cbf330 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_enumerate.txt @@ -0,0 +1,4 @@ +consider-using-enumerate:7:bad:Consider using enumerate instead of iterating with range and len +consider-using-enumerate:9:bad:Consider using enumerate instead of iterating with range and len +consider-using-enumerate:17:Bad.__iter__:Consider using enumerate instead of iterating with range and len +consider-using-enumerate:21:Bad.test:Consider using enumerate instead of iterating with range and len diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_get.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_get.py new file mode 100644 index 0000000..8c5c689 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_get.py @@ -0,0 +1,90 @@ +# pylint: disable=missing-docstring,invalid-name,using-constant-test,invalid-sequence-index,undefined-variable +dictionary = dict() +key = 'key' + +if 'key' in dictionary: # [consider-using-get] + variable = dictionary['key'] + +if 'key' in dictionary: # [consider-using-get] + variable = dictionary['key'] +else: + variable = 'default' + +if key in dictionary: # [consider-using-get] + variable = dictionary[key] + +if 'key' in dictionary: # not accessing the dictionary in assignment + variable = "string" + +if 'key' in dictionary: # is a match, but not obvious and we ignore it for now + variable = dictionary[key] + +if 'key1' in dictionary: # dictionary querried for wrong key + variable = dictionary['key2'] + +if 'key' in dictionary: # body is not pure + variable = dictionary['key'] + print('found') + +if 'key' in dictionary: # body is not pure + variable = dictionary['key'] + print('found') +else: + variable = 'default' + +if 'key' in dictionary1: # different dictionaries + variable = dictionary2['key'] +else: + variable = 'default' + +if 'key' in dictionary: # body is not pure + variable = dictionary['key'] +else: + variable = 'default' + print('found') + +if 'key' in dictionary: # different variables + variable1 = dictionary['key'] +else: + variable2 = 'default' + +if 'key' in dictionary: # assignment is not simple + variable1 = variable2 = dictionary['key'] + +if 'key' in dictionary: # assignment is not simple + variable1 = dictionary['key'] +else: + variable1 = variable2 = "default" + +if 'word' in 'text': + variable = 'text'['word'] # already bogus, but to assert that this only works with dictionaries + +if 'word' in dictionary: + variable = 'dictionary'['word'] + +if 'key1' in dictionary: # not the simple case + variable = dictionary['key1'] +elif 'key2' in dictionary: # [consider-using-get] + variable = dictionary['key2'] +else: + variable = 'default' + +if 'key' in dictionary and bool(key): # not a simple compare + variable = dictionary['key1'] +else: + variable = 'default' + +if bool(key) and 'key' in dictionary: # not a simple compare + variable = dictionary['key1'] +else: + variable = 'default' + + +d1 = {'foo': None} +d2 = {} +# Cannot be represented as using .get() +if 'foo' in d1: + d2['bar'] = d1['foo'] + +if 'key' in dictionary: + variable = dictionary[1:] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_get.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_get.txt new file mode 100644 index 0000000..012ba0a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_get.txt @@ -0,0 +1,4 @@ +consider-using-get:5::Consider using dict.get for getting values from a dict if a key is present or a default if not +consider-using-get:8::Consider using dict.get for getting values from a dict if a key is present or a default if not +consider-using-get:13::Consider using dict.get for getting values from a dict if a key is present or a default if not +consider-using-get:67::Consider using dict.get for getting values from a dict if a key is present or a default if not diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_in.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_in.py new file mode 100644 index 0000000..fb68ac5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_in.py @@ -0,0 +1,46 @@ +# pylint: disable=missing-docstring, invalid-name, pointless-statement, misplaced-comparison-constant, undefined-variable, literal-comparison, line-too-long, unneeded-not + +value = value1 = 1 +value2 = 2 +a_set = {1, 2, 3} +a_list = [1, 2, 3] +a_str = '1' + +# Positive +value == 1 or value == 1 # [consider-using-in] +value == 1 or value == 2 # [consider-using-in] +'value' == value or 'value' == value # [consider-using-in] +value == 1 or value == undef_value # [consider-using-in] +value == 1 or value == 2 or value == 3 # [consider-using-in] +value == '2' or value == 1 # [consider-using-in] +1 == value or 2 == value # [consider-using-in] +1 == value or value == 2 # [consider-using-in] +value == 1 or value == a_list # [consider-using-in] +value == a_set or value == a_list or value == a_str # [consider-using-in] +value != 1 and value != 2 # [consider-using-in] +value1 == value2 or value2 == value1 # [consider-using-in] +a_list == [1, 2, 3] or a_list == [] # [consider-using-in] + +# Negative +value != 1 or value != 2 # not a "not in"-case because of "or" +value == 1 and value == 2 # not a "in"-case because of "and" +value == 1 and value == 2 or value == 3 # not only 'or's +value == 1 or value == 2 or 3 < value < 4 # not only '==' +value == 1 # value not checked against multiple values +value == 1 or value == 2 or value == 3 and value == 4 # not all checks are concatenated with 'or' +value == 1 or 2 < value < 3 # length of 'ops' != 1 for second check +value is 1 or value is 2 # 'in' compares using '==' not 'is' and therefore not considered +not value == 1 and not value == 2 +value1 == 1 or value2 == 2 # different variables and only one comparison for each +value1 == value2 == 1 or value1 == 2 # not checking multi-compares for '==' +value1 != 1 == value2 and value2 != value1 != 2 # not checking multi-compares for '!=' +value1 == 1 or value1 == value2 or value2 == 3 # value1 or value2 do not occur in every check +value1 == 1 or value1 == 2 or value2 == 1 or value2 == 2 # value1 or value2 do not occur in every check +'value' == 1 or 'value' == 2 # only detect variables for now + + +def oops(): + return 5 / 0 + + +some_value = value == 4 or value == 5 or value == oops() # We only look for names and constants diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_in.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_in.txt new file mode 100644 index 0000000..1093ea2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_in.txt @@ -0,0 +1,13 @@ +consider-using-in:10::Consider merging these comparisons with "in" to 'value in (1,)' +consider-using-in:11::Consider merging these comparisons with "in" to 'value in (1, 2)' +consider-using-in:12::Consider merging these comparisons with "in" to "value in ('value',)" +consider-using-in:13::Consider merging these comparisons with "in" to 'value in (1, undef_value)' +consider-using-in:14::Consider merging these comparisons with "in" to 'value in (1, 2, 3)' +consider-using-in:15::Consider merging these comparisons with "in" to "value in ('2', 1)" +consider-using-in:16::Consider merging these comparisons with "in" to 'value in (1, 2)' +consider-using-in:17::Consider merging these comparisons with "in" to 'value in (1, 2)' +consider-using-in:18::Consider merging these comparisons with "in" to 'value in (1, a_list)' +consider-using-in:19::Consider merging these comparisons with "in" to 'value in (a_set, a_list, a_str)' +consider-using-in:20::Consider merging these comparisons with "in" to 'value not in (1, 2)' +consider-using-in:21::Consider merging these comparisons with "in" to 'value1 in (value2,)' +consider-using-in:22::Consider merging these comparisons with "in" to 'a_list in ([1, 2, 3], [])' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_set_comprehension.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_set_comprehension.py new file mode 100644 index 0000000..2c42ef2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_set_comprehension.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring, invalid-name + +numbers = [1, 2, 3, 4, 5, 6] + +set() + +set([]) + +set([number for number in numbers]) # [consider-using-set-comprehension] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_set_comprehension.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_set_comprehension.txt new file mode 100644 index 0000000..225d37a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/consider_using_set_comprehension.txt @@ -0,0 +1 @@ +consider-using-set-comprehension:9::Consider using a set comprehension \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/continue_in_finally.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/continue_in_finally.py new file mode 100644 index 0000000..d40d63c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/continue_in_finally.py @@ -0,0 +1,24 @@ +"""Test that `continue` is catched when met inside a `finally` clause.""" + +# pylint: disable=missing-docstring, lost-exception, broad-except + +while True: + try: + pass + finally: + continue # [continue-in-finally] + +while True: + try: + pass + finally: + break + +while True: + try: + pass + except Exception: + pass + else: + continue + \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/continue_in_finally.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/continue_in_finally.txt new file mode 100644 index 0000000..cb2ee16 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/continue_in_finally.txt @@ -0,0 +1 @@ +continue-in-finally:9::'continue' not supported inside 'finally' clause diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/control_pragmas.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/control_pragmas.py new file mode 100644 index 0000000..993f9a5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/control_pragmas.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring + + +def test_pragma(): + """Test that the control pragmas are not too eager to consume the entire line + + We should stop either at: + - ; or # + - or at the end of line + """ + # noqa: E501 # pylint: disable=unused-variable #nosec + variable = 1 + + # noqa # pylint: disable=undefined-variable,no-member; don't trigger + other_variable = some_variable + variable.member + + # noqa # pylint: disable=unbalanced-tuple-unpacking,no-member # no trigger + first, second = some_other_variable + return first + other_variable.method() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/control_pragmas.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/control_pragmas.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/crash_missing_module_type.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/crash_missing_module_type.py new file mode 100644 index 0000000..0f42b4b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/crash_missing_module_type.py @@ -0,0 +1,18 @@ +""" Test for a crash found in +https://bitbucket.org/logilab/astroid/issue/45/attributeerror-module-object-has-no#comment-11944673 +""" +# pylint: disable=no-init, invalid-name, too-few-public-methods, redefined-outer-name, useless-object-inheritance +def decor(trop): + """ decorator """ + return trop + +class Foo(object): + """ Class """ + @decor + def prop(self): + """ method """ + return self + +if __name__ == '__main__': + trop = Foo() + trop.prop = 42 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/crash_missing_module_type.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/crash_missing_module_type.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ctor_arguments.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ctor_arguments.py new file mode 100644 index 0000000..d9a9944 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ctor_arguments.py @@ -0,0 +1,104 @@ +"""Test function argument checker on __init__ + +Based on test/functional/arguments.py +""" +# pylint: disable=C0111,R0903,W0231, useless-object-inheritance + + +class Class1Arg(object): + def __init__(self, first_argument): + """one argument function""" + +class Class3Arg(object): + def __init__(self, first_argument, second_argument, third_argument): + """three arguments function""" + +class ClassDefaultArg(object): + def __init__(self, one=1, two=2): + """function with default value""" + +class Subclass1Arg(Class1Arg): + pass + +class ClassAllArgs(Class1Arg): + def __init__(self, *args, **kwargs): + pass + +class ClassMultiInheritance(Class1Arg, Class3Arg): + pass + +class ClassNew(object): + def __new__(cls, first_argument, kwarg=None): + return first_argument, kwarg + +Class1Arg(420) +Class1Arg() # [no-value-for-parameter] +Class1Arg(1337, 347) # [too-many-function-args] + +Class3Arg(420, 789) # [no-value-for-parameter] +# +1:[no-value-for-parameter,no-value-for-parameter,no-value-for-parameter] +Class3Arg() +Class3Arg(1337, 347, 456) +Class3Arg('bab', 'bebe', None, 5.6) # [too-many-function-args] + +ClassDefaultArg(1, two=5) +ClassDefaultArg(two=5) + +Class1Arg(bob=4) # [no-value-for-parameter,unexpected-keyword-arg] +ClassDefaultArg(1, 4, coin="hello") # [unexpected-keyword-arg] + +ClassDefaultArg(1, one=5) # [redundant-keyword-arg] + +Subclass1Arg(420) +Subclass1Arg() # [no-value-for-parameter] +Subclass1Arg(1337, 347) # [too-many-function-args] + +ClassAllArgs() +ClassAllArgs(1, 2, 3, even=4, more=5) + +ClassMultiInheritance(1) +ClassMultiInheritance(1, 2, 3) # [too-many-function-args] + +ClassNew(1, kwarg=1) +ClassNew(1, 2, 3) # [too-many-function-args] +ClassNew(one=2) # [no-value-for-parameter,unexpected-keyword-arg] + + +class Metaclass(type): + def __new__(cls, name, bases, namespace): + return type.__new__(cls, name, bases, namespace) + +def with_metaclass(meta, base=object): + """Create a new type that can be used as a metaclass.""" + return meta("NewBase", (base, ), {}) + +class ClassWithMeta(with_metaclass(Metaclass)): + pass + +ClassWithMeta() + + +class BuiltinExc(Exception): + def __init__(self, val=True): + self.val = val + +BuiltinExc(42, 24, badarg=1) # [too-many-function-args,unexpected-keyword-arg] + + +class Clsmethod(object): + def __init__(self, first, second): + self.first = first + self.second = second + + @classmethod + def from_nothing(cls): + return cls(1, 2, 3, 4) # [too-many-function-args] + + @classmethod + def from_nothing1(cls): + return cls() # [no-value-for-parameter,no-value-for-parameter] + + @classmethod + def from_nothing2(cls): + # +1: [no-value-for-parameter,unexpected-keyword-arg] + return cls(1, not_argument=2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ctor_arguments.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ctor_arguments.txt new file mode 100644 index 0000000..639e92c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ctor_arguments.txt @@ -0,0 +1,24 @@ +no-value-for-parameter:35::No value for argument 'first_argument' in constructor call +too-many-function-args:36::Too many positional arguments for constructor call +no-value-for-parameter:38::No value for argument 'third_argument' in constructor call +no-value-for-parameter:40::No value for argument 'first_argument' in constructor call +no-value-for-parameter:40::No value for argument 'second_argument' in constructor call +no-value-for-parameter:40::No value for argument 'third_argument' in constructor call +too-many-function-args:42::Too many positional arguments for constructor call +no-value-for-parameter:47::No value for argument 'first_argument' in constructor call +unexpected-keyword-arg:47::Unexpected keyword argument 'bob' in constructor call +unexpected-keyword-arg:48::Unexpected keyword argument 'coin' in constructor call +redundant-keyword-arg:50::Argument 'one' passed by position and keyword in constructor call +no-value-for-parameter:53::No value for argument 'first_argument' in constructor call +too-many-function-args:54::Too many positional arguments for constructor call +too-many-function-args:60::Too many positional arguments for constructor call +too-many-function-args:63::Too many positional arguments for constructor call +no-value-for-parameter:64::No value for argument 'first_argument' in constructor call +unexpected-keyword-arg:64::Unexpected keyword argument 'one' in constructor call +too-many-function-args:85::Too many positional arguments for constructor call +unexpected-keyword-arg:85::Unexpected keyword argument 'badarg' in constructor call +too-many-function-args:95:Clsmethod.from_nothing:Too many positional arguments for constructor call +no-value-for-parameter:99:Clsmethod.from_nothing1:"No value for argument 'first' in constructor call" +no-value-for-parameter:99:Clsmethod.from_nothing1:"No value for argument 'second' in constructor call" +no-value-for-parameter:104:Clsmethod.from_nothing2:"No value for argument 'second' in constructor call" +unexpected-keyword-arg:104:Clsmethod.from_nothing2:"Unexpected keyword argument 'not_argument' in constructor call" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.py new file mode 100644 index 0000000..58a22f4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.py @@ -0,0 +1,79 @@ +# pylint: disable=missing-docstring + + +HEHE = {} + +def function1(value=[]): # [dangerous-default-value] + """docstring""" + return value + +def function2(value=HEHE): # [dangerous-default-value] + """docstring""" + return value + +def function3(value): + """docstring""" + return value + +def function4(value=set()): # [dangerous-default-value] + """set is mutable and dangerous.""" + return value + +def function5(value=frozenset()): + """frozenset is immutable and safe.""" + return value + +GLOBAL_SET = set() + +def function6(value=GLOBAL_SET): # [dangerous-default-value] + """set is mutable and dangerous.""" + return value + +def function7(value=dict()): # [dangerous-default-value] + """dict is mutable and dangerous.""" + return value + +def function8(value=list()): # [dangerous-default-value] + """list is mutable and dangerous.""" + return value + +def function9(value=[1, 2, 3, 4]): # [dangerous-default-value] + """list with items should not output item values in error message""" + return value + +def function10(value={'a': 1, 'b': 2}): # [dangerous-default-value] + """dictionaries with items should not output item values in error message""" + return value + +def function11(value=list([1, 2, 3])): # [dangerous-default-value] + """list with items should not output item values in error message""" + return value + +def function12(value=dict([('a', 1), ('b', 2)])): # [dangerous-default-value] + """dictionaries with items should not output item values in error message""" + return value + +OINK = { + 'a': 1, + 'b': 2 +} + +def function13(value=OINK): # [dangerous-default-value] + """dictionaries with items should not output item values in error message""" + return value + +def function14(value=dict([(1, 2), (1, 2, 3)])): # [dangerous-default-value] + """a dictionary which will not be inferred to a syntax AST, but to an + astroid.Instance. + """ + return value + +INVALID_DICT = dict([(1, 2), (1, 2, 3)]) + +def function15(value=INVALID_DICT): # [dangerous-default-value] + """The same situation as function14.""" + return value + +def function16(value={1}): # [dangerous-default-value] + """set literal as default value""" + return value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.rc new file mode 100644 index 0000000..b11e16d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.txt new file mode 100644 index 0000000..92180e9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value.txt @@ -0,0 +1,14 @@ +dangerous-default-value:6:function1:Dangerous default value [] as argument +dangerous-default-value:10:function2:Dangerous default value HEHE (__builtin__.dict) as argument +dangerous-default-value:18:function4:Dangerous default value set() (__builtin__.set) as argument +dangerous-default-value:28:function6:Dangerous default value GLOBAL_SET (__builtin__.set) as argument +dangerous-default-value:32:function7:Dangerous default value dict() (__builtin__.dict) as argument +dangerous-default-value:36:function8:Dangerous default value list() (__builtin__.list) as argument +dangerous-default-value:40:function9:Dangerous default value [] as argument +dangerous-default-value:44:function10:Dangerous default value {} as argument +dangerous-default-value:48:function11:Dangerous default value list() (__builtin__.list) as argument +dangerous-default-value:52:function12:Dangerous default value dict() (__builtin__.dict) as argument +dangerous-default-value:61:function13:Dangerous default value OINK (__builtin__.dict) as argument +dangerous-default-value:65:function14:Dangerous default value dict() (__builtin__.dict) as argument +dangerous-default-value:73:function15:Dangerous default value INVALID_DICT (__builtin__.dict) as argument +dangerous-default-value:77:function16:Dangerous default value set() as argument diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.py new file mode 100644 index 0000000..58a22f4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.py @@ -0,0 +1,79 @@ +# pylint: disable=missing-docstring + + +HEHE = {} + +def function1(value=[]): # [dangerous-default-value] + """docstring""" + return value + +def function2(value=HEHE): # [dangerous-default-value] + """docstring""" + return value + +def function3(value): + """docstring""" + return value + +def function4(value=set()): # [dangerous-default-value] + """set is mutable and dangerous.""" + return value + +def function5(value=frozenset()): + """frozenset is immutable and safe.""" + return value + +GLOBAL_SET = set() + +def function6(value=GLOBAL_SET): # [dangerous-default-value] + """set is mutable and dangerous.""" + return value + +def function7(value=dict()): # [dangerous-default-value] + """dict is mutable and dangerous.""" + return value + +def function8(value=list()): # [dangerous-default-value] + """list is mutable and dangerous.""" + return value + +def function9(value=[1, 2, 3, 4]): # [dangerous-default-value] + """list with items should not output item values in error message""" + return value + +def function10(value={'a': 1, 'b': 2}): # [dangerous-default-value] + """dictionaries with items should not output item values in error message""" + return value + +def function11(value=list([1, 2, 3])): # [dangerous-default-value] + """list with items should not output item values in error message""" + return value + +def function12(value=dict([('a', 1), ('b', 2)])): # [dangerous-default-value] + """dictionaries with items should not output item values in error message""" + return value + +OINK = { + 'a': 1, + 'b': 2 +} + +def function13(value=OINK): # [dangerous-default-value] + """dictionaries with items should not output item values in error message""" + return value + +def function14(value=dict([(1, 2), (1, 2, 3)])): # [dangerous-default-value] + """a dictionary which will not be inferred to a syntax AST, but to an + astroid.Instance. + """ + return value + +INVALID_DICT = dict([(1, 2), (1, 2, 3)]) + +def function15(value=INVALID_DICT): # [dangerous-default-value] + """The same situation as function14.""" + return value + +def function16(value={1}): # [dangerous-default-value] + """set literal as default value""" + return value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.txt new file mode 100644 index 0000000..7571c00 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/dangerous_default_value_py30.txt @@ -0,0 +1,14 @@ +dangerous-default-value:6:function1:Dangerous default value [] as argument +dangerous-default-value:10:function2:Dangerous default value HEHE (builtins.dict) as argument +dangerous-default-value:18:function4:Dangerous default value set() (builtins.set) as argument +dangerous-default-value:28:function6:Dangerous default value GLOBAL_SET (builtins.set) as argument +dangerous-default-value:32:function7:Dangerous default value dict() (builtins.dict) as argument +dangerous-default-value:36:function8:Dangerous default value list() (builtins.list) as argument +dangerous-default-value:40:function9:Dangerous default value [] as argument +dangerous-default-value:44:function10:Dangerous default value {} as argument +dangerous-default-value:48:function11:Dangerous default value list() (builtins.list) as argument +dangerous-default-value:52:function12:Dangerous default value dict() (builtins.dict) as argument +dangerous-default-value:61:function13:Dangerous default value OINK (builtins.dict) as argument +dangerous-default-value:65:function14:Dangerous default value dict() (builtins.dict) as argument +dangerous-default-value:73:function15:Dangerous default value INVALID_DICT (builtins.dict) as argument +dangerous-default-value:77:function16:Dangerous default value set() as argument \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/defined_and_used_on_same_line.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/defined_and_used_on_same_line.py new file mode 100644 index 0000000..a61bcd7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/defined_and_used_on_same_line.py @@ -0,0 +1,29 @@ +"""Check for definitions and usage happening on the same line.""" +#pylint: disable=missing-docstring,multiple-statements,no-absolute-import,parameter-unpacking,wrong-import-position +from __future__ import print_function +print([index + for index in range(10)]) + +print((index + for index in range(10))) + +FILTER_FUNC = lambda x: not x + +def func(xxx): return xxx + +def func2(xxx): return xxx + func2(1) + +import sys; print(sys.exc_info()) + +for i in range(10): print(i) + +j = 4; LAMB = lambda x: x+j + +FUNC4 = lambda a, b: a != b + +# test http://www.logilab.org/ticket/6954: + +with open('f') as f: print(f.read()) + +with open('f') as f, open(f.read()) as g: + print(g.read()) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.py new file mode 100644 index 0000000..92a2e84 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,invalid-name,no-absolute-import + +import functools + +# Don't do this, use a comprehension instead. +assert map(lambda x: x*2, [1, 2, 3]) == [2, 4, 6] # [deprecated-lambda] + +assert filter(lambda x: x != 1, [1, 2, 3]) == [2, 3] # [deprecated-lambda] + +# It's still ok to use map and filter with anything but an inline lambda. +double = lambda x: x * 2 +assert map(double, [1, 2, 3]) == [2, 4, 6] + +# It's also ok to pass lambdas to other functions. +assert functools.reduce(lambda x, y: x * y, [1, 2, 3, 4]) == 24 + +# Or to an undefined function or one with varargs +def f(*a): + return len(a) + +f(lambda x, y: x + y, [1, 2, 3]) + +undefined_function(lambda: 2) # pylint: disable=undefined-variable diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.txt new file mode 100644 index 0000000..78cd9fb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_lambda.txt @@ -0,0 +1,2 @@ +deprecated-lambda:6::map/filter on lambda could be replaced by comprehension +deprecated-lambda:8::map/filter on lambda could be replaced by comprehension diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.py new file mode 100644 index 0000000..3338c24 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.py @@ -0,0 +1,4 @@ +"""Test that getmoduleinfo is deprecated.""" +import inspect + +inspect.getmoduleinfo(inspect) # [deprecated-method] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.rc new file mode 100644 index 0000000..a444ca6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.rc @@ -0,0 +1,3 @@ +[testoptions] +max_pyver=3.6 +min_pyver=3.3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.txt new file mode 100644 index 0000000..9009bbf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_method_getmoduleinfo.txt @@ -0,0 +1 @@ +deprecated-method:4::Using deprecated method getmoduleinfo() \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.py new file mode 100644 index 0000000..ceba1e4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.py @@ -0,0 +1,9 @@ +""" Functional test for deprecated methods in Python 2 """ +# pylint: disable=no-member +import os +import xml.etree.ElementTree + +os.popen2('') # [deprecated-method] +os.popen3('') # [deprecated-method] +os.popen4('') # [deprecated-method] +xml.etree.ElementTree.Element('elem').getchildren() # [deprecated-method] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.txt new file mode 100644 index 0000000..e103818 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py2.txt @@ -0,0 +1,4 @@ +deprecated-method:6::Using deprecated method popen2() +deprecated-method:7::Using deprecated method popen3() +deprecated-method:8::Using deprecated method popen4() +deprecated-method:9::Using deprecated method getchildren() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.py new file mode 100644 index 0000000..d390c8d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.py @@ -0,0 +1,50 @@ +""" Functional tests for method deprecation. """ +# pylint: disable=missing-docstring, super-init-not-called, not-callable +import base64 +import cgi +import inspect +import logging +import nntplib +import platform +import unittest +import xml.etree.ElementTree + + +class MyTest(unittest.TestCase): + def test(self): + self.assert_(True) # [deprecated-method] + +xml.etree.ElementTree.Element('tag').getchildren() # [deprecated-method] +xml.etree.ElementTree.Element('tag').getiterator() # [deprecated-method] +xml.etree.ElementTree.XMLParser('tag', None, None).doctype(None, None, None) # [deprecated-method] +nntplib.NNTP(None).xpath(None) # [deprecated-method] + + +inspect.getargspec(None) # [deprecated-method] +logging.warn("a") # [deprecated-method] +platform.popen([]) # [deprecated-method] +base64.encodestring("42") # [deprecated-method] +base64.decodestring("42") # [deprecated-method] +cgi.escape("a") # [deprecated-method] + + +class SuperCrash(unittest.TestCase): + + def __init__(self): + # should not crash. + super(SuperCrash, self)() + +xml.etree.ElementTree.iterparse(None) + + +class Tests(unittest.TestCase): + + def test_foo(self): + self.assertEquals(2 + 2, 4) # [deprecated-method] + self.assertNotEquals(2 + 2, 4) # [deprecated-method] + self.assertAlmostEquals(2 + 2, 4) # [deprecated-method] + self.assertNotAlmostEquals(2 + 2, 4) # [deprecated-method] + self.assert_("abc" == "2") # [deprecated-method] + + self.assertRaisesRegex(ValueError, "exception") + self.assertRegex("something", r".+") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.rc new file mode 100644 index 0000000..28c99bc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.txt new file mode 100644 index 0000000..ad58834 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py3.txt @@ -0,0 +1,16 @@ +deprecated-method:15:MyTest.test:Using deprecated method assert_() +deprecated-method:17::Using deprecated method getchildren() +deprecated-method:18::Using deprecated method getiterator() +deprecated-method:19::Using deprecated method doctype() +deprecated-method:20::Using deprecated method xpath() +deprecated-method:23::Using deprecated method getargspec() +deprecated-method:24::Using deprecated method warn() +deprecated-method:25::Using deprecated method popen() +deprecated-method:26::Using deprecated method encodestring() +deprecated-method:27::Using deprecated method decodestring() +deprecated-method:28::Using deprecated method escape() +deprecated-method:43:Tests.test_foo:Using deprecated method assertEquals() +deprecated-method:44:Tests.test_foo:Using deprecated method assertNotEquals() +deprecated-method:45:Tests.test_foo:Using deprecated method assertAlmostEquals() +deprecated-method:46:Tests.test_foo:Using deprecated method assertNotAlmostEquals() +deprecated-method:47:Tests.test_foo:Using deprecated method assert_() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.py new file mode 100644 index 0000000..f416a14 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.py @@ -0,0 +1,7 @@ +""" Functional tests for method deprecation. """ +# pylint: disable=no-value-for-parameter +import unittest +from importlib.machinery import SourceFileLoader, SourcelessFileLoader + +SourceFileLoader('unittest', unittest.__file__).load_module() # [deprecated-method] +SourcelessFileLoader('unittest', unittest.__file__).load_module() # [deprecated-method] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.txt new file mode 100644 index 0000000..e5ae124 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_methods_py36.txt @@ -0,0 +1,2 @@ +deprecated-method:6::Using deprecated method load_module() +deprecated-method:7::Using deprecated method load_module() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.py new file mode 100644 index 0000000..b0d1865 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.py @@ -0,0 +1,8 @@ +"""Test deprecated modules.""" +# pylint: disable=unused-import,no-name-in-module,import-error,ungrouped-imports + +import Bastion # [deprecated-module] +import rexec # [deprecated-module] + +from Bastion import bastion_module # [deprecated-module] +from rexec import rexec_module # [deprecated-module] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.txt new file mode 100644 index 0000000..54f5555 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py2.txt @@ -0,0 +1,4 @@ +deprecated-module:4::Uses of a deprecated module 'Bastion' +deprecated-module:5::Uses of a deprecated module 'rexec' +deprecated-module:7::Uses of a deprecated module 'Bastion' +deprecated-module:8::Uses of a deprecated module 'rexec' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.py new file mode 100644 index 0000000..308d400 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.py @@ -0,0 +1,4 @@ +"""Test deprecated modules.""" +# pylint: disable=unused-import + +import optparse # [deprecated-module] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.rc new file mode 100644 index 0000000..46343d2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.0 +max_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.txt new file mode 100644 index 0000000..c41bf3b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py3.txt @@ -0,0 +1 @@ +deprecated-module:4::Uses of a deprecated module 'optparse' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.py new file mode 100644 index 0000000..c49f9f0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.py @@ -0,0 +1,4 @@ +"""Test deprecated modules from Python 3.6.""" +# pylint: disable=unused-import,import-error + +import optparse # [deprecated-module] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.txt new file mode 100644 index 0000000..c41bf3b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py36.txt @@ -0,0 +1 @@ +deprecated-module:4::Uses of a deprecated module 'optparse' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.py new file mode 100644 index 0000000..3cad959 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.py @@ -0,0 +1,4 @@ +"""Test deprecated modules.""" + +from deprecated import foo # [deprecated-module] +import deprecated # [deprecated-module] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.rc new file mode 100644 index 0000000..6fbd340 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.rc @@ -0,0 +1,4 @@ +[Messages Control] +deprecated-modules=deprecated +disable=all +enable=deprecated-module diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.txt new file mode 100644 index 0000000..74062f7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_py4.txt @@ -0,0 +1,2 @@ +deprecated-module:3::Uses of a deprecated module 'deprecated' +deprecated-module:4::Uses of a deprecated module 'deprecated' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.py new file mode 100644 index 0000000..52d55fa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.py @@ -0,0 +1,5 @@ +"""Test deprecated modules uninstalled.""" +# pylint: disable=unused-import,no-name-in-module,import-error + +from uninstalled import uninstalled_module # [deprecated-module] +import uninstalled # [deprecated-module] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.rc new file mode 100644 index 0000000..05973da --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.rc @@ -0,0 +1,2 @@ +[Messages Control] +deprecated-modules=uninstalled \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.txt new file mode 100644 index 0000000..6f14ddd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/deprecated_module_uninstalled.txt @@ -0,0 +1,2 @@ +deprecated-module:4::Uses of a deprecated module 'uninstalled' +deprecated-module:5::Uses of a deprecated module 'uninstalled' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_msg_github_issue_1389.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_msg_github_issue_1389.py new file mode 100644 index 0000000..5c7ad1e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_msg_github_issue_1389.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-docstring,too-few-public-methods + +from typing import Dict, NamedTuple, NewType, Set + +UserId = NewType('UserId', str) # pylint: disable=invalid-name +PlaceId = NewType('PlaceId', str) # pylint: disable=invalid-name + + +class Bar(NamedTuple): + place: PlaceId + name: str + + +class Foo(NamedTuple): + user: Dict[UserId, Set[Bar]] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_msg_github_issue_1389.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_msg_github_issue_1389.rc new file mode 100644 index 0000000..1450ccc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_msg_github_issue_1389.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_ungrouped_imports.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_ungrouped_imports.py new file mode 100644 index 0000000..cfcc01f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_ungrouped_imports.py @@ -0,0 +1,10 @@ +"""Checks that disabling 'ungrouped-imports' on an import prevents subsequent +imports from being considered ungrouped in respect to it.""" +# pylint: disable=unused-import,relative-import,wrong-import-position,wrong-import-order,using-constant-test +# pylint: disable=import-error +import os +import logging.config # pylint: disable=ungrouped-imports +import os.path +import logging +from os.path import join # [ungrouped-imports] +import logging.handlers # [ungrouped-imports] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_ungrouped_imports.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_ungrouped_imports.txt new file mode 100644 index 0000000..9f2fa44 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_ungrouped_imports.txt @@ -0,0 +1,2 @@ +ungrouped-imports:9::Imports from package os are not grouped +ungrouped-imports:10::Imports from package logging are not grouped diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_order.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_order.py new file mode 100644 index 0000000..f725d48 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_order.py @@ -0,0 +1,11 @@ +"""Checks that disabling 'wrong-import-order' on an import prevents subsequent +imports from being considered out-of-order in respect to it but does not prevent +it from being considered for 'ungrouped-imports'.""" +# pylint: disable=unused-import,import-error,no-name-in-module + +from first_party.foo import bar # pylint: disable=wrong-import-order +import logging +import os.path +import sys +from astroid import are_exclusive +import first_party # [ungrouped-imports] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_order.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_order.txt new file mode 100644 index 0000000..df71711 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_order.txt @@ -0,0 +1 @@ +ungrouped-imports:11::Imports from package first_party are not grouped diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_position.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_position.py new file mode 100644 index 0000000..0703325 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/disable_wrong_import_position.py @@ -0,0 +1,7 @@ +"""Checks that disabling 'wrong-import-position' on a statement prevents it from +invalidating subsequent imports.""" +# pylint: disable=unused-import + +CONSTANT = True # pylint: disable=wrong-import-position + +import sys diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/docstrings.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/docstrings.py new file mode 100644 index 0000000..497aa24 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/docstrings.py @@ -0,0 +1,90 @@ +# pylint: disable=R0201, useless-object-inheritance, unnecessary-pass +# -1: [missing-docstring] +from __future__ import print_function + +# +1: [empty-docstring] +def function0(): + """""" + +# +1: [missing-docstring] +def function1(value): + # missing docstring + print(value) + +def function2(value): + """docstring""" + print(value) + +def function3(value): + """docstring""" + print(value) + +# +1: [missing-docstring] +class AAAA(object): + # missing docstring + +## class BBBB: +## # missing docstring +## pass + +## class CCCC: +## """yeah !""" +## def method1(self): +## pass + +## def method2(self): +## """ yeah !""" +## pass + + # +1: [missing-docstring] + def method1(self): + pass + + def method2(self): + """ yeah !""" + pass + + # +1: [empty-docstring] + def method3(self): + """""" + pass + + def __init__(self): + pass + +class DDDD(AAAA): + """yeah !""" + + def __init__(self): + AAAA.__init__(self) + + # +1: [empty-docstring] + def method2(self): + """""" + pass + + def method3(self): + pass + + # +1: [missing-docstring] + def method4(self): + pass + +# pylint: disable=missing-docstring +def function4(): + pass + +# pylint: disable=empty-docstring +def function5(): + """""" + pass + +def function6(): + """ I am a {} docstring.""".format("good") + +def function7(): + """docstring""" + def inner(): + # Not documented + return 42 + return inner() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/docstrings.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/docstrings.txt new file mode 100644 index 0000000..e30e462 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/docstrings.txt @@ -0,0 +1,8 @@ +missing-docstring:1::Missing module docstring +empty-docstring:6:function0:Empty function docstring +missing-docstring:10:function1:Missing function docstring +missing-docstring:23:AAAA:Missing class docstring +missing-docstring:40:AAAA.method1:Missing method docstring:INFERENCE +empty-docstring:48:AAAA.method3:Empty method docstring:INFERENCE +empty-docstring:62:DDDD.method2:Empty method docstring:INFERENCE +missing-docstring:70:DDDD.method4:Missing method docstring:INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name.py new file mode 100644 index 0000000..c60b117 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name.py @@ -0,0 +1,14 @@ +"""Check for duplicate function arguments.""" + + +def foo1(_, _): # [duplicate-argument-name, duplicate-argument-name] + """Function with duplicate argument name.""" + +def foo2(_abc, *, _abc): # [duplicate-argument-name, duplicate-argument-name] + """Function with duplicate argument name.""" + +def foo3(_, _=3): # [duplicate-argument-name, duplicate-argument-name] + """Function with duplicate argument name.""" + +def foo4(_, *, _): # [duplicate-argument-name, duplicate-argument-name] + """Function with duplicate argument name.""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name.txt new file mode 100644 index 0000000..d60d1eb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name.txt @@ -0,0 +1,8 @@ +duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition +duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition +duplicate-argument-name:7:foo2:Duplicate argument name _abc in function definition +duplicate-argument-name:7:foo2:Duplicate argument name _abc in function definition +duplicate-argument-name:10:foo3:Duplicate argument name _ in function definition +duplicate-argument-name:10:foo3:Duplicate argument name _ in function definition +duplicate-argument-name:13:foo4:Duplicate argument name _ in function definition +duplicate-argument-name:13:foo4:Duplicate argument name _ in function definition \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.py new file mode 100644 index 0000000..c7fbe34 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.py @@ -0,0 +1,5 @@ +"""Check for duplicate function keywordonly arguments.""" + + +def foo1(_, *_, _=3): # [duplicate-argument-name, duplicate-argument-name] + """Function with duplicate argument name.""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.txt new file mode 100644 index 0000000..d866317 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_argument_name_py3.txt @@ -0,0 +1,2 @@ +duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition +duplicate-argument-name:4:foo1:Duplicate argument name _ in function definition \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_bases.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_bases.py new file mode 100644 index 0000000..9088e53 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_bases.py @@ -0,0 +1,15 @@ +"""Test duplicate bases error.""" +# pylint: disable=missing-docstring,too-few-public-methods,no-init + + +class Duplicates(str, str): # [duplicate-bases] + pass + + +class Alpha(str): + pass + + +class NotDuplicates(Alpha, str): + """The error should not be emitted for this case, since the + other same base comes from the ancestors.""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_bases.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_bases.txt new file mode 100644 index 0000000..beb91b5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_bases.txt @@ -0,0 +1 @@ +duplicate-bases:5:Duplicates:Duplicate bases for class 'Duplicates' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_dict_literal_key.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_dict_literal_key.py new file mode 100644 index 0000000..726a259 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_dict_literal_key.py @@ -0,0 +1,17 @@ +"""Check multiple key definition""" +# pylint: disable=C0103,pointless-statement + +correct_dict = { + 'tea': 'for two', + 'two': 'for tea', +} + +wrong_dict = { # [duplicate-key] + 'tea': 'for two', + 'two': 'for tea', + 'tea': 'time', + +} + +{1: b'a', 1: u'a'} # [duplicate-key] +{1: 1, 1.0: 2} # [duplicate-key] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_dict_literal_key.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_dict_literal_key.txt new file mode 100644 index 0000000..060d9dc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_dict_literal_key.txt @@ -0,0 +1,3 @@ +duplicate-key:9::Duplicate key 'tea' in dictionary +duplicate-key:16::Duplicate key 1 in dictionary +duplicate-key:17::Duplicate key 1.0 in dictionary diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_except.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_except.py new file mode 100644 index 0000000..c68cf7a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_except.py @@ -0,0 +1,12 @@ +"""Test for duplicate-check.""" + +def main(): + """The second ValueError should be flagged.""" + try: + raise ValueError('test') + except ValueError: + return 1 + except ValueError: # [duplicate-except] + return 2 + except (OSError, TypeError): + return 3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_except.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_except.txt new file mode 100644 index 0000000..a037948 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_except.txt @@ -0,0 +1 @@ +duplicate-except:9:main:Catching previously caught exception type ValueError diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_string_formatting_argument.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_string_formatting_argument.py new file mode 100644 index 0000000..b012f98 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_string_formatting_argument.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-docstring + +NAME = 42 +OTHER_NAME = 24 +OTHER_OTHER_NAME = 2 + +# +1: [duplicate-string-formatting-argument,duplicate-string-formatting-argument] +CONST = "some value {} some other value {} {} {} {} {}".format( + NAME, + NAME, + OTHER_NAME, + OTHER_NAME, + OTHER_NAME, + OTHER_OTHER_NAME, +) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_string_formatting_argument.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_string_formatting_argument.txt new file mode 100644 index 0000000..6d352eb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/duplicate_string_formatting_argument.txt @@ -0,0 +1,2 @@ +duplicate-string-formatting-argument:8::Duplicate string formatting argument 'NAME', consider passing as named argument +duplicate-string-formatting-argument:8::Duplicate string formatting argument 'OTHER_NAME', consider passing as named argument diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/eval_used.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/eval_used.py new file mode 100644 index 0000000..d03dad7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/eval_used.py @@ -0,0 +1,10 @@ +"""test for eval usage""" + +eval('os.listdir(".")') # [eval-used] +eval('os.listdir(".")', globals={}) # [eval-used] + +eval('os.listdir(".")', globals=globals()) # [eval-used] + +def func(): + """ eval in local scope""" + eval('b = 1') # [eval-used] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/eval_used.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/eval_used.txt new file mode 100644 index 0000000..6b1b078 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/eval_used.txt @@ -0,0 +1,4 @@ +eval-used:3::Use of eval +eval-used:4::Use of eval +eval-used:6::Use of eval +eval-used:10:func:Use of eval \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_is_binary_op.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_is_binary_op.py new file mode 100644 index 0000000..f71163d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_is_binary_op.py @@ -0,0 +1,12 @@ +"""Warn about binary operations used as exceptions.""" +from __future__ import print_function +try: + pass +except Exception or BaseException: # [binary-op-exception] + print("caught1") +except Exception and BaseException: # [binary-op-exception] + print("caught2") +except Exception or BaseException: # [binary-op-exception] + print("caught3") +except (Exception or BaseException) as exc: # [binary-op-exception] + print("caught4") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_is_binary_op.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_is_binary_op.txt new file mode 100644 index 0000000..e6512c9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_is_binary_op.txt @@ -0,0 +1,4 @@ +binary-op-exception:5::"Exception to catch is the result of a binary ""or"" operation" +binary-op-exception:7::"Exception to catch is the result of a binary ""and"" operation" +binary-op-exception:9::"Exception to catch is the result of a binary ""or"" operation" +binary-op-exception:11::"Exception to catch is the result of a binary ""or"" operation" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.py new file mode 100644 index 0000000..da95c78 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.py @@ -0,0 +1,41 @@ +""" +Check accessing Exception.message +""" +# pylint: disable=import-error, no-absolute-import, broad-except + +from unknown import ExtensionException +__revision__ = 0 + +class SubException(IndexError): + """ empty """ + +_ = IndexError("test").message # [exception-message-attribute] +_ = ZeroDivisionError("error").message # [exception-message-attribute] +_ = ExtensionException("error").message +_ = SubException("error").message # [exception-message-attribute] + +try: + raise Exception('e') +except Exception as exception: + _ = exception.message # [exception-message-attribute] + del exception.message # [exception-message-attribute] + exception.message += 'hello world' # [exception-message-attribute] + exception.message = 'hello world' + + +class CompatException(Exception): + """An exception which should work on py2 and py3.""" + + def __init__(self, message=''): + super(CompatException, self).__init__() + self.message = message + + def __repr__(self): + result = 'CompatException %s' % self.message + return result.encode('utf-8') + + +try: + raise CompatException('message here') +except CompatException as error: + _ = error.message diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.rc new file mode 100644 index 0000000..9540bc9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.rc @@ -0,0 +1,5 @@ +[testoptions] +max_pyver=3.0 + +[Messages Control] +enable=python3 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.txt new file mode 100644 index 0000000..2df7a3b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exception_message.txt @@ -0,0 +1,6 @@ +exception-message-attribute:12::Exception.message removed in Python 3 +exception-message-attribute:13::Exception.message removed in Python 3 +exception-message-attribute:15::Exception.message removed in Python 3 +exception-message-attribute:20::Exception.message removed in Python 3 +exception-message-attribute:21::Exception.message removed in Python 3 +exception-message-attribute:22::Exception.message removed in Python 3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.py new file mode 100644 index 0000000..8f7f07d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.py @@ -0,0 +1,10 @@ +# pylint: disable=missing-docstring + +exec 'a = __revision__' # [exec-used] +VALUES = {} +exec 'a = 1' in VALUES # [exec-used] + +exec 'a = 1' in globals() # [exec-used] + +def func(): + exec 'b = 1' # [exec-used] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.txt new file mode 100644 index 0000000..a7e1050 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py2.txt @@ -0,0 +1,4 @@ +exec-used:3::Use of exec +exec-used:5::Use of exec +exec-used:7::Use of exec +exec-used:10:func:Use of exec \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.py new file mode 100644 index 0000000..5f84948 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring + +exec('a = __revision__') # [exec-used] +exec('a = 1', globals={}) # [exec-used] + +exec('a = 1', globals=globals()) # [exec-used] + +def func(): + exec('b = 1') # [exec-used] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.txt new file mode 100644 index 0000000..c19ee94 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/exec_used_py3.txt @@ -0,0 +1,4 @@ +exec-used:3::Use of exec +exec-used:4::Use of exec +exec-used:6::Use of exec +exec-used:9:func:Use of exec \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_disabled.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_disabled.py new file mode 100644 index 0000000..321eb11 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_disabled.py @@ -0,0 +1,10 @@ +# pylint: disable=missing-docstring,unused-import +try: + import urllib2 as urllib_request #@ + import urllib2 as urllib_error + from urlparse import urlparse +except ImportError: + # python2 + from urllib import request as urllib_request + from urllib import error as urllib_error + from urllib.parse import urlparseq diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_disabled.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_disabled.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.py new file mode 100644 index 0000000..9420830 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.py @@ -0,0 +1,5 @@ +# pylint: disable=missing-docstring,unused-import +try: + import collections.missing # [no-name-in-module] +except ImportError: + from collections import missing # [no-name-in-module] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.rc new file mode 100644 index 0000000..204ce11 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.rc @@ -0,0 +1,2 @@ +[IMPORTS] +analyse-fallback-blocks=yes \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.txt new file mode 100644 index 0000000..e795b82 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fallback_import_enabled.txt @@ -0,0 +1,2 @@ +no-name-in-module:3::No name 'missing' in module 'collections' +no-name-in-module:5::No name 'missing' in module 'collections' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme.py new file mode 100644 index 0000000..298355d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme.py @@ -0,0 +1,24 @@ +# -*- encoding=utf-8 -*- +# pylint: disable=missing-docstring, unused-variable + +# +1: [fixme] +# FIXME: beep + + +def function(): + variable = "FIXME: Ignore me!" + # +1: [fixme] + test = "text" # FIXME: Valid test + + # +1: [fixme] + # TODO: Do something with the variables + # +1: [fixme] + xxx = "n/a" # XXX: Fix this later + # +1: [fixme] + #FIXME: no space after hash + # +1: [fixme] + #todo: no space after hash + #FIXME: in fact nothing to fix #pylint: disable=fixme + #TODO: in fact nothing to do #pylint: disable=fixme + #TODO: in fact nothing to do #pylint: disable=line-too-long, fixme + # Todoist API mentioned should not result in a message. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme.txt new file mode 100644 index 0000000..d281646 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme.txt @@ -0,0 +1,6 @@ +fixme:5::"FIXME: beep" +fixme:11::"FIXME: Valid test" +fixme:14::"TODO: Do something with the variables" +fixme:16::"XXX: Fix this later" +fixme:18::"FIXME: no space after hash" +fixme:20::"todo: no space after hash" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.py new file mode 100644 index 0000000..6ee67ce --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.py @@ -0,0 +1,6 @@ +""" +Test for issue ##1139 - when CRLF newline characters are used, +\r is left in msg section. As a result, output line in cmdline +is overwritten with text after msg""" + +# TODO Lorem ipsum dolor sit amet consectetur adipiscing elit # [fixme] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.rc new file mode 100644 index 0000000..554bb30 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.rc @@ -0,0 +1,2 @@ +[MESSAGES CONTROL] +msg-template={C}:{line:3d},{column:2d}: {obj}: {msg} ({symbol}, {msg_id}) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.txt new file mode 100644 index 0000000..62ea8b8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/fixme_bad_formatting_1139.txt @@ -0,0 +1 @@ +fixme:6::TODO Lorem ipsum dolor sit amet consectetur adipiscing elit # [fixme]:HIGH diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.py new file mode 100644 index 0000000..8feb4e2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.py @@ -0,0 +1,8 @@ +"""Test that `if` in formatted string literal won't break Pylint.""" +# pylint: disable=missing-docstring, pointless-statement, using-constant-test + +f'{"+" if True else "-"}' +if True: + pass +elif True: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatted_string_literal_with_if_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatting.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/formatting.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/function_redefined.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/function_redefined.py new file mode 100644 index 0000000..ba28328 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/function_redefined.py @@ -0,0 +1,109 @@ +# pylint: disable=R0201,missing-docstring,using-constant-test,unused-import,wrong-import-position,reimported, useless-object-inheritance, unnecessary-pass +from __future__ import division +__revision__ = '' + +class AAAA(object): + """docstring""" + def __init__(self): + pass + def method1(self): + """docstring""" + + def method2(self): + """docstring""" + + def method2(self): # [function-redefined] + """docstring""" + +class AAAA(object): # [function-redefined] + """docstring""" + def __init__(self): + pass + def yeah(self): + """hehehe""" + def yoo(self): + """yoo""" +def func1(): + """docstring""" + +def func2(): + """docstring""" + +def func2(): # [function-redefined] + """docstring""" + __revision__ = 1 # [redefined-outer-name] + return __revision__ + +if __revision__: + def exclusive_func(): + "docstring" +else: + def exclusive_func(): + "docstring" + +try: + def exclusive_func2(): + "docstring" +except TypeError: + def exclusive_func2(): + "docstring" +else: + def exclusive_func2(): # [function-redefined] + "this one redefine the one defined line 42" + + +def with_inner_function_1(): + """docstring""" + def callback(): + """callback docstring""" + pass + return callback + +def with_inner_function_2(): + """docstring""" + def callback(): + """does not redefine callback returned by with_inner_function_1""" + pass + return callback + +def some_func(): + """Don't emit if we defined a variable with the same name as a + __future__ directive. + """ + division = 2 + return division + +def dummy_func(): + """First dummy function""" + pass + +def dummy_func(): + """Second dummy function, don't emit function-redefined message + because of the dummy name""" + pass + +from math import ceil +def ceil(): # [function-redefined] + pass + +import math +def math(): # [function-redefined] + pass + +import math as _ +def _(): + pass + +# pylint: disable=too-few-public-methods +class ObjectProxy: + """ABC""" + + # We actually *redefine* these attributes, but these shouldn't + # be considered actual redefinitions. Issue #2451 + @property + def __module__(self): + return "actual.module" + + @property + def __doc__(self): + return "Docstring" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/function_redefined.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/function_redefined.txt new file mode 100644 index 0000000..fcd3c0e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/function_redefined.txt @@ -0,0 +1,7 @@ +function-redefined:15:AAAA.method2:method already defined line 12 +function-redefined:18:AAAA:class already defined line 5 +function-redefined:32:func2:function already defined line 29 +redefined-outer-name:34:func2:Redefining name '__revision__' from outer scope (line 3) +function-redefined:51:exclusive_func2:function already defined line 45 +function-redefined:86:ceil:function already defined line 85 +function-redefined:90:math:function already defined line 89 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_import.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_import.py new file mode 100644 index 0000000..e4d3785 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_import.py @@ -0,0 +1,3 @@ +"""a docstring""" + +from __future__ import generators diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.py new file mode 100644 index 0000000..30c2bd6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.py @@ -0,0 +1,6 @@ +"""Unicode literals in Python 2.*""" +from __future__ import unicode_literals + + +BAD_STRING = b'\u1234' # >= 2.7.4:[anomalous-unicode-escape-in-string] +GOOD_STRING = '\u1234' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.rc new file mode 100644 index 0000000..58b5a94 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.rc @@ -0,0 +1 @@ +[testoptions] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.txt new file mode 100644 index 0000000..60d291e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/future_unicode_literals.txt @@ -0,0 +1 @@ +anomalous-unicode-escape-in-string:5::"Anomalous Unicode escape in byte string: '\u'. String constant might be missing an r or u prefix." diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/generated_members.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/generated_members.py new file mode 100644 index 0000000..802ebaf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/generated_members.py @@ -0,0 +1,18 @@ +"""Test the generated-members config option.""" +# pylint: disable=pointless-statement, invalid-name, useless-object-inheritance +from __future__ import print_function +from astroid import node_classes +from pylint import checkers + +class Klass(object): + """A class with a generated member.""" + +print(Klass().DoesNotExist) +print(Klass().aBC_set1) +node_classes.Tuple.does.not_.exist +checkers.base.doesnotexist() + +session = Klass() +SESSION = Klass() +session.rollback() +SESSION.rollback() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/generated_members.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/generated_members.rc new file mode 100644 index 0000000..177eca9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/generated_members.rc @@ -0,0 +1,5 @@ +[Messages Control] +disable=too-few-public-methods,print-statement + +[typecheck] +generated-members=DoesNotExist,"[a-zA-Z]+_set{1,2}",node_classes.Tuple.*,checkers.*?base,(session|SESSION).rollback diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexp_in_class_scope.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexp_in_class_scope.py new file mode 100644 index 0000000..868cf6b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexp_in_class_scope.py @@ -0,0 +1,6 @@ +# pylint: disable=W0232,R0903, missing-docstring, useless-object-inheritance +"""Class scope must be handled correctly in genexps""" + +class MyClass(object): + var1 = [] + var2 = list(value*2 for value in var1) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexp_in_class_scope.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexp_in_class_scope.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexpr_variable_scope.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexpr_variable_scope.py new file mode 100644 index 0000000..a00d72d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexpr_variable_scope.py @@ -0,0 +1,5 @@ +"""test name defined in generator expression are not available +outside the genexpr scope +""" +from __future__ import print_function +print(n) # [undefined-variable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexpr_variable_scope.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexpr_variable_scope.txt new file mode 100644 index 0000000..3cfa6c5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/genexpr_variable_scope.txt @@ -0,0 +1 @@ +undefined-variable:5::Undefined variable 'n' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/globals.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/globals.py new file mode 100644 index 0000000..1a24ff7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/globals.py @@ -0,0 +1,32 @@ +"""Warnings about global statements and usage of global variables.""" +from __future__ import print_function + +global CSTE # [global-at-module-level] +print(CSTE) # [undefined-variable] + +CONSTANT = 1 + +def fix_contant(value): + """all this is ok, but try not using global ;)""" + global CONSTANT # [global-statement] + print(CONSTANT) + CONSTANT = value + + +def other(): + """global behaviour test""" + global HOP # [global-variable-not-assigned] + print(HOP) # [undefined-variable] + + +def define_constant(): + """ok but somevar is not defined at the module scope""" + global SOMEVAR # [global-variable-undefined] + SOMEVAR = 2 + + +# pylint: disable=invalid-name +def global_with_import(): + """should only warn for global-statement""" + global sys # [global-statement] + import sys diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/globals.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/globals.txt new file mode 100644 index 0000000..0ce528d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/globals.txt @@ -0,0 +1,7 @@ +global-at-module-level:4::Using the global statement at the module level +undefined-variable:5::Undefined variable 'CSTE' +global-statement:11:fix_contant:Using the global statement +global-variable-not-assigned:18:other:Using global for 'HOP' but no assignment is done +undefined-variable:19:other:Undefined variable 'HOP' +global-variable-undefined:24:define_constant:Global variable 'SOMEVAR' undefined at the module level +global-statement:31:global_with_import:Using the global statement diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.py new file mode 100644 index 0000000..8c4b5cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.py @@ -0,0 +1,26 @@ +#pylint: disable=bad-continuation,invalid-name,missing-docstring + +# Basic test with a list +TEST_LIST1 = ['a' 'b'] # [implicit-str-concat-in-sequence] +# Testing with unicode strings in a tuple, with a comma AFTER concatenation +TEST_LIST2 = (u"a" u"b", u"c") # [implicit-str-concat-in-sequence] +# Testing with raw strings in a set, with a comma BEFORE concatenation +TEST_LIST3 = {r'''a''', r'''b''' r'''c'''} # [implicit-str-concat-in-sequence] +# Testing that only ONE warning is generated when string concatenation happens +# in the middle of a list +TEST_LIST4 = ["""a""", """b""" """c""", """d"""] # [implicit-str-concat-in-sequence] + +# The following shouldn't raise a warning because it is a function call +print('a', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'ccc') + +# The following shouldn't raise a warning because string literals are +# on different lines +TEST_LIST5 = ('a', 'b' + 'c') + +# The following shouldn't raise a warning because of the escaped newline +TEST_LIST6 = ('a' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \ + ccc') + +# No warning for bytes +TEST_LIST7 = [b'A' b'B'] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.txt new file mode 100644 index 0000000..b9e1cbb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence.txt @@ -0,0 +1,4 @@ +implicit-str-concat-in-sequence:4::Implicit string concatenation found in list +implicit-str-concat-in-sequence:6::Implicit string concatenation found in tuple +implicit-str-concat-in-sequence:8::Implicit string concatenation found in set +implicit-str-concat-in-sequence:11::Implicit string concatenation found in list diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_latin1.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_latin1.py new file mode 100644 index 0000000..44a2a94 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_latin1.py @@ -0,0 +1,4 @@ +# coding: latin_1 +#pylint: disable=bad-continuation,invalid-name,missing-docstring + +TOTO = ('Caf', 'Caf', 'Caf') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_latin1.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_latin1.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_utf8.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_utf8.py new file mode 100644 index 0000000..fa996e9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_utf8.py @@ -0,0 +1,3 @@ +#pylint: disable=bad-continuation,invalid-name,missing-docstring + +TOTO = ('Café', 'Café', 'Café') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_utf8.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/implicit_str_concat_in_sequence_utf8.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.py new file mode 100644 index 0000000..69fd15b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.py @@ -0,0 +1,29 @@ +""" Test that import errors are detected. """ +# pylint: disable=invalid-name, unused-import, no-absolute-import, bare-except, broad-except, wrong-import-order, wrong-import-position +import totally_missing # [import-error] + +try: + import maybe_missing +except ImportError: + maybe_missing = None + +try: + import maybe_missing_1 +except (ImportError, SyntaxError): + maybe_missing_1 = None + +try: + import maybe_missing_2 # [import-error] +except ValueError: + maybe_missing_2 = None + + +try: + if maybe_missing: + import really_missing +except ImportError: + pass + +from .collections import missing # [import-error] + +from .syntax_error import toto # [syntax-error] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.rc new file mode 100644 index 0000000..de78a17 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.rc @@ -0,0 +1,2 @@ +[Messages Control] +disable=C,R,W diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.txt new file mode 100644 index 0000000..493e79a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/import_error.txt @@ -0,0 +1,4 @@ +import-error:3::"Unable to import 'totally_missing'" +import-error:16::"Unable to import 'maybe_missing_2'" +import-error:27::"Unable to import 'functional.collections'" +syntax-error:29::"Cannot import 'syntax_error' due to syntax error 'invalid syntax (<unknown>, line 1)'" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_mro.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_mro.py new file mode 100644 index 0000000..0ae67e4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_mro.py @@ -0,0 +1,9 @@ +"""Tests for inconsistent-mro.""" +# pylint: disable=missing-docstring,too-few-public-methods,no-init + +class Str(str): + pass + + +class Inconsistent(str, Str): # [inconsistent-mro] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_mro.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_mro.txt new file mode 100644 index 0000000..1ae9687 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_mro.txt @@ -0,0 +1 @@ +inconsistent-mro:8:Inconsistent:Inconsistent method resolution order for class 'Inconsistent' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.py new file mode 100644 index 0000000..6191656 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.py @@ -0,0 +1,264 @@ +#pylint: disable=missing-docstring, no-else-return, invalid-name, unused-variable, superfluous-parens, try-except-raise +"""Testing inconsistent returns""" +import math +import sys + +# These ones are consistent +def explicit_returns(var): + if var >= 0: + return math.sqrt(var) + else: + return None + +def explicit_returns2(var): + if var < 0: + return None + return math.sqrt(var) + +def empty_implicit_returns(var): + if var < 0: + return + +def returns_in_exceptions(): + try: + raise ValueError('test') + except ValueError: + return 1 + except (OSError, TypeError): + return 2 + +def returns_and_exceptions(var): + if var < 10: + return var**2 + else: + raise ValueError("Incorrect value") + +def returns_and_exceptions_issue1770(var): + try: + if var == 1: + return 'a' + elif var == 2: + return 'b' + else: + raise ValueError + except AssertionError: + return None + +def explicit_returns3(arg): + if arg: + return False + else: + if arg < 3: + print('arg < 3') + return True + +def explicit_returns4(arg): + if arg: + if arg > 2: + print('arg > 2') + return False + else: + if arg < 3: + print('arg < 3') + return True + +def explicit_returns5(arg): + if arg: + if arg > 2: + print('arg > 2') + return False + else: + return True + +def nested_function(): + def dummy_return(): + return True + return dummy_return + +def explicit_returns6(x, y, z): + if x: # pylint: disable=no-else-return + a = 1 + if y: # pylint: disable=no-else-return + b = 2 + return y + else: + c = 3 + return x + else: + d = 4 + return z + +def explicit_returns7(arg): + if arg < 0: + arg = 2 * arg + return 'below 0' + elif arg == 0: + print("Null arg") + return '0' + else: + arg = 3 * arg + return 'above 0' + +def bug_1772(): + """Don't check inconsistent return statements inside while loop""" + counter = 1 + while True: + counter += 1 + if counter == 100: + return 7 + +def bug_1771(var): + if var == 1: + sys.exit(1) + else: + return var * 2 + +def bug_1771_with_user_config(var): + # sys.getdefaultencoding is considered as a never + # returning function in the inconsistent_returns.rc file. + if var == 1: + sys.getdefaultencoding() + else: + return var * 2 + +def bug_1794_inner_func_in_if(var): + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return None + return None + else: + return None + +try: + import ConfigParser as configparser +except ImportError: + import configparser + +# Due to the try/except import above, astroid cannot safely +# infer the exception type. It doesn't matter here, because +# as the raise statement is not inside a try/except one, there +# is no need to infer the exception type. It is just an exception +# that is raised. +def bug_1794(a): + for x in range(a): + if x == 100: + return a + raise configparser.NoSectionError('toto') + +#pylint: disable = no-else-return +def bug_1782_bis(val=3): + if val == 3: + while True: + break + return True + else: + raise RuntimeError() + +# Next ones are not consistent +def explicit_implicit_returns(var): # [inconsistent-return-statements] + if var >= 0: + return math.sqrt(var) + +def empty_explicit_returns(var): # [inconsistent-return-statements] + if var < 0: + return + return math.sqrt(var) + +def explicit_implicit_returns2(arg): # [inconsistent-return-statements] + if arg: + if arg > 2: + print('arg > 2') + return False + else: + return True + +def explicit_implicit_returns3(arg): # [inconsistent-return-statements] + if arg: + if arg > 2: + print('arg > 2') + return False + else: + return True + +def returns_missing_in_catched_exceptions(arg): # [inconsistent-return-statements] + try: + arg = arg**2 + raise ValueError('test') + except ValueError: + print('ValueError') + arg = 0 + except (OSError, TypeError): + return 2 + +def complex_func(arg): # [inconsistent-return-statements] + for i in range(arg): + if i > arg / 2: + break + else: + return arg + +def inconsistent_returns_in_nested_function(): + def not_consistent_returns_inner(arg): # [inconsistent-return-statements] + for i in range(arg): + if i > arg / 2: + break + else: + return arg + return not_consistent_returns_inner + +def bug_1771_counter_example(var): # [inconsistent-return-statements] + if var == 1: + inconsistent_returns_in_nested_function() + else: + return var * 2 + +class BlargException(Exception): + pass + + +def blarg(someval): + try: + if someval: + raise BlargException() + return 5 + except BlargException: + raise + +def bug_1772_counter_example(): # [inconsistent-return-statements] + counter = 1 + if counter == 1: + while True: + counter += 1 + if counter == 100: + return 7 + +def bug_1794_inner_func_in_if_counter_example_1(var): # [inconsistent-return-statements] + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return None + return None + else: + return + +def bug_1794_inner_func_in_if_counter_example_2(var): # [inconsistent-return-statements] + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return + return None + else: + return + +def bug_1794_inner_func_in_if_counter_example_3(var): # [inconsistent-return-statements] + # pylint: disable = no-else-return,useless-return + if var: + def _inner(): + return None + return None + else: + def _inner2(var_bis): # [inconsistent-return-statements] + if var_bis: + return True + return diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.rc new file mode 100644 index 0000000..dd6cbb5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.rc @@ -0,0 +1,2 @@ +[REFACTORING] +never-returning-functions=sys.exit,sys.getdefaultencoding diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.txt new file mode 100644 index 0000000..d2d70e6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inconsistent_returns.txt @@ -0,0 +1,13 @@ +inconsistent-return-statements:159:explicit_implicit_returns:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:163:empty_explicit_returns:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:168:explicit_implicit_returns2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:176:explicit_implicit_returns3:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:184:returns_missing_in_catched_exceptions:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:194:complex_func:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:202:inconsistent_returns_in_nested_function.not_consistent_returns_inner:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:210:bug_1771_counter_example:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:228:bug_1772_counter_example:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:236:bug_1794_inner_func_in_if_counter_example_1:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:245:bug_1794_inner_func_in_if_counter_example_2:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:254:bug_1794_inner_func_in_if_counter_example_3:Either all return statements in a function should return an expression, or none of them should. +inconsistent-return-statements:261:bug_1794_inner_func_in_if_counter_example_3._inner2:Either all return statements in a function should return an expression, or none of them should. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.py new file mode 100644 index 0000000..9ac1a7c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.py @@ -0,0 +1,15 @@ +""" +Check for indexing exceptions. +""" +# pylint: disable=import-error, no-absolute-import + +from unknown import ExtensionException +__revision__ = 0 + +class SubException(IndexError): + """ empty """ + +_ = IndexError("test")[0] # [indexing-exception] +_ = ZeroDivisionError("error")[0] # [indexing-exception] +_ = ExtensionException("error")[0] +_ = SubException("error")[1] # [indexing-exception] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.rc new file mode 100644 index 0000000..9540bc9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.rc @@ -0,0 +1,5 @@ +[testoptions] +max_pyver=3.0 + +[Messages Control] +enable=python3 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.txt new file mode 100644 index 0000000..268e260 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/indexing_exception.txt @@ -0,0 +1,3 @@ +indexing-exception:12::Indexing exceptions will not work on Python 3 +indexing-exception:13::Indexing exceptions will not work on Python 3 +indexing-exception:15::Indexing exceptions will not work on Python 3 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inherit_non_class.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inherit_non_class.py new file mode 100644 index 0000000..c231e05 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inherit_non_class.py @@ -0,0 +1,81 @@ +"""Test that inheriting from something which is not +a class emits a warning. """ + +# pylint: disable=no-init, import-error, invalid-name, using-constant-test, useless-object-inheritance +# pylint: disable=missing-docstring, too-few-public-methods, no-absolute-import + +from missing import Missing + +if 1: + Ambiguous = None +else: + Ambiguous = int + +class Empty(object): + """ Empty class. """ + +def return_class(): + """ Return a class. """ + return Good3 + +class Bad(1): # [inherit-non-class] + """ Can't inherit from instance. """ + +class Bad1(lambda abc: 42): # [inherit-non-class] + """ Can't inherit from lambda. """ + +class Bad2(object()): # [inherit-non-class] + """ Can't inherit from an instance of object. """ + +class Bad3(return_class): # [inherit-non-class] + """ Can't inherit from function. """ + +class Bad4(Empty()): # [inherit-non-class] + """ Can't inherit from instance. """ + +class Good(object): + pass + +class Good1(int): + pass + +class Good2(type): + pass + +class Good3(type(int)): + pass + +class Good4(return_class()): + pass + +class Good5(Good4, int, object): + pass + +class Good6(Ambiguous): + """ Inherits from something ambiguous. + + This could emit a warning when we will have + flow detection. + """ + +class Unknown(Missing): + pass + +class Unknown1(Good5 if True else Bad1): + pass + + +class NotInheritableBool(bool): # [inherit-non-class] + pass + + +class NotInheritableRange(range): # [inherit-non-class] + pass + + +class NotInheritableSlice(slice): # [inherit-non-class] + pass + + +class NotInheritableMemoryView(memoryview): # [inherit-non-class] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inherit_non_class.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inherit_non_class.txt new file mode 100644 index 0000000..3be70cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/inherit_non_class.txt @@ -0,0 +1,9 @@ +inherit-non-class:21:Bad:Inheriting '1', which is not a class. +inherit-non-class:24:Bad1:"Inheriting 'lambda abc: 42', which is not a class." +inherit-non-class:27:Bad2:Inheriting 'object()', which is not a class. +inherit-non-class:30:Bad3:Inheriting 'return_class', which is not a class. +inherit-non-class:33:Bad4:Inheriting 'Empty()', which is not a class. +inherit-non-class:68:NotInheritableBool:Inheriting 'bool', which is not a class. +inherit-non-class:72:NotInheritableRange:Inheriting 'range', which is not a class. +inherit-non-class:76:NotInheritableSlice:Inheriting 'slice', which is not a class. +inherit-non-class:80:NotInheritableMemoryView:Inheriting 'memoryview', which is not a class. \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_is_generator.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_is_generator.py new file mode 100644 index 0000000..17f96db --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_is_generator.py @@ -0,0 +1,5 @@ +# pylint: disable=missing-docstring,too-few-public-methods, useless-object-inheritance + +class SomeClass(object): + def __init__(self): # [init-is-generator] + yield None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_is_generator.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_is_generator.txt new file mode 100644 index 0000000..5d2132a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_is_generator.txt @@ -0,0 +1 @@ +init-is-generator:4:SomeClass.__init__:__init__ method is a generator diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_not_called.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_not_called.py new file mode 100644 index 0000000..2823064 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_not_called.py @@ -0,0 +1,64 @@ +# pylint: disable=R0903,import-error,missing-docstring,wrong-import-position,useless-super-delegation, useless-object-inheritance, unnecessary-pass +"""test for __init__ not called +""" +from __future__ import print_function + +class AAAA: + """ancestor 1""" + + def __init__(self): + print('init', self) + +class BBBB: + """ancestor 2""" + + def __init__(self): + print('init', self) + +class CCCC: + """ancestor 3""" + + +class ZZZZ(AAAA, BBBB, CCCC): + """derived class""" + + def __init__(self): # [super-init-not-called] + AAAA.__init__(self) + +class NewStyleA(object): + """new style class""" + def __init__(self): + super(NewStyleA, self).__init__() + print('init', self) + +class NewStyleB(NewStyleA): + """derived new style class""" + def __init__(self): + super(NewStyleB, self).__init__() + +class NoInit(object): + """No __init__ defined""" + +class Init(NoInit): + """Don't complain for not calling the super __init__""" + + def __init__(self, arg): + self.arg = arg + +class NewStyleC(object): + """__init__ defined by assignment.""" + def xx_init(self): + """Initializer.""" + pass + + __init__ = xx_init + +class AssignedInit(NewStyleC): + """No init called.""" + def __init__(self): # [super-init-not-called] + self.arg = 0 + +from missing import Missing + +class UnknownBases(Missing): + """Don't emit no-init if the bases aren't known.""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_not_called.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_not_called.txt new file mode 100644 index 0000000..955d418 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_not_called.txt @@ -0,0 +1,3 @@ +no-init:18:CCCC:Class has no __init__ method +super-init-not-called:25:ZZZZ.__init__:__init__ method from base class 'BBBB' is not called +super-init-not-called:58:AssignedInit.__init__:__init__ method from base class 'NewStyleC' is not called diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_subclass_classmethod_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_subclass_classmethod_py36.py new file mode 100644 index 0000000..ad37970 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_subclass_classmethod_py36.py @@ -0,0 +1,16 @@ +# pylint: disable=too-few-public-methods, missing-docstring,no-init, useless-object-inheritance + +class PluginBase(object): + subclasses = [] + + def __init_subclass__(cls, **kwargs): + super().__init_subclass__(**kwargs) + cls.subclasses.append(cls) + + +class Plugin1(PluginBase): + pass + + +class Plugin2(PluginBase): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_subclass_classmethod_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_subclass_classmethod_py36.rc new file mode 100644 index 0000000..1450ccc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/init_subclass_classmethod_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_all_object.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_all_object.py new file mode 100644 index 0000000..729f051 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_all_object.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring +__all__ = ( + 1, # [invalid-all-object] + lambda: None, # [invalid-all-object] + None, # [invalid-all-object] +) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_all_object.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_all_object.txt new file mode 100644 index 0000000..428292e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_all_object.txt @@ -0,0 +1,3 @@ +invalid-all-object:3::Invalid object '1' in __all__, must contain only strings +invalid-all-object:4:<lambda>:"Invalid object 'lambda: None' in __all__, must contain only strings" +invalid-all-object:5::Invalid object 'None' in __all__, must contain only strings diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.py new file mode 100644 index 0000000..fb6b2de --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.py @@ -0,0 +1,3 @@ +"""Test data file with wrong encoding and if coding is not first line.""" +# coding: utd-8 # [syntax-error] +STR = 'some text' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.rc new file mode 100644 index 0000000..eca2dd9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=2.7.10 +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.txt new file mode 100644 index 0000000..856a1a1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_encoding_py27.txt @@ -0,0 +1 @@ +syntax-error:2::Cannot decode using encoding "utd-8", bad encoding diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_envvar_value.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_envvar_value.py new file mode 100644 index 0000000..3c1a888 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_envvar_value.py @@ -0,0 +1,84 @@ +# pylint: disable=useless-return,missing-docstring +from os import getenv + + +def function_returning_list(): + return [] + +def function_returning_none(): + return None + +def function_returning_string(): + return "Result" + +def function_returning_bytes(): + return b"Result" + +def deep_function_returning_string(): + return function_returning_string() + +def deep_function_returning_bytes(): + return function_returning_bytes() + + +# --------------------------------------------------------------------------- # +# Testing getenv # +# --------------------------------------------------------------------------- # + +getenv() # pylint: disable=no-value-for-parameter + +getenv(b"TEST") # [invalid-envvar-value] +getenv("TEST") +getenv(None) # [invalid-envvar-value] +getenv(["Crap"]) # [invalid-envvar-value] +getenv(function_returning_bytes()) # [invalid-envvar-value] +getenv(deep_function_returning_bytes()) # [invalid-envvar-value] +getenv(function_returning_list()) # [invalid-envvar-value] +getenv(function_returning_none()) # [invalid-envvar-value] +getenv(function_returning_string()) +getenv(deep_function_returning_string()) + +getenv(b"TEST", "default") # [invalid-envvar-value] +getenv("TEST", "default") +getenv(None, "default") # [invalid-envvar-value] +getenv(["Crap"], "default") # [invalid-envvar-value] +getenv(function_returning_bytes(), "default") # [invalid-envvar-value] +getenv(function_returning_list(), "default") # [invalid-envvar-value] +getenv(function_returning_none(), "default") # [invalid-envvar-value] +getenv(function_returning_string(), "default") + +getenv(key=b"TEST") # [invalid-envvar-value] +getenv(key="TEST") +getenv(key=None) # [invalid-envvar-value] +getenv(key=["Crap"]) # [invalid-envvar-value] +getenv(key=function_returning_bytes()) # [invalid-envvar-value] +getenv(key=function_returning_list()) # [invalid-envvar-value] +getenv(key=function_returning_none()) # [invalid-envvar-value] +getenv(key=function_returning_string()) + +getenv('TEST', "value") +getenv('TEST', []) # [invalid-envvar-default] +getenv('TEST', None) +getenv('TEST', b"123") # [invalid-envvar-default] +getenv('TEST', function_returning_list()) # [invalid-envvar-default] +getenv('TEST', function_returning_none()) +getenv('TEST', function_returning_string()) +getenv('TEST', function_returning_bytes()) # [invalid-envvar-default] + +getenv('TEST', default="value") +getenv('TEST', default=[]) # [invalid-envvar-default] +getenv('TEST', default=None) +getenv('TEST', default=b"123") # [invalid-envvar-default] +getenv('TEST', default=function_returning_list()) # [invalid-envvar-default] +getenv('TEST', default=function_returning_none()) +getenv('TEST', default=function_returning_string()) +getenv('TEST', default=function_returning_bytes()) # [invalid-envvar-default] + +getenv(key='TEST') +getenv(key='TEST', default="value") +getenv(key='TEST', default=b"value") # [invalid-envvar-default] +getenv(key='TEST', default=["Crap"]) # [invalid-envvar-default] +getenv(key='TEST', default=function_returning_list()) # [invalid-envvar-default] +getenv(key='TEST', default=function_returning_none()) +getenv(key='TEST', default=function_returning_string()) +getenv(key='TEST', default=function_returning_bytes()) # [invalid-envvar-default] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_envvar_value.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_envvar_value.txt new file mode 100644 index 0000000..824d20e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_envvar_value.txt @@ -0,0 +1,31 @@ +invalid-envvar-value:30::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:32::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:33::os.getenv does not support builtins.list type argument +invalid-envvar-value:34::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:35::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:36::os.getenv does not support builtins.list type argument +invalid-envvar-value:37::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:41::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:43::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:44::os.getenv does not support builtins.list type argument +invalid-envvar-value:45::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:46::os.getenv does not support builtins.list type argument +invalid-envvar-value:47::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:50::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:52::os.getenv does not support builtins.NoneType type argument +invalid-envvar-value:53::os.getenv does not support builtins.list type argument +invalid-envvar-value:54::os.getenv does not support builtins.bytes type argument +invalid-envvar-value:55::os.getenv does not support builtins.list type argument +invalid-envvar-value:56::os.getenv does not support builtins.NoneType type argument +invalid-envvar-default:60::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:62::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:63::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:66::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:69::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:71::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:72::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:75::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:79::os.getenv default type is builtins.bytes. Expected str or None. +invalid-envvar-default:80::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:81::os.getenv default type is builtins.list. Expected str or None. +invalid-envvar-default:84::os.getenv default type is builtins.bytes. Expected str or None. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_caught.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_caught.py new file mode 100644 index 0000000..2526434 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_caught.py @@ -0,0 +1,135 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance +# pylint: disable=too-many-ancestors, no-absolute-import, import-error, multiple-imports,wrong-import-position +from __future__ import print_function + +import socket, binascii, abc, six + +class MyException(object): + """Custom 'exception'.""" + +class MySecondException(object): + """Custom 'exception'.""" + +class MyGoodException(Exception): + """Custom exception.""" + +class MySecondGoodException(MyGoodException): + """Custom exception.""" + +class SkipException(socket.error): + """Not an exception for Python 2, but one in 3.""" + +class SecondSkipException(SkipException): + """Also a good exception.""" + +try: + 1 + 1 +except MyException: # [catching-non-exception] + print("caught") + +try: + 1 + 2 +# +1:[catching-non-exception,catching-non-exception] +except (MyException, MySecondException): + print("caught") + +try: + 1 + 3 +except MyGoodException: + print("caught") + +try: + 1 + 3 +except (MyGoodException, MySecondGoodException): + print("caught") + +try: + 1 + 3 +except (SkipException, SecondSkipException): + print("caught") + +try: + 1 + 42 +# +1:[catching-non-exception,catching-non-exception] +except (None, list()): + print("caught") + +try: + 1 + 24 +except None: # [catching-non-exception] + print("caught") + +EXCEPTION = None +EXCEPTION = ZeroDivisionError +try: + 1 + 46 +except EXCEPTION: + print("caught") + +try: + 1 + 42 +# +1:[catching-non-exception,catching-non-exception,catching-non-exception] +except (list([4, 5, 6]), None, ZeroDivisionError, 4): + print("caught") + +EXCEPTION_TUPLE = (ZeroDivisionError, OSError) +NON_EXCEPTION_TUPLE = (ZeroDivisionError, OSError, 4) + +try: + 1 + 42 +except EXCEPTION_TUPLE: + print("caught") + +try: + 1 + 42 +except NON_EXCEPTION_TUPLE: # [catching-non-exception] + print("caught") + +from missing_import import UnknownError +UNKNOWN_COMPONENTS = (ZeroDivisionError, UnknownError) + +try: + 1 + 42 +except UNKNOWN_COMPONENTS: + print("caught") + +try: + 1 + 42 +except binascii.Error: + print('builtin and detected') + +try: + 1 + 45 +except object: # [catching-non-exception] + print('caught') + +try: + 1 + 42 +except range: # [catching-non-exception] + print('caught') + + +class HasErrorInMRO(six.with_metaclass(abc.ABCMeta, Exception)): + pass + + +class Second(HasErrorInMRO): + pass + + +try: + raise Second +except Second: + pass + + +class SomeBase(UnknownError): + pass + + +EXCEPTIONS = (SomeBase, ValueError) + +try: + raise ValueError +except EXCEPTIONS: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_caught.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_caught.txt new file mode 100644 index 0000000..e51030b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_caught.txt @@ -0,0 +1,12 @@ +catching-non-exception:27::"Catching an exception which doesn't inherit from Exception: MyException" +catching-non-exception:33::"Catching an exception which doesn't inherit from Exception: MyException" +catching-non-exception:33::"Catching an exception which doesn't inherit from Exception: MySecondException" +catching-non-exception:54::"Catching an exception which doesn't inherit from Exception: None" +catching-non-exception:54::"Catching an exception which doesn't inherit from Exception: list()" +catching-non-exception:59::"Catching an exception which doesn't inherit from Exception: None" +catching-non-exception:72::"Catching an exception which doesn't inherit from Exception: 4" +catching-non-exception:72::"Catching an exception which doesn't inherit from Exception: None" +catching-non-exception:72::"Catching an exception which doesn't inherit from Exception: list([4, 5, 6])" +catching-non-exception:85::"Catching an exception which doesn't inherit from Exception: NON_EXCEPTION_TUPLE" +catching-non-exception:103::"Catching an exception which doesn't inherit from Exception: object" +catching-non-exception:108::"Catching an exception which doesn't inherit from Exception: range" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_raised.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_raised.py new file mode 100644 index 0000000..78e6b65 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_raised.py @@ -0,0 +1,105 @@ +# pylint:disable=too-few-public-methods,no-init,import-error,missing-docstring, not-callable, useless-object-inheritance +"""test pb with exceptions and old/new style classes""" + + +class ValidException(Exception): + """Valid Exception.""" + +class OldStyleClass: + """Not an exception.""" + +class NewStyleClass(object): + """Not an exception.""" + + +def good_case(): + """raise""" + raise ValidException('hop') + +def good_case1(): + """zlib.error is defined in C module.""" + import zlib + raise zlib.error(4) + +def good_case2(): + """decimal.DivisionByZero is defined in C on Python 3.""" + import decimal + raise decimal.DivisionByZero(4) + +def good_case3(): + """io.BlockingIOError is defined in C.""" + import io + raise io.BlockingIOError + +def bad_case0(): + """raise""" + # +2:<3.0:[nonstandard-exception] + # +1:>=3.0:[raising-non-exception] + raise OldStyleClass('hop') + +def bad_case1(): + """raise""" + raise NewStyleClass() # [raising-non-exception] + +def bad_case2(): + """raise""" + # +2:<3.0:[nonstandard-exception] + # +1:>=3.0:[raising-non-exception] + raise OldStyleClass('hop') + +def bad_case3(): + """raise""" + raise NewStyleClass # [raising-non-exception] + +def bad_case4(): + """raise""" + raise NotImplemented('hop') # [notimplemented-raised] + +def bad_case5(): + """raise""" + raise 1 # [raising-bad-type] + +def bad_case6(): + """raise""" + raise None # [raising-bad-type] + +def bad_case7(): + """raise list""" + raise list # [raising-non-exception] + +def bad_case8(): + """raise tuple""" + raise tuple # [raising-non-exception] + +def bad_case9(): + """raise dict""" + raise dict # [raising-non-exception] + +def unknown_bases(): + """Don't emit when we don't know the bases.""" + from lala import bala + class MyException(bala): + pass + raise MyException + + +def exception_instance_regression(): + """Exceptions have a particular class type""" + try: + int("9a") + except ValueError as exc: + raise exc + + +def reusing_same_name_picks_the_latest_raised_value(): + class Error(Exception): + """some error""" + + exceptions = tuple([ValueError, TypeError]) + try: + raise ValueError + except exceptions as exc: # pylint: disable=catching-non-exception + # https://github.com/PyCQA/pylint/issues/1756 + exc = Error(exc) + if exc: + raise exc diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_raised.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_raised.txt new file mode 100644 index 0000000..47eb0fe --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_exceptions_raised.txt @@ -0,0 +1,12 @@ +nonstandard-exception:38:bad_case0:"Exception doesn't inherit from standard ""Exception"" class" +raising-non-exception:38:bad_case0:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:42:bad_case1:Raising a new style class which doesn't inherit from BaseException +nonstandard-exception:48:bad_case2:"Exception doesn't inherit from standard ""Exception"" class" +raising-non-exception:48:bad_case2:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:52:bad_case3:Raising a new style class which doesn't inherit from BaseException +notimplemented-raised:56:bad_case4:NotImplemented raised - should raise NotImplementedError +raising-bad-type:60:bad_case5:Raising int while only classes or instances are allowed +raising-bad-type:64:bad_case6:Raising NoneType while only classes or instances are allowed +raising-non-exception:68:bad_case7:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:72:bad_case8:Raising a new style class which doesn't inherit from BaseException +raising-non-exception:76:bad_case9:Raising a new style class which doesn't inherit from BaseException \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_length_returned.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_length_returned.py new file mode 100644 index 0000000..e57db52 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_length_returned.py @@ -0,0 +1,64 @@ +"""Check invalid value returned by __len__ """ + +# pylint: disable=too-few-public-methods,missing-docstring,no-self-use,import-error, useless-object-inheritance +import sys + +import six + +from missing import Missing + + +class FirstGoodLen(object): + """__len__ returns <type 'int'>""" + + def __len__(self): + return 0 + + +class SecondGoodLen(object): + """__len__ returns <type 'long'>""" + + def __len__(self): + return sys.maxsize + 1 + + +class LenMetaclass(type): + def __len__(cls): + return 1 + + +@six.add_metaclass(LenMetaclass) +class ThirdGoodLen(object): + """Length through the metaclass.""" + + +class FirstBadLen(object): + """ __len__ returns a negative integer """ + + def __len__(self): # [invalid-length-returned] + return -1 + + +class SecondBadLen(object): + """ __len__ returns non-int """ + + def __len__(self): # [invalid-length-returned] + return 3.0 + + +class ThirdBadLen(object): + """ __len__ returns node which does not have 'value' in AST """ + + def __len__(self): # [invalid-length-returned] + return lambda: 3 + + +class AmbigousLen(object): + """ Uninferable return value """ + __len__ = lambda self: Missing + + +class AnotherAmbiguousLen(object): + """Potential uninferable return value""" + def __len__(self): + return int(Missing) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_length_returned.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_length_returned.txt new file mode 100644 index 0000000..6febeb6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_length_returned.txt @@ -0,0 +1,3 @@ +invalid-length-returned:38:FirstBadLen.__len__:__len__ does not return non-negative integer +invalid-length-returned:45:SecondBadLen.__len__:__len__ does not return non-negative integer +invalid-length-returned:52:ThirdBadLen.__len__:__len__ does not return non-negative integer diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass.py new file mode 100644 index 0000000..c0e9d74 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass.py @@ -0,0 +1,34 @@ +# pylint: disable=missing-docstring, too-few-public-methods, import-error,unused-argument, useless-object-inheritance + +import abc + +import six +from unknown import Unknown + + +class InvalidAsMetaclass(object): + pass + + +class ValidAsMetaclass(type): + pass + + +@six.add_metaclass(type) +class FirstGood(object): + pass + + +@six.add_metaclass(abc.ABCMeta) +class SecondGood(object): + pass + + +@six.add_metaclass(Unknown) +class ThirdGood(object): + pass + + +@six.add_metaclass(ValidAsMetaclass) +class FourthGood(object): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.py new file mode 100644 index 0000000..2fc458f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring, too-few-public-methods, import-error,unused-argument + +from unknown import Unknown + + +def valid_metaclass_1(name, _, attrs): + return type + + +def valid_metaclass_2(_name, _bases, _attrs): + return Unknown + + +class GoodMetaclass(metaclass=valid_metaclass_1): + pass + + +class SecondGoodMetaclass(metaclass=valid_metaclass_2): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_metaclass_py3.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_name.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_name.py new file mode 100644 index 0000000..1a82b74 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_name.py @@ -0,0 +1,39 @@ +""" Tests for invalid-name checker. """ +# pylint: disable=unused-import, no-absolute-import, wrong-import-position + +AAA = 24 +try: + import collections +except ImportError: + collections = None + +aaa = 42 # [invalid-name] +try: + import time +except ValueError: + time = None # [invalid-name] + +try: + from sys import argv, executable as python +except ImportError: + argv = 42 + python = 24 + +def test(): + """ Shouldn't emit an invalid-name here. """ + try: + import re + except ImportError: + re = None + return re + +def a(): # [invalid-name] + """yo""" + + +def _generate_cmdline_tests(): + TestCase = collections.namedtuple('TestCase', 'cmd, valid') + valid = ['leave-mode', 'hint all'] + # Valid command only -> valid + for item in valid: + yield TestCase(''.join(item), True) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_name.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_name.txt new file mode 100644 index 0000000..25d3a56 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_name.txt @@ -0,0 +1,3 @@ +invalid-name:10::"Constant name ""aaa"" doesn't conform to UPPER_CASE naming style" +invalid-name:14::"Constant name ""time"" doesn't conform to UPPER_CASE naming style" +invalid-name:30:a:"Function name ""a"" doesn't conform to snake_case naming style" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_sequence_index.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_sequence_index.py new file mode 100644 index 0000000..d11155c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_sequence_index.py @@ -0,0 +1,242 @@ +"""Errors for invalid sequence indices""" +# pylint: disable=too-few-public-methods, no-self-use, import-error, missing-docstring, useless-object-inheritance, unnecessary-pass +import six +from unknown import Unknown + +TESTLIST = [1, 2, 3] +TESTTUPLE = (1, 2, 3) +TESTSTR = '123' + +# getitem tests with bad indices +def function1(): + """list index is a function""" + return TESTLIST[id] # [invalid-sequence-index] + +def function2(): + """list index is None""" + return TESTLIST[None] # [invalid-sequence-index] + +def function3(): + """list index is a float expression""" + return TESTLIST[float(0)] # [invalid-sequence-index] + +def function4(): + """list index is a str constant""" + return TESTLIST['0'] # [invalid-sequence-index] + +def function5(): + """list index does not implement __index__""" + class NonIndexType(object): + """Class without __index__ method""" + pass + + return TESTLIST[NonIndexType()] # [invalid-sequence-index] + +def function6(): + """Tuple index is None""" + return TESTTUPLE[None] # [invalid-sequence-index] + +def function7(): + """String index is None""" + return TESTSTR[None] # [invalid-sequence-index] + +def function8(): + """Index of subclass of tuple is None""" + class TupleTest(tuple): + """Subclass of tuple""" + pass + return TupleTest()[None] # [invalid-sequence-index] + +# getitem tests with good indices +def function9(): + """list index is an int constant""" + return TESTLIST[0] # no error + +def function10(): + """list index is an integer expression""" + return TESTLIST[int(0.0)] # no error + +def function11(): + """list index is a slice""" + return TESTLIST[slice(1, 2, 3)] # no error + +def function12(): + """list index implements __index__""" + class IndexType(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + return TESTLIST[IndexType()] # no error + +def function13(): + """list index implements __index__ in a superclass""" + class IndexType(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + class IndexSubType(IndexType): + """Class with __index__ in parent""" + pass + + return TESTLIST[IndexSubType()] # no error + +def function14(): + """Tuple index is an int constant""" + return TESTTUPLE[0] + +def function15(): + """String index is an int constant""" + return TESTSTR[0] + +def function16(): + """Index of subclass of tuple is an int constant""" + class TupleTest(tuple): + """Subclass of tuple""" + pass + return TupleTest()[0] # no error + +def function17(): + """Index of subclass of tuple with custom __getitem__ is None""" + class TupleTest(tuple): + """Subclass of tuple with custom __getitem__""" + def __getitem__(self, index): + """Allow non-integer indices""" + return 0 + return TupleTest()[None] # no error + +def function18(): + """Index of subclass of tuple with __getitem__ in superclass is None""" + class TupleTest(tuple): + """Subclass of tuple with custom __getitem__""" + def __getitem__(self, index): + """Allow non-integer indices""" + return 0 + + class SubTupleTest(TupleTest): + """Subclass of a subclass of tuple""" + pass + + return SubTupleTest()[None] # no error + +# Test with set and delete statements +def function19(): + """Set with None and integer indices""" + TESTLIST[None] = 0 # [invalid-sequence-index] + TESTLIST[0] = 0 # no error + +def function20(): + """Delete with None and integer indicies""" + del TESTLIST[None] # [invalid-sequence-index] + del TESTLIST[0] # no error + +def function21(): + """Set and delete on a subclass of list""" + class ListTest(list): + """Inherit all list get/set/del handlers""" + pass + test = ListTest() + + # Set and delete with invalid indices + test[None] = 0 # [invalid-sequence-index] + del test[None] # [invalid-sequence-index] + + # Set and delete with valid indices + test[0] = 0 # no error + del test[0] # no error + +def function22(): + """Get, set, and delete on a subclass of list that overrides __setitem__""" + class ListTest(list): + """Override setitem but not get or del""" + def __setitem__(self, key, value): + pass + test = ListTest() + + # failure on the getitem with None + test[None][0] = 0 # [invalid-sequence-index] + # failure on the getitem with None + del test[None] # [invalid-sequence-index] + + test[0][0] = 0 # getitem with int and setitem with int, no error + test[None] = 0 # setitem overridden, no error + test[0] = 0 # setitem with int, no error + del test[0] # delitem with int, no error + +def function23(): + """Get, set, and delete on a subclass of list that overrides __delitem__""" + class ListTest(list): + """Override delitem but not get or set""" + def __delitem__(self, key): + pass + test = ListTest() + + # failure on the getitem with None + test[None][0] = 0 # [invalid-sequence-index] + # setitem with invalid index + test[None] = 0 # [invalid-sequence-index] + + test[0][0] = 0 # getitem with int and setitem with int, no error + test[0] = 0 # setitem with int, no error + del test[None] # delitem overridden, no error + del test[0] # delitem with int, no error + +def function24(): + """Get, set, and delete on a subclass of list that overrides __getitem__""" + class ListTest(list): + """Override gelitem but not del or set""" + def __getitem__(self, key): + pass + test = ListTest() + + # setitem with invalid index + test[None] = 0 # [invalid-sequence-index] + # delitem with invalid index + del test[None] # [invalid-sequence-index] + + test[None][0] = 0 # getitem overridden, no error + test[0][0] = 0 # getitem with int and setitem with int, no error + test[0] = 0 # setitem with int, no error + del test[0] # delitem with int, no error + +# Teest ExtSlice usage +def function25(): + """Extended slice used with a list""" + return TESTLIST[..., 0] # [invalid-sequence-index] + +def function26(): + """Extended slice used with an object that implements __getitem__""" + class ExtSliceTest(object): + """Permit extslice syntax by implementing __getitem__""" + def __getitem__(self, index): + return 0 + return ExtSliceTest()[..., 0] # no error + +def function27(): + """Don't warn in the case where the indexed object has unknown base classes.""" + class UnknownBase(Unknown): + pass + slices = UnknownBase["aaaa"] + UnknownBase()[object] + ext_slices = UnknownBase[..., 0] + UnknownBase()[..., 0] + return slices, ext_slices + + +def function28(): + """Don't emit for classes with the right implementation.""" + + class Meta(type): + def __getitem__(cls, arg): + return 24 + + @six.add_metaclass(Meta) + class Works(object): + pass + + @six.add_metaclass(Meta) + class Error(list): + pass + + return Works['hello'] + Error['hello'] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_sequence_index.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_sequence_index.txt new file mode 100644 index 0000000..204aebc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_sequence_index.txt @@ -0,0 +1,20 @@ +invalid-sequence-index:13:function1:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:17:function2:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:21:function3:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:25:function4:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:33:function5:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:37:function6:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:41:function7:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:48:function8:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:128:function19:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:133:function20:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:144:function21:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:145:function21:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:159:function22:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:160:function22:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:162:function22:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:178:function23:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:180:function23:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:196:function24:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:198:function24:Sequence index is not an int, slice, or instance with __index__ +invalid-sequence-index:208:function25:Sequence index is not an int, slice, or instance with __index__ \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_slice_index.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_slice_index.py new file mode 100644 index 0000000..1eb2fda --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_slice_index.py @@ -0,0 +1,71 @@ +"""Errors for invalid slice indices""" +# pylint: disable=too-few-public-methods, no-self-use,missing-docstring,expression-not-assigned, useless-object-inheritance, unnecessary-pass + + +TESTLIST = [1, 2, 3] + +# Invalid indices +def function1(): + """functions used as indices""" + return TESTLIST[id:id:] # [invalid-slice-index,invalid-slice-index] + +def function2(): + """strings used as indices""" + return TESTLIST['0':'1':] # [invalid-slice-index,invalid-slice-index] + +def function3(): + """class without __index__ used as index""" + + class NoIndexTest(object): + """Class with no __index__ method""" + pass + + return TESTLIST[NoIndexTest()::] # [invalid-slice-index] + +# Valid indices +def function4(): + """integers used as indices""" + return TESTLIST[0:0:0] # no error + +def function5(): + """None used as indices""" + return TESTLIST[None:None:None] # no error + +def function6(): + """class with __index__ used as index""" + class IndexTest(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + return TESTLIST[IndexTest():None:None] # no error + +def function7(): + """class with __index__ in superclass used as index""" + class IndexType(object): + """Class with __index__ method""" + def __index__(self): + """Allow objects of this class to be used as slice indices""" + return 0 + + class IndexSubType(IndexType): + """Class with __index__ in parent""" + pass + + return TESTLIST[IndexSubType():None:None] # no error + +def function8(): + """slice object used as index""" + return TESTLIST[slice(1, 2, 3)] # no error + + +def function9(): + """Use a custom class that knows how to handle string slices""" + class StringSlice: + def __getitem__(self, item): + return item + + StringSlice()["a":"b":"c"] + StringSlice()["a":"b":"c", "a":"b"] + StringSlice()[slice("a", "b", "c")] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_slice_index.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_slice_index.txt new file mode 100644 index 0000000..cd4dc6e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_slice_index.txt @@ -0,0 +1,5 @@ +invalid-slice-index:10:function1:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:10:function1:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:14:function2:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:14:function2:Slice index is not an int, None, or instance with __index__ +invalid-slice-index:23:function3:Slice index is not an int, None, or instance with __index__ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.py new file mode 100644 index 0000000..112dd0b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.py @@ -0,0 +1,4 @@ +"""Test for *a = b """ + +*FIRST = [1, 2, 3] # [invalid-star-assignment-target] +(*FIRST, ) = [1, 2, 3] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.txt new file mode 100644 index 0000000..8cef8eb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_star_assignment_target.txt @@ -0,0 +1 @@ +invalid-star-assignment-target:3::Starred assignment target must be in a list or tuple diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_unary_operand_type.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_unary_operand_type.py new file mode 100644 index 0000000..cb27878 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_unary_operand_type.py @@ -0,0 +1,51 @@ +"""Detect problems with invalid operands used on invalid objects.""" +# pylint: disable=missing-docstring,too-few-public-methods,invalid-name +# pylint: disable=unused-variable, useless-object-inheritance + +import collections + + +class Implemented(object): + def __invert__(self): + return 42 + def __pos__(self): + return 42 + def __neg__(self): + return 42 + + +def these_are_good(): + negative = -1 + negative1 = -1.0 + positive = +1 + positive2 = +1.0 + inverted = ~1 + not_int = not 1 + not_float = not 2.0 + not_string = not "" + not_list = not [] + not_dict = not {} + not_tuple = not (1, 2) + inverted_instance = ~Implemented() + positive_instance = +Implemented() + negative_instance = -Implemented() + not_instance = not Implemented() + + +def these_are_bad(): + invert_list = ~[] # [invalid-unary-operand-type] + invert_tuple = ~() # [invalid-unary-operand-type] + invert_dict = ~dict() # [invalid-unary-operand-type] + invert_dict_1 = ~{} # [invalid-unary-operand-type] + invert_set = ~set() # [invalid-unary-operand-type] + neg_set = -set() # [invalid-unary-operand-type] + neg_str = -"" # [invalid-unary-operand-type] + invert_str = ~"" # [invalid-unary-operand-type] + pos_str = +"" # [invalid-unary-operand-type] + class A(object): + pass + invert_func = ~(lambda: None) # [invalid-unary-operand-type] + invert_class = ~A # [invalid-unary-operand-type] + invert_instance = ~A() # [invalid-unary-operand-type] + invert_module = ~collections # [invalid-unary-operand-type] + invert_float = ~2.0 # [invalid-unary-operand-type] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_unary_operand_type.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_unary_operand_type.txt new file mode 100644 index 0000000..437d8e7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/invalid_unary_operand_type.txt @@ -0,0 +1,14 @@ +invalid-unary-operand-type:36:these_are_bad:"bad operand type for unary ~: list" +invalid-unary-operand-type:37:these_are_bad:"bad operand type for unary ~: tuple" +invalid-unary-operand-type:38:these_are_bad:"bad operand type for unary ~: dict" +invalid-unary-operand-type:39:these_are_bad:"bad operand type for unary ~: dict" +invalid-unary-operand-type:40:these_are_bad:"bad operand type for unary ~: set" +invalid-unary-operand-type:41:these_are_bad:"bad operand type for unary -: set" +invalid-unary-operand-type:42:these_are_bad:"bad operand type for unary -: str" +invalid-unary-operand-type:43:these_are_bad:"bad operand type for unary ~: str" +invalid-unary-operand-type:44:these_are_bad:"bad operand type for unary +: str" +invalid-unary-operand-type:47:these_are_bad:"bad operand type for unary ~: <lambda>" +invalid-unary-operand-type:48:these_are_bad:"bad operand type for unary ~: A" +invalid-unary-operand-type:49:these_are_bad:"bad operand type for unary ~: A" +invalid-unary-operand-type:50:these_are_bad:"bad operand type for unary ~: collections" +invalid-unary-operand-type:51:these_are_bad:"bad operand type for unary ~: float" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context.py new file mode 100644 index 0000000..abe5cc6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context.py @@ -0,0 +1,192 @@ +""" +Checks that primitive values are not used in an +iterating/mapping context. +""" +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods,no-init,no-self-use,import-error,unused-argument,bad-mcs-method-argument,wrong-import-position,no-else-return, useless-object-inheritance +from __future__ import print_function + +# primitives +numbers = [1, 2, 3] + +for i in numbers: + pass + +for i in iter(numbers): + pass + +for i in "123": + pass + +for i in u"123": + pass + +for i in b"123": + pass + +for i in bytearray(b"123"): + pass + +for i in set(numbers): + pass + +for i in frozenset(numbers): + pass + +for i in dict(a=1, b=2): + pass + +# comprehensions +for i in [x for x in range(10)]: + pass + +for i in {x for x in range(1, 100, 2)}: + pass + +for i in {x: 10 - x for x in range(10)}: + pass + +# generators +def powers_of_two(): + k = 0 + while k < 10: + yield 2 ** k + k += 1 + +for i in powers_of_two(): + pass + +for i in powers_of_two: # [not-an-iterable] + pass + +# check for custom iterators +class A(object): + pass + +class B(object): + def __iter__(self): + return self + + def __next__(self): + return 1 + + def next(self): + return 1 + +class C(object): + "old-style iterator" + def __getitem__(self, k): + if k > 10: + raise IndexError + return k + 1 + + def __len__(self): + return 10 + +for i in C(): + print(i) + + +def test(*args): + print(args) + + +test(*A()) # [not-an-iterable] +test(*B()) +test(*B) # [not-an-iterable] +for i in A(): # [not-an-iterable] + pass +for i in B(): + pass +for i in B: # [not-an-iterable] + pass + +for i in range: # [not-an-iterable] + pass + +# check that primitive non-iterable types are caught +for i in True: # [not-an-iterable] + pass + +for i in None: # [not-an-iterable] + pass + +for i in 8.5: # [not-an-iterable] + pass + +for i in 10: # [not-an-iterable] + pass + + +# skip uninferable instances +from some_missing_module import Iterable + +class MyClass(Iterable): + pass + +m = MyClass() +for i in m: + print(i) + +# skip checks if statement is inside mixin/base/abstract class +class ManagedAccessViewMixin(object): + access_requirements = None + + def get_access_requirements(self): + return self.access_requirements + + def dispatch(self, *_args, **_kwargs): + klasses = self.get_access_requirements() + + # no error should be emitted here + for requirement in klasses: + print(requirement) + +class BaseType(object): + valid_values = None + + def validate(self, value): + if self.valid_values is None: + return True + else: + # error should not be emitted here + for v in self.valid_values: + if value == v: + return True + return False + +class AbstractUrlMarkManager(object): + def __init__(self): + self._lineparser = None + self._init_lineparser() + # error should not be emitted here + for line in self._lineparser: + print(line) + + def _init_lineparser(self): + raise NotImplementedError + +# class is not named as abstract +# but still is deduceably abstract +class UrlMarkManager(object): + def __init__(self): + self._lineparser = None + self._init_lineparser() + # error should not be emitted here + for line in self._lineparser: + print(line) + + def _init_lineparser(self): + raise NotImplementedError + + +class HasDynamicGetattr(object): + + def __init__(self): + self._obj = [] + + def __getattr__(self, attr): + return getattr(self._obj, attr) + + +for elem in HasDynamicGetattr(): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context.txt new file mode 100644 index 0000000..fbe1433 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context.txt @@ -0,0 +1,10 @@ +not-an-iterable:58::Non-iterable value powers_of_two is used in an iterating context +not-an-iterable:93::Non-iterable value A() is used in an iterating context +not-an-iterable:95::Non-iterable value B is used in an iterating context +not-an-iterable:96::Non-iterable value A() is used in an iterating context +not-an-iterable:100::Non-iterable value B is used in an iterating context +not-an-iterable:103::Non-iterable value range is used in an iterating context +not-an-iterable:107::Non-iterable value True is used in an iterating context +not-an-iterable:110::Non-iterable value None is used in an iterating context +not-an-iterable:113::Non-iterable value 8.5 is used in an iterating context +not-an-iterable:116::Non-iterable value 10 is used in an iterating context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.py new file mode 100644 index 0000000..22c60c1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.py @@ -0,0 +1,18 @@ +""" +Checks that iterable metaclasses are recognized by pylint. +""" +# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,bad-mcs-method-argument, useless-object-inheritance + +# metaclasses as iterables +class Meta(type): + def __iter__(self): + return iter((1, 2, 3)) + +class SomeClass(object): + __metaclass__ = Meta + + +for i in SomeClass: + print i +for i in SomeClass(): # [not-an-iterable] + print i diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.txt new file mode 100644 index 0000000..8de579a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py2.txt @@ -0,0 +1 @@ +not-an-iterable:17::Non-iterable value SomeClass() is used in an iterating context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.py new file mode 100644 index 0000000..34047ed --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.py @@ -0,0 +1,55 @@ +""" +Checks that iterable metaclasses are recognized by pylint. +""" +# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,bad-mcs-method-argument +# pylint: disable=wrong-import-position +# metaclasses as iterables +class Meta(type): + def __iter__(self): + return iter((1, 2, 3)) + +class SomeClass(metaclass=Meta): + pass + + +for i in SomeClass: + print(i) +for i in SomeClass(): # [not-an-iterable] + print(i) + + +import asyncio + + +@asyncio.coroutine +def coroutine_function_return_none(): + return + + +@asyncio.coroutine +def coroutine_function_return_object(): + return 12 + + +@asyncio.coroutine +def coroutine_function_return_future(): + return asyncio.Future() + + +@asyncio.coroutine +def coroutine_function_pass(): + pass + + +@asyncio.coroutine +def coroutine_generator(): + yield + + +@asyncio.coroutine +def main(): + yield from coroutine_function_return_none() + yield from coroutine_function_return_object() + yield from coroutine_function_return_future() + yield from coroutine_function_pass() + yield from coroutine_generator() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.rc new file mode 100644 index 0000000..9bf6df0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.0 + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.txt new file mode 100644 index 0000000..8de579a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py3.txt @@ -0,0 +1 @@ +not-an-iterable:17::Non-iterable value SomeClass() is used in an iterating context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.py new file mode 100644 index 0000000..3a4740c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.py @@ -0,0 +1,28 @@ +# pylint: disable=missing-docstring,too-few-public-methods,unused-variable +import asyncio + +class AIter: + async def __aiter__(self): + for value in range(20): + yield value + + async def to_list(self): + values = [m async for m in self] + other_values = [m for m in self] # [not-an-iterable] + for value in self: # [not-an-iterable] + yield value + async for value in self: + yield value + + +async def some_iter_func(number): + """ emits 1 number per second """ + for i in range(1, number): + yield i + await asyncio.sleep(1) + + +async def count_to(number): + """ counts to n in async manner""" + async for i in some_iter_func(number): + print(i) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.rc new file mode 100644 index 0000000..1450ccc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.txt new file mode 100644 index 0000000..877323c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/iterable_context_py36.txt @@ -0,0 +1,2 @@ +not-an-iterable:11:AIter.to_list:Non-iterable value self is used in an iterating context +not-an-iterable:12:AIter.to_list:Non-iterable value self is used in an iterating context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/keyword_arg_before_vararg.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/keyword_arg_before_vararg.py new file mode 100644 index 0000000..1192874 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/keyword_arg_before_vararg.py @@ -0,0 +1,35 @@ +"""Unittests for W1125 (kw args before *args)""" +from __future__ import absolute_import, print_function + +# pylint: disable=unused-argument, useless-object-inheritance, unnecessary-pass +def check_kwargs_before_args(param1, param2=2, *args): # [keyword-arg-before-vararg] + """docstring""" + pass + +check_kwargs_before_args(5) + +# pylint: disable=too-few-public-methods, invalid-name +class AAAA(object): + """class AAAA""" + def func_in_class(self, param1, param2=2, *args): # [keyword-arg-before-vararg] + "method in class AAAA" + pass + + @staticmethod + def static_method_in_class(param1, param2=3, *args): # [keyword-arg-before-vararg] + "static method in class AAAA" + pass + + @classmethod + def class_method_in_class(cls, param1, param2=4, *args): # [keyword-arg-before-vararg] + "class method in class AAAA" + pass + +some_var = AAAA() +some_var.func_in_class(3) + +some_var.static_method_in_class(4) +AAAA.static_method_in_class(4) + +some_var.class_method_in_class(5) +AAAA.class_method_in_class(5) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/keyword_arg_before_vararg.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/keyword_arg_before_vararg.txt new file mode 100644 index 0000000..c83ff73 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/keyword_arg_before_vararg.txt @@ -0,0 +1,4 @@ +keyword-arg-before-vararg:5:check_kwargs_before_args:Keyword argument before variable positional arguments list in the definition of check_kwargs_before_args function +keyword-arg-before-vararg:14:AAAA.func_in_class:Keyword argument before variable positional arguments list in the definition of func_in_class function +keyword-arg-before-vararg:19:AAAA.static_method_in_class:Keyword argument before variable positional arguments list in the definition of static_method_in_class function +keyword-arg-before-vararg:24:AAAA.class_method_in_class:Keyword argument before variable positional arguments list in the definition of class_method_in_class function diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/len_checks.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/len_checks.py new file mode 100644 index 0000000..8b35a22 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/len_checks.py @@ -0,0 +1,77 @@ +# pylint: disable=too-few-public-methods,import-error, no-absolute-import,missing-docstring, misplaced-comparison-constant +# pylint: disable=useless-super-delegation,wrong-import-position,invalid-name, wrong-import-order + +if len('TEST'): # [len-as-condition] + pass + +while not len('TEST'): # [len-as-condition] + pass + +assert len('TEST') > 0 # [len-as-condition] + +x = 1 if len('TEST') != 0 else 2 # [len-as-condition] + +if len('TEST') == 0: # [len-as-condition] + pass + +if True and len('TEST') == 0: # [len-as-condition] + pass + +if 0 == len('TEST') < 10: # [len-as-condition] + pass + +if 0 < 1 <= len('TEST') < 10: # Should be fine + pass + +if 10 > len('TEST') != 0: # [len-as-condition] + pass + +z = False +if z and len(['T', 'E', 'S', 'T']): # [len-as-condition] + pass + +if 10 > len('TEST') > 1 > 0: + pass + +f_o_o = len('TEST') or 42 # Should be fine + +a = x and len(x) # Should be fine + +if 0 <= len('TEST') < 100: # Should be fine + pass + +if z or 10 > len('TEST') != 0: # [len-as-condition] + pass + +def some_func(): + return len('TEST') > 0 # Should be fine + + +def github_issue_1325(): + l = [1, 2, 3] + length = len(l) if l else 0 + return length + + +def github_issue_1331(*args): + assert False, len(args) + + +def github_issue_1331_v2(*args): + assert len(args), args # [len-as-condition] + + +def github_issue_1331_v3(*args): + assert len(args) or z, args # [len-as-condition] + +if len('TEST') < 1: # [len-as-condition] + pass + +if len('TEST') <= 0: # [len-as-condition] + pass + +if 1 > len('TEST'): # [len-as-condition] + pass + +if 0 >= len('TEST'): # [len-as-condition] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/len_checks.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/len_checks.txt new file mode 100644 index 0000000..a3ee678 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/len_checks.txt @@ -0,0 +1,16 @@ +len-as-condition:4::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:7::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:10::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:12::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:14::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:17::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:20::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:26::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:30::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:43::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:61:github_issue_1331_v2:Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:65:github_issue_1331_v3:Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:67::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:70::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:73::Do not use `len(SEQUENCE)` to determine if a sequence is empty +len-as-condition:76::Do not use `len(SEQUENCE)` to determine if a sequence is empty diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.py new file mode 100644 index 0000000..bfff514 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.py @@ -0,0 +1,3 @@ +"mixing line endings are not welcome" +# +1: [unexpected-line-ending-format, mixed-line-endings] +CONST = 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.rc new file mode 100644 index 0000000..95532ea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.rc @@ -0,0 +1,2 @@ +[Format] +expected-line-ending-format=LF diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.txt new file mode 100644 index 0000000..a18a872 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_endings.txt @@ -0,0 +1,2 @@ +mixed-line-endings:3::Mixed line endings LF and CRLF +unexpected-line-ending-format:3::Unexpected line ending format. There is 'CRLF' while it should be 'LF'. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long.py new file mode 100644 index 0000000..27a2a4f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long.py @@ -0,0 +1,45 @@ +# pylint: disable=invalid-encoded-data, fixme, unnecessary-pass +# +1: [line-too-long] +##################################################################################################### +# +1: [line-too-long] +""" that one is too long tooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo loooooong""" + +# The next line is exactly 80 characters long. +A = "--------------------------------------------------------------------------" + +# Do not trigger the line-too-long warning if the only token that makes the +# line longer than 80 characters is a trailing pylint disable. +# pylint:disable=invalid-name +var = ( + "This line has a disable pragma and whitespace trailing beyond 80 chars. " +) + +# +1: [line-too-long] +badname = "This line is already longer than 100 characters even without the pragma. Trust me. Please." # pylint:disable=invalid-name + +# http://example.com/this/is/a/very/long/url?but=splitting&urls=is&a=pain&so=they&can=be&long + + +# +1: [line-too-long] +# This line is toooooooooooooooooooooooooooooooooooooooooooooooo looooooooooooooooooooooooooooooooooooooooong #pylint: disable=fixme + +# +1: [line-too-long] +# TODO: This line is toooooooooooooooooooooooooooooooooooooooooooooooo looooooooooooooooooooooooooooooooooooooooong #pylint: disable=fixme + + +def function(): + # +3: [line-too-long] + """This is a docstring. + + That contains a very, very long line that exceeds the 100 characters limit by a good margin. So good? + """ + pass + + +# Don't crash when the line is in a docstring +def func_with_long(parameter): + """ + # pylint: disable=line-too-long + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccc + """ + return parameter diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long.txt new file mode 100644 index 0000000..22c2181 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long.txt @@ -0,0 +1,6 @@ +line-too-long:3::Line too long (101/100) +line-too-long:5::Line too long (104/100) +line-too-long:18::Line too long (102/100) +line-too-long:24::Line too long (109/100) +line-too-long:27::Line too long (115/100) +line-too-long:34::Line too long (105/100) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long_end_of_module.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long_end_of_module.py new file mode 100644 index 0000000..d8d4031 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/line_too_long_end_of_module.py @@ -0,0 +1,7 @@ +#pylint: disable=missing-docstring, line-too-long + +# Hey this is a very long commented line just to trigger pylint's line-too-long message. It is just above a dummy function with a very long code line. +def dummy_function(): + print("What a beautiful dummy function with such a very long line inside that it should trigger pylint's line-too-long message ") + +# Hey this is a very long commented line at the end of the module. It is just here to trigger pylint's line-too-long message. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/literal_comparison.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/literal_comparison.py new file mode 100644 index 0000000..646e57e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/literal_comparison.py @@ -0,0 +1,50 @@ +# pylint: disable=missing-docstring, comparison-with-itself + + +if 2 is 2: # [literal-comparison] + pass + +if "a" is b"a": # [literal-comparison] + pass + +if 2.0 is 3.0: # [literal-comparison] + pass + +if () is (1, 2, 3): # [literal-comparison] + pass + +if () is {1:2, 2:3}: # [literal-comparison] + pass + +if [] is [4, 5, 6]: # [literal-comparison] + pass + +if () is {1, 2, 3}: # [literal-comparison] + pass + +if () is not {1:2, 2:3}: # [literal-comparison] + pass + +if [] is not [4, 5, 6]: # [literal-comparison] + pass + +if () is not {1, 2, 3}: # [literal-comparison] + pass + + +CONST = 24 + + +if CONST is 0: # [literal-comparison] + pass + +if CONST is 1: # [literal-comparison] + pass + +if CONST is 42: # [literal-comparison] + pass + +# We do not do inference for this check, since the comparing +# object might be used as a sentinel. +if () is CONST: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/literal_comparison.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/literal_comparison.txt new file mode 100644 index 0000000..5026dec --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/literal_comparison.txt @@ -0,0 +1,13 @@ +literal-comparison:4::Comparison to literal +literal-comparison:7::Comparison to literal +literal-comparison:10::Comparison to literal +literal-comparison:13::Comparison to literal +literal-comparison:16::Comparison to literal +literal-comparison:19::Comparison to literal +literal-comparison:22::Comparison to literal +literal-comparison:25::Comparison to literal +literal-comparison:28::Comparison to literal +literal-comparison:31::Comparison to literal +literal-comparison:38::Comparison to literal +literal-comparison:41::Comparison to literal +literal-comparison:44::Comparison to literal diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation.py new file mode 100644 index 0000000..2b33f22 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation.py @@ -0,0 +1,38 @@ +# pylint: disable=E1101, no-absolute-import, import-error,line-too-long, missing-docstring,wrong-import-order,wrong-import-position +# pylint: disable=invalid-name +try: + import __builtin__ as builtins +except ImportError: + import builtins + +# Muck up the names in an effort to confuse... +import logging as renamed_logging +import os as logging +from uninferable import UNINFERABLE + +FORMAT_STR = '{0}, {1}' + +# Statements that should be flagged: +renamed_logging.debug('{0}, {1}'.format(4, 5)) # [logging-format-interpolation] +renamed_logging.log(renamed_logging.DEBUG, 'msg: {}'.format('Run!')) # [logging-format-interpolation] +renamed_logging.debug(FORMAT_STR.format(4, 5)) # [logging-format-interpolation] +renamed_logging.log(renamed_logging.DEBUG, FORMAT_STR.format(4, 5)) # [logging-format-interpolation] +renamed_logging.info("Read {l} rows".format(l=123456789)) # [logging-format-interpolation] + +# Statements that should not be flagged: +renamed_logging.debug(format(66, 'x')) +renamed_logging.debug(builtins.format(66, 'x')) +renamed_logging.log(renamed_logging.DEBUG, 'msg: Run!'.upper()) +logging.debug('{0}, {1}'.format(4, 5)) +logging.log(logging.DEBUG, 'msg: {}'.format('Run!')) +renamed_logging.info("Read {l:,d} rows".format(l=123456789)) +renamed_logging.info(UNINFERABLE.format(l=123456789)) + + +class Logger(renamed_logging.Logger): + pass + +custom_logger = Logger('three') + +custom_logger.info('testing {0}'.format('info')) # [logging-format-interpolation] +custom_logger.info('testing %s' % 'info') # [logging-not-lazy] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation.txt new file mode 100644 index 0000000..e733fcd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation.txt @@ -0,0 +1,7 @@ +logging-format-interpolation:16::Use % formatting in logging functions and pass the % parameters as arguments +logging-format-interpolation:17::Use % formatting in logging functions and pass the % parameters as arguments +logging-format-interpolation:18::Use % formatting in logging functions and pass the % parameters as arguments +logging-format-interpolation:19::Use % formatting in logging functions and pass the % parameters as arguments +logging-format-interpolation:20::Use % formatting in logging functions and pass the % parameters as arguments +logging-format-interpolation:37::Use % formatting in logging functions and pass the % parameters as arguments +logging-not-lazy:38::Specify string format arguments as logging function parameters diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.py new file mode 100644 index 0000000..f6af9f5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.py @@ -0,0 +1,5 @@ +"""Test logging-format-interpolation for Python 3.6""" +import logging as renamed_logging + + +renamed_logging.info(f'Read {renamed_logging} from globals') # [logging-fstring-interpolation] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.txt new file mode 100644 index 0000000..ec7e5b9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_format_interpolation_py36.txt @@ -0,0 +1 @@ +logging-fstring-interpolation:5::Use % formatting in logging functions and pass the % parameters as arguments \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.py new file mode 100644 index 0000000..5aebb7d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.py @@ -0,0 +1,21 @@ +"""Test logging-fstring-interpolation for Python 3.6""" +# pylint: disable=invalid-name + +from datetime import datetime + +import logging as renamed_logging + + +local_var_1 = 4 +local_var_2 = "run!" + +pi = 3.14159265 + +may_14 = datetime(year=2018, month=5, day=14) + +# Statements that should be flagged: +renamed_logging.debug(f'{local_var_1} {local_var_2}') # [logging-fstring-interpolation] +renamed_logging.log(renamed_logging.DEBUG, f'msg: {local_var_2}') # [logging-fstring-interpolation] +renamed_logging.log(renamed_logging.DEBUG, f'pi: {pi:.3f}') # [logging-fstring-interpolation] +renamed_logging.info(f"{local_var_2.upper()}") # [logging-fstring-interpolation] +renamed_logging.info(f"{may_14:'%b %d: %Y'}") # [logging-fstring-interpolation] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.txt new file mode 100644 index 0000000..e2469d6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_fstring_interpolation_py36.txt @@ -0,0 +1,5 @@ +logging-fstring-interpolation:17::Use % formatting in logging functions and pass the % parameters as arguments +logging-fstring-interpolation:18::Use % formatting in logging functions and pass the % parameters as arguments +logging-fstring-interpolation:19::Use % formatting in logging functions and pass the % parameters as arguments +logging-fstring-interpolation:20::Use % formatting in logging functions and pass the % parameters as arguments +logging-fstring-interpolation:21::Use % formatting in logging functions and pass the % parameters as arguments \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_not_lazy.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_not_lazy.py new file mode 100644 index 0000000..c063432 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_not_lazy.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,no-member,deprecated-method,invalid-name + +# Muck up the names in an effort to confuse... +import logging as renamed_logging +import os as logging + +var = "123" +var_name = 'Var:' +# Statements that should be flagged: +renamed_logging.warn('%s, %s' % (4, 5)) # [logging-not-lazy] +renamed_logging.exception('%s' % 'Exceptional!') # [logging-not-lazy] +renamed_logging.log(renamed_logging.INFO, 'msg: %s' % 'Run!') # [logging-not-lazy] +renamed_logging.log(renamed_logging.INFO, "Var: " + var) # [logging-not-lazy] +renamed_logging.warn('%s' + ' the rest of a single string') # [logging-not-lazy] +renamed_logging.log(renamed_logging.INFO, var_name + var) # [logging-not-lazy] + +var_name = 'Var:' +# Statements that should not be flagged: +renamed_logging.warn('%s, %s', 4, 5) +renamed_logging.log(renamed_logging.INFO, 'msg: %s', 'Run!') +logging.warn('%s, %s' % (4, 5)) +logging.log(logging.INFO, 'msg: %s' % 'Run!') +logging.log("Var: " + var) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_not_lazy.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_not_lazy.txt new file mode 100644 index 0000000..31e7cc4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logging_not_lazy.txt @@ -0,0 +1,6 @@ +logging-not-lazy:10::Specify string format arguments as logging function parameters +logging-not-lazy:11::Specify string format arguments as logging function parameters +logging-not-lazy:12::Specify string format arguments as logging function parameters +logging-not-lazy:13::Specify string format arguments as logging function parameters +logging-not-lazy:14::Specify string format arguments as logging function parameters +logging-not-lazy:15::Specify string format arguments as logging function parameters diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logical_tautology.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logical_tautology.py new file mode 100644 index 0000000..ca7ebb0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logical_tautology.py @@ -0,0 +1,40 @@ +"""Check for logical tautology, when a value is compared against itself.""" +# pylint: disable=missing-docstring, blacklisted-name, singleton-comparison, too-many-return-statements, inconsistent-return-statements, no-else-return, too-many-branches, bad-whitespace, literal-comparison + +def foo(): + arg = 786 + if arg == arg: # [comparison-with-itself] + return True + elif arg != arg: # [comparison-with-itself] + return True + elif arg > arg: # [comparison-with-itself] + return True + elif arg <= arg: # [comparison-with-itself] + return True + elif None == None: # [comparison-with-itself] + return None + elif 786 == 786: # [comparison-with-itself] + return True + elif 786 is 786: # [comparison-with-itself] + return True + elif 786 is not 786: # [comparison-with-itself] + return True + elif arg is arg: # [comparison-with-itself] + return True + elif arg is not arg: # [comparison-with-itself] + return True + elif True is True: # [comparison-with-itself] + return True + elif 666 == 786: + return False + else: + return None + + +def bar(): + arg = 666 + return 666 if arg != arg else 786 # [comparison-with-itself] + +def foobar(): + arg = 786 + return arg > 786 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logical_tautology.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logical_tautology.txt new file mode 100644 index 0000000..4422c85 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/logical_tautology.txt @@ -0,0 +1,12 @@ +comparison-with-itself:6:foo:Redundant comparison - arg == arg +comparison-with-itself:8:foo:Redundant comparison - arg != arg +comparison-with-itself:10:foo:Redundant comparison - arg > arg +comparison-with-itself:12:foo:Redundant comparison - arg <= arg +comparison-with-itself:14:foo:Redundant comparison - None == None +comparison-with-itself:16:foo:Redundant comparison - 786 == 786 +comparison-with-itself:18:foo:Redundant comparison - 786 is 786 +comparison-with-itself:20:foo:Redundant comparison - 786 is not 786 +comparison-with-itself:22:foo:Redundant comparison - arg is arg +comparison-with-itself:24:foo:Redundant comparison - arg is not arg +comparison-with-itself:26:foo:Redundant comparison - True is True +comparison-with-itself:36:bar:Redundant comparison - arg != arg diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_lines_with_utf8.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_lines_with_utf8.py new file mode 100644 index 0000000..a1d90ed --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_lines_with_utf8.py @@ -0,0 +1,7 @@ +# coding: utf-8 +"""Test data file files with non-ASCII content.""" + + +THIS_IS_A_LONG_VARIABLE_NAME = 'Существительное Частица' # but the line is okay + +THIS_IS_A_VERY_LONG_VARIABLE_NAME = 'Существительное Частица' # and the line is not okay # [line-too-long] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_lines_with_utf8.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_lines_with_utf8.txt new file mode 100644 index 0000000..42a7976 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_lines_with_utf8.txt @@ -0,0 +1 @@ +line-too-long:7::Line too long (108/100) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_utf8_lines.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_utf8_lines.py new file mode 100644 index 0000000..815759f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_utf8_lines.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +"""this utf-8 doc string have some non ASCII caracters like 'é', or '¢»ß'""" +### check also comments with some more non ASCII caracters like 'é' or '¢»ß' + +__revision__ = 1100 + +ASCII = "----------------------------------------------------------------------" +UTF_8 = "--------------------------------------------------------------------éé" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_utf8_lines.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/long_utf8_lines.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/lost_exception.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/lost_exception.py new file mode 100644 index 0000000..fe7dedd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/lost_exception.py @@ -0,0 +1,41 @@ +# pylint: disable=missing-docstring, using-constant-test,cell-var-from-loop + +def insidious_break_and_return(): + for i in range(0, -5, -1): + my_var = 0 + + try: + my_var += 1.0/i + if i < -3: + break + else: + return my_var + finally: + if i > -2: + break # [lost-exception] + else: + return my_var # [lost-exception] + return None + + +def break_and_return(): + for i in range(0, -5, -1): + my_var = 0 + if i: + break + try: + my_var += 1.0/i + finally: + for _ in range(2): + if True: + break + else: + def strange(): + if True: + return my_var + return None + strange() + if i: + break + else: + return diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/lost_exception.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/lost_exception.txt new file mode 100644 index 0000000..4fb37ec --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/lost_exception.txt @@ -0,0 +1,2 @@ +lost-exception:15:insidious_break_and_return:break statement in finally block may swallow exception +lost-exception:17:insidious_break_and_return:return statement in finally block may swallow exception \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context.py new file mode 100644 index 0000000..6b3a135 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context.py @@ -0,0 +1,109 @@ +""" +Checks that only valid values are used in a mapping context. +""" +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods,no-self-use,import-error,wrong-import-position, useless-object-inheritance +from __future__ import print_function + + +def test(**kwargs): + print(kwargs) + + +# dictionary value/comprehension +dict_value = dict(a=1, b=2, c=3) +dict_comp = {chr(x): x for x in range(256)} +test(**dict_value) +test(**dict_comp) + + +# in order to be used in kwargs custom mapping class should define +# __iter__(), __getitem__(key) and keys(). +class CustomMapping(object): + def __init__(self): + self.data = dict(a=1, b=2, c=3, d=4, e=5) + + def __getitem__(self, key): + return self.data[key] + + def keys(self): + return self.data.keys() + +test(**CustomMapping()) +test(**CustomMapping) # [not-a-mapping] + +class NotMapping(object): + pass + +test(**NotMapping()) # [not-a-mapping] + +# skip checks if statement is inside mixin/base/abstract class +class SomeMixin(object): + kwargs = None + + def get_kwargs(self): + return self.kwargs + + def run(self, **kwargs): + print(kwargs) + + def dispatch(self): + kws = self.get_kwargs() + self.run(**kws) + +class AbstractThing(object): + kwargs = None + + def get_kwargs(self): + return self.kwargs + + def run(self, **kwargs): + print(kwargs) + + def dispatch(self): + kws = self.get_kwargs() + self.run(**kws) + +class BaseThing(object): + kwargs = None + + def get_kwargs(self): + return self.kwargs + + def run(self, **kwargs): + print(kwargs) + + def dispatch(self): + kws = self.get_kwargs() + self.run(**kws) + +# abstract class +class Thing(object): + def get_kwargs(self): + raise NotImplementedError + + def run(self, **kwargs): + print(kwargs) + + def dispatch(self): + kwargs = self.get_kwargs() + self.run(**kwargs) + +# skip uninferable instances +from some_missing_module import Mapping + +class MyClass(Mapping): + pass + +test(**MyClass()) + + +class HasDynamicGetattr(object): + + def __init__(self): + self._obj = {} + + def __getattr__(self, attr): + return getattr(self._obj, attr) + + +test(**HasDynamicGetattr()) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context.txt new file mode 100644 index 0000000..201da1a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context.txt @@ -0,0 +1,2 @@ +not-a-mapping:32::Non-mapping value CustomMapping is used in a mapping context +not-a-mapping:37::Non-mapping value NotMapping() is used in a mapping context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.py new file mode 100644 index 0000000..f5cdc75 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods,no-self-use,bad-mcs-method-argument, useless-object-inheritance +from __future__ import print_function + + +def test(**kwargs): + print(kwargs) + +# metaclasses as mappings +class Meta(type): + def __getitem__(self, key): + return ord(key) + def keys(self): + return ['a', 'b', 'c'] + +class SomeClass(object): + __metaclass__ = Meta + +test(**SomeClass) +test(**SomeClass()) # [not-a-mapping] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.txt new file mode 100644 index 0000000..59cca6c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py2.txt @@ -0,0 +1 @@ +not-a-mapping:19::Non-mapping value SomeClass() is used in a mapping context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.py new file mode 100644 index 0000000..042d4d0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods,no-self-use +from __future__ import print_function + +def test(**kwargs): + print(kwargs) + +# metaclasses as mappings +class Meta(type): + def __getitem__(cls, key): + return ord(key) + + def keys(cls): + return ['a', 'b', 'c'] + +class SomeClass(metaclass=Meta): + pass + +test(**SomeClass) +test(**SomeClass()) # [not-a-mapping] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.rc new file mode 100644 index 0000000..9bf6df0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.0 + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.txt new file mode 100644 index 0000000..59cca6c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mapping_context_py3.txt @@ -0,0 +1 @@ +not-a-mapping:19::Non-mapping value SomeClass() is used in a mapping context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks.py new file mode 100644 index 0000000..d4aef7c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks.py @@ -0,0 +1,199 @@ +# pylint: disable=print-statement,missing-docstring,no-self-use,too-few-public-methods,bare-except,broad-except, useless-object-inheritance +# pylint: disable=using-constant-test,expression-not-assigned, assigning-non-slot, unused-variable,pointless-statement +from __future__ import print_function +import six +class Provider(object): + """provide some attributes and method""" + cattr = 4 + def __init__(self): + self.attr = 4 + def method(self, val): + """impressive method""" + return self.attr * val + def hophop(self): + """hop method""" + print('hop hop hop', self) + + +class Client(object): + """use provider class""" + + def __init__(self): + self._prov = Provider() + self._prov_attr = Provider.cattr + self._prov_attr2 = Provider.cattribute # [no-member] + self.set_later = 0 + + def set_set_later(self, value): + """set set_later attribute (introduce an inference ambiguity)""" + self.set_later = value + + def use_method(self): + """use provider's method""" + self._prov.hophop() + self._prov.hophophop() # [no-member] + + def use_attr(self): + """use provider's attr""" + print(self._prov.attr) + print(self._prov.attribute) # [no-member] + + def debug(self): + """print debug information""" + print(self.__class__.__name__) + print(self.__doc__) + print(self.__dict__) + print(self.__module__) + + def test_bt_types(self): + """test access to unexistant member of builtin types""" + lis = [] + lis.apppend(self) # [no-member] + dic = {} + dic.set(self) # [no-member] + tup = () + tup.append(self) # [no-member] + string = 'toto' + print(string.loower()) # [no-member] + integer = 1 + print(integer.whatever) # [no-member] + + def test_no_false_positives(self): + none = None + print(none.whatever) + # No misssing in the parents. + super(Client, self).misssing() # [no-member] + + +class Mixin(object): + """No no-member should be emitted for mixins.""" + +class Getattr(object): + """no-member shouldn't be emitted for classes with dunder getattr.""" + + def __getattr__(self, attr): + return self.__dict__[attr] + + +class Getattribute(object): + """no-member shouldn't be emitted for classes with dunder getattribute.""" + + def __getattribute__(self, attr): + return 42 + +print(object.__init__) +print(property.__init__) +print(Client().set_later.lower()) +print(Mixin().nanana()) +print(Getattr().nananan()) +print(Getattribute().batman()) + +try: + Client().missing_method() +except AttributeError: + pass + +try: + Client().indeed() # [no-member] +except ImportError: + pass + +try: + Client.missing() +except AttributeError: + Client.missing() # [no-member] + +try: + Client.missing() +except AttributeError: + try: + Client.missing() # [no-member] + except ValueError: + pass + +try: + if Client: + Client().missing() +except AttributeError: + pass + +try: + Client().indeed() +except AttributeError: + try: + Client.missing() # [no-member] + except Exception: + pass + + +class SuperChecks(str, str): # pylint: disable=duplicate-bases + """Don't fail when the MRO is invalid.""" + def test(self): + super(SuperChecks, self).lalala() + +type(Client()).ala # [no-member] +type({}).bala # [no-member] +type('').portocala # [no-member] + + +def socket_false_positive(): + """Test a regression + Version used: + + - Pylint 0.10.0 + - Logilab common 0.15.0 + - Logilab astroid 0.15.1 + + False E1101 positive, line 23: + Instance of '_socketobject' has no 'connect' member + """ + + import socket + sckt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sckt.connect(('127.0.0.1', 80)) + sckt.close() + + +def no_conjugate_member(magic_flag): + """should not raise E1101 on something.conjugate""" + if magic_flag: + something = 1.0 + else: + something = 1.0j + if isinstance(something, float): + return something + return something.conjugate() + + +class NoDunderNameInInstance(object): + """Emit a warning when accessing __name__ from an instance.""" + def __init__(self): + self.var = self.__name__ # [no-member] + + +class InvalidAccessBySlots(object): + __slots__ = ('a', ) + def __init__(self): + var = self.teta # [no-member] + self.teta = 24 + + +class MetaWithDynamicGetattr(type): + + def __getattr__(cls, attr): + return attr + +@six.add_metaclass(MetaWithDynamicGetattr) +class SomeClass(object): + pass + + +SomeClass.does_not_exist + +class ClassWithMangledAttribute(object): + def __init__(self): + self.name = 'Bug1643' + def __bar(self): + print(self.name + "xD") + +ClassWithMangledAttribute()._ClassWithMangledAttribute__bar() # pylint: disable=protected-access diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks.txt new file mode 100644 index 0000000..bf5f2c2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks.txt @@ -0,0 +1,18 @@ +no-member:24:Client.__init__:Class 'Provider' has no 'cattribute' member:INFERENCE +no-member:34:Client.use_method:Instance of 'Provider' has no 'hophophop' member:INFERENCE +no-member:39:Client.use_attr:Instance of 'Provider' has no 'attribute' member:INFERENCE +no-member:51:Client.test_bt_types:Instance of 'list' has no 'apppend' member; maybe 'append'?:INFERENCE +no-member:53:Client.test_bt_types:Instance of 'dict' has no 'set' member; maybe 'get'?:INFERENCE +no-member:55:Client.test_bt_types:Instance of 'tuple' has no 'append' member:INFERENCE +no-member:57:Client.test_bt_types:Instance of 'str' has no 'loower' member; maybe 'lower'?:INFERENCE +no-member:59:Client.test_bt_types:Instance of 'int' has no 'whatever' member:INFERENCE +no-member:65:Client.test_no_false_positives:Super of 'Client' has no 'misssing' member:INFERENCE +no-member:97::Instance of 'Client' has no 'indeed' member:INFERENCE +no-member:104::Class 'Client' has no 'missing' member:INFERENCE +no-member:110::Class 'Client' has no 'missing' member:INFERENCE +no-member:124::Class 'Client' has no 'missing' member:INFERENCE +no-member:134::Class 'Client' has no 'ala' member:INFERENCE +no-member:135::Class 'dict' has no 'bala' member:INFERENCE +no-member:136::Class 'str' has no 'portocala' member:INFERENCE +no-member:171:NoDunderNameInInstance.__init__:Instance of 'NoDunderNameInInstance' has no '__name__' member:INFERENCE +no-member:177:InvalidAccessBySlots.__init__:Instance of 'InvalidAccessBySlots' has no 'teta' member:INFERENCE \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.py new file mode 100644 index 0000000..407c522 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.py @@ -0,0 +1,27 @@ +# pylint: disable=missing-docstring, too-few-public-methods, pointless-statement, useless-object-inheritance + + +class Parent(object): + + def __init__(self): + self._parent = 42 + self._registry = {} + self._similar1 = 24 + self._similar2 = 23 + self._similar3 = 24 + self._really_similar1 = 23 + self._really_similar2 = 42 + + +class Child(Parent): + + def __init__(self): + super(Child, self).__init__() + + self._similar # [no-member] + self._really_similar # [no-member] + self._paren # [no-member] + # Distance is too big + self._registryyyy # [no-member] + # Nothing close. + self._pretty_sure_this_wont_match # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.rc new file mode 100644 index 0000000..311e051 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.rc @@ -0,0 +1,3 @@ +[TYPECHECK] +missing-member-max-choices = 3 +missing-member-hint-distance = 1 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.txt new file mode 100644 index 0000000..27f1e3d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_hints.txt @@ -0,0 +1,5 @@ +no-member:21:Child.__init__:Instance of 'Child' has no '_similar' member; maybe one of '_similar1', '_similar2' or '_similar3'?:INFERENCE +no-member:22:Child.__init__:Instance of 'Child' has no '_really_similar' member; maybe one of '_really_similar1' or '_really_similar2'?:INFERENCE +no-member:23:Child.__init__:Instance of 'Child' has no '_paren' member; maybe '_parent'?:INFERENCE +no-member:25:Child.__init__:Instance of 'Child' has no '_registryyyy' member:INFERENCE +no-member:27:Child.__init__:Instance of 'Child' has no '_pretty_sure_this_wont_match' member:INFERENCE \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.py new file mode 100644 index 0000000..06f01cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.py @@ -0,0 +1,7 @@ +# pylint: disable=missing-docstring, useless-return + +def func(): + return None + + +SOME_VAR = func().DOES_NOT_EXIST # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.rc new file mode 100644 index 0000000..dd365ac --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.rc @@ -0,0 +1,2 @@ +[TYPECHECK] +ignore-none=no \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.txt new file mode 100644 index 0000000..61ef7e8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_ignore_none.txt @@ -0,0 +1 @@ +no-member:7::Instance of 'NoneType' has no 'DOES_NOT_EXIST' member:INFERENCE \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.py new file mode 100644 index 0000000..407c522 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.py @@ -0,0 +1,27 @@ +# pylint: disable=missing-docstring, too-few-public-methods, pointless-statement, useless-object-inheritance + + +class Parent(object): + + def __init__(self): + self._parent = 42 + self._registry = {} + self._similar1 = 24 + self._similar2 = 23 + self._similar3 = 24 + self._really_similar1 = 23 + self._really_similar2 = 42 + + +class Child(Parent): + + def __init__(self): + super(Child, self).__init__() + + self._similar # [no-member] + self._really_similar # [no-member] + self._paren # [no-member] + # Distance is too big + self._registryyyy # [no-member] + # Nothing close. + self._pretty_sure_this_wont_match # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.rc new file mode 100644 index 0000000..780950d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.rc @@ -0,0 +1,2 @@ +[TYPECHECK] +missing-member-hint=no \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.txt new file mode 100644 index 0000000..eea748d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_no_hints.txt @@ -0,0 +1,5 @@ +no-member:21:Child.__init__:Instance of 'Child' has no '_similar' member:INFERENCE +no-member:22:Child.__init__:Instance of 'Child' has no '_really_similar' member:INFERENCE +no-member:23:Child.__init__:Instance of 'Child' has no '_paren' member:INFERENCE +no-member:25:Child.__init__:Instance of 'Child' has no '_registryyyy' member:INFERENCE +no-member:27:Child.__init__:Instance of 'Child' has no '_pretty_sure_this_wont_match' member:INFERENCE \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.py new file mode 100644 index 0000000..9b592af --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring,import-error + +from unknown import Unknown, some_value + + +def test(argument): + if argument: + return 42 + return Unknown + + +test(some_value).test() # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.rc new file mode 100644 index 0000000..025cd2a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.rc @@ -0,0 +1,2 @@ +[TYPECHECK] +ignore-on-opaque-inference=n diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.txt new file mode 100644 index 0000000..dae2953 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_opaque.txt @@ -0,0 +1 @@ +no-member:12::Instance of 'int' has no 'test' member:INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.py new file mode 100644 index 0000000..8d59b7d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.py @@ -0,0 +1,19 @@ +# pylint: disable=missing-docstring +import collections +import asyncio + +isinstance([], collections.Iterable) + + +async def gen(): + await asyncio.sleep(0.1) + value = yield 42 + print(value) + await asyncio.sleep(0.2) + + +async def test(): + generator = gen() + + await generator.asend(None) + await generator.send(None) # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.rc new file mode 100644 index 0000000..5d05724 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.txt new file mode 100644 index 0000000..82a339d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/member_checks_py37.txt @@ -0,0 +1 @@ +no-member:19:test:AsyncGenerator 'async_generator' has no 'send' member; maybe 'asend'?:INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol.py new file mode 100644 index 0000000..3401f4b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol.py @@ -0,0 +1,123 @@ +# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,too-few-public-methods,import-error,no-init,wrong-import-position,no-else-return, comparison-with-itself, useless-object-inheritance + +# standard types +1 in [1, 2, 3] +1 in {'a': 1, 'b': 2} +1 in {1, 2, 3} +1 in (1, 2, 3) +'1' in "123" +'1' in u"123" +'1' in bytearray(b"123") +1 in frozenset([1, 2, 3]) + +# comprehensions +1 in [x ** 2 % 10 for x in range(10)] +1 in {x ** 2 % 10 for x in range(10)} +1 in {x: x ** 2 % 10 for x in range(10)} + +# iterators +1 in iter([1, 2, 3]) + +# generator +def count(upto=float("inf")): + i = 0 + while True: + if i > upto: + break + yield i + i += 1 + +10 in count(upto=10) + +# custom instance +class UniversalContainer(object): + def __contains__(self, key): + return True + +42 in UniversalContainer() + +# custom iterable +class CustomIterable(object): + def __iter__(self): + return iter((1, 2, 3)) +3 in CustomIterable() + +# old-style iterable +class OldStyleIterable(object): + def __getitem__(self, key): + if key < 10: + return 2 ** key + else: + raise IndexError("bad index") +64 in OldStyleIterable() + +# do not emit warning if class has unknown bases +from some_missing_module import ImportedClass + +class MaybeIterable(ImportedClass): + pass + +10 in MaybeIterable() + +# do not emit warning inside mixins/abstract/base classes +class UsefulMixin(object): + stuff = None + + def get_stuff(self): + return self.stuff + + def act(self, thing): + stuff = self.get_stuff() + if thing in stuff: + pass + +class BaseThing(object): + valid_values = None + + def validate(self, value): + if self.valid_values is None: + return True + else: + # error should not be emitted here + return value in self.valid_values + +class AbstractThing(object): + valid_values = None + + def validate(self, value): + if self.valid_values is None: + return True + else: + # error should not be emitted here + return value in self.valid_values + +# class is not named as abstract +# but still is deduceably abstract +class Thing(object): + valid_values = None + + def __init__(self): + self._init_values() + + def validate(self, value): + if self.valid_values is None: + return True + else: + # error should not be emitted here + return value in self.valid_values + + def _init_values(self): + raise NotImplementedError + +# error cases +42 in 42 # [unsupported-membership-test] +42 not in None # [unsupported-membership-test] +42 in 8.5 # [unsupported-membership-test] + +class EmptyClass(object): + pass + +42 not in EmptyClass() # [unsupported-membership-test] +42 in EmptyClass # [unsupported-membership-test] +42 not in count # [unsupported-membership-test] +42 in range # [unsupported-membership-test] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol.txt new file mode 100644 index 0000000..edb2227 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol.txt @@ -0,0 +1,7 @@ +unsupported-membership-test:113::Value '42' doesn't support membership test +unsupported-membership-test:114::Value 'None' doesn't support membership test +unsupported-membership-test:115::Value '8.5' doesn't support membership test +unsupported-membership-test:120::Value 'EmptyClass()' doesn't support membership test +unsupported-membership-test:121::Value 'EmptyClass' doesn't support membership test +unsupported-membership-test:122::Value 'count' doesn't support membership test +unsupported-membership-test:123::Value 'range' doesn't support membership test diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.py new file mode 100644 index 0000000..8a569c3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.py @@ -0,0 +1,36 @@ +# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,pointless-statement,expression-not-assigned,undefined-variable, useless-object-inheritance + +# metaclasses that support membership test protocol +class MetaIterable(type): + def __iter__(cls): + return iter((1, 2, 3)) + +class MetaOldIterable(type): + def __getitem__(cls, key): + if key < 10: + return key ** 2 + else: + raise IndexError("bad index") + +class MetaContainer(type): + def __contains__(cls, key): + return False + + +class IterableClass(object): + __metaclass__ = MetaIterable + +class OldIterableClass(object): + __metaclass__ = MetaOldIterable + +class ContainerClass(object): + __metaclass__ = MetaContainer + + +def test(): + 1 in IterableClass + 1 in OldIterableClass + 1 in ContainerClass + 1 in IterableClass() # [unsupported-membership-test] + 1 in OldIterableClass() # [unsupported-membership-test] + 1 in ContainerClass() # [unsupported-membership-test] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.rc new file mode 100644 index 0000000..c78f32f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.rc @@ -0,0 +1,3 @@ +[testoptions] +max_pyver=3.0 + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.txt new file mode 100644 index 0000000..4ba7575 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py2.txt @@ -0,0 +1,3 @@ +unsupported-membership-test:34:test:Value 'IterableClass()' doesn't support membership test +unsupported-membership-test:35:test:Value 'OldIterableClass()' doesn't support membership test +unsupported-membership-test:36:test:Value 'ContainerClass()' doesn't support membership test diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.py new file mode 100644 index 0000000..6780723 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.py @@ -0,0 +1,36 @@ +# pylint: disable=missing-docstring,too-few-public-methods,no-init,no-self-use,unused-argument,pointless-statement,expression-not-assigned + +# metaclasses that support membership test protocol +class MetaIterable(type): + def __iter__(cls): + return iter((1, 2, 3)) + +class MetaOldIterable(type): + def __getitem__(cls, key): + if key < 10: + return key ** 2 + + raise IndexError("bad index") + +class MetaContainer(type): + def __contains__(cls, key): + return False + + +class IterableClass(metaclass=MetaOldIterable): + pass + +class OldIterableClass(metaclass=MetaOldIterable): + pass + +class ContainerClass(metaclass=MetaContainer): + pass + + +def test(): + 1 in IterableClass + 1 in OldIterableClass + 1 in ContainerClass + 1 in IterableClass() # [unsupported-membership-test] + 1 in OldIterableClass() # [unsupported-membership-test] + 1 in ContainerClass() # [unsupported-membership-test] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.rc new file mode 100644 index 0000000..9bf6df0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.0 + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.txt new file mode 100644 index 0000000..4ba7575 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/membership_protocol_py3.txt @@ -0,0 +1,3 @@ +unsupported-membership-test:34:test:Value 'IterableClass()' doesn't support membership test +unsupported-membership-test:35:test:Value 'OldIterableClass()' doesn't support membership test +unsupported-membership-test:36:test:Value 'ContainerClass()' doesn't support membership test diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/messages_managed_by_id.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/messages_managed_by_id.py new file mode 100644 index 0000000..a96ac5c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/messages_managed_by_id.py @@ -0,0 +1,11 @@ +# -*- encoding=utf-8 -*- +#pylint: disable=C0111 +def foo(): #pylint: disable=C0102 + return 1 + +def toto(): #pylint: disable=C0102,R1711 + return + +# +1: [missing-docstring] +def test_enabled_by_id_msg(): #pylint: enable=C0111 + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/messages_managed_by_id.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/messages_managed_by_id.txt new file mode 100644 index 0000000..e766ab0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/messages_managed_by_id.txt @@ -0,0 +1,6 @@ +use-symbolic-message-instead:2::"Id 'C0111' is used to disable 'missing-docstring' message emission" +use-symbolic-message-instead:3::"Id 'C0102' is used to disable 'blacklisted-name' message emission" +use-symbolic-message-instead:6::"Id 'C0102' is used to disable 'blacklisted-name' message emission" +use-symbolic-message-instead:6::"Id 'R1711' is used to disable 'useless-return' message emission" +use-symbolic-message-instead:10::"Id 'C0111' is used to enable 'missing-docstring' message emission" +missing-docstring:10:test_enabled_by_id_msg:"Missing function docstring" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/method_hidden.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/method_hidden.py new file mode 100644 index 0000000..4288696 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/method_hidden.py @@ -0,0 +1,60 @@ +# pylint: disable=too-few-public-methods,print-statement, useless-object-inheritance,missing-docstring +"""check method hidding ancestor attribute +""" +from __future__ import print_function + +class Abcd(object): + """dummy""" + def __init__(self): + self.abcd = 1 + +class Cdef(Abcd): + """dummy""" + def abcd(self): # [method-hidden] + """test + """ + print(self) + +class CustomProperty: + """dummy""" + def __init__(self, _): + pass + + def __get__(self, obj, __): + if not obj: + return self + return 5 + + def __set__(self, _, __): + pass + +class Ddef: + """dummy""" + def __init__(self): + self.five = "five" + + @CustomProperty + def five(self): + """Always 5.""" + return self + + +def my_decorator(*args, **kwargs): + return CustomProperty(*args, **kwargs) + + +class Foo: + def __init__(self): + self._bar = 42 + self._baz = 84 + + @my_decorator + def method(self): # E0202 + return self._baz + + @method.setter + def method(self, value): + self._baz = value + + def do_something_with_baz(self, value): + self.method = value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/method_hidden.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/method_hidden.txt new file mode 100644 index 0000000..7dfb8d3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/method_hidden.txt @@ -0,0 +1 @@ +method-hidden:13:Cdef.abcd:An attribute defined in functional.method_hidden line 9 hides this method diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_bare_raise.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_bare_raise.py new file mode 100644 index 0000000..b65bd9b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_bare_raise.py @@ -0,0 +1,85 @@ +# pylint: disable=missing-docstring, broad-except, unreachable, try-except-raise +# pylint: disable=unused-variable, too-few-public-methods, invalid-name, useless-object-inheritance + +try: + raise # [misplaced-bare-raise] +except Exception: + pass + +try: + pass +except Exception: + raise + +# pylint: disable=misplaced-comparison-constant +try: + pass +except Exception: + if 1 == 2: + raise + +def test(): + try: + pass + except Exception: + def chest(): + try: + pass + except Exception: + raise + raise + +def test1(): + try: + if 1 > 2: + def best(): + raise # [misplaced-bare-raise] + except Exception: + pass + raise # [misplaced-bare-raise] +raise # [misplaced-bare-raise] + +try: + pass +finally: + # This might work or might not to, depending if there's + # an error raised inside the try block. But relying on this + # behaviour can be error prone, so we decided to warn + # against it. + raise # [misplaced-bare-raise] + + +class A(object): + try: + pass + except Exception: + raise + raise # [misplaced-bare-raise] + +# This works in Python 2, but the intent is nevertheless +# unclear. It will also not work on Python 3, so it's best +# not to rely on it. +exc = None +try: + 1/0 +except ZeroDivisionError as exc: + pass +if exc: + raise # [misplaced-bare-raise] + +# Don't emit if we're in ``__exit__``. +class ContextManager(object): + def __enter__(self): + return self + def __exit__(self, *args): + raise + + +def test_dont_trigger_in_finally_clause_found_in_exception_handler(): + try: + raise ValueError('bad value') + except ValueError: + try: + raise IOError('failed') + finally: + raise diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_bare_raise.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_bare_raise.txt new file mode 100644 index 0000000..013e58c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_bare_raise.txt @@ -0,0 +1,7 @@ +misplaced-bare-raise:5::The raise statement is not inside an except clause +misplaced-bare-raise:36:test1.best:The raise statement is not inside an except clause +misplaced-bare-raise:39:test1:The raise statement is not inside an except clause +misplaced-bare-raise:40::The raise statement is not inside an except clause +misplaced-bare-raise:49::The raise statement is not inside an except clause +misplaced-bare-raise:57:A:The raise statement is not inside an except clause +misplaced-bare-raise:68::The raise statement is not inside an except clause diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_comparison_constant.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_comparison_constant.py new file mode 100644 index 0000000..29f2b1e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_comparison_constant.py @@ -0,0 +1,36 @@ +"""Check that the constants are on the right side of the comparisons""" + +# pylint: disable=singleton-comparison, missing-docstring, too-few-public-methods, useless-object-inheritance + +class MyClass(object): + def __init__(self): + self.attr = 1 + + def dummy_return(self): + return self.attr + +def dummy_return(): + return 2 + +def bad_comparisons(): + """this is not ok""" + instance = MyClass() + for i in range(10): + if 5 <= i: # [misplaced-comparison-constant] + pass + if 1 == i: # [misplaced-comparison-constant] + pass + if 3 < dummy_return(): # [misplaced-comparison-constant] + pass + if 4 != instance.dummy_return(): # [misplaced-comparison-constant] + pass + if 1 == instance.attr: # [misplaced-comparison-constant] + pass + if "aaa" == instance.attr: # [misplaced-comparison-constant] + pass + +def good_comparison(): + """this is ok""" + for i in range(10): + if i == 5: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_comparison_constant.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_comparison_constant.txt new file mode 100644 index 0000000..a7f0d95 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_comparison_constant.txt @@ -0,0 +1,6 @@ +misplaced-comparison-constant:19:bad_comparisons:Comparison should be i >= 5 +misplaced-comparison-constant:21:bad_comparisons:Comparison should be i == 1 +misplaced-comparison-constant:23:bad_comparisons:Comparison should be dummy_return() > 3 +misplaced-comparison-constant:25:bad_comparisons:Comparison should be instance.dummy_return() != 4 +misplaced-comparison-constant:27:bad_comparisons:Comparison should be instance.attr == 1 +misplaced-comparison-constant:29:bad_comparisons:Comparison should be instance.attr == 'aaa' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_format_function.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_format_function.py new file mode 100644 index 0000000..3520dc7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_format_function.py @@ -0,0 +1,58 @@ +"""Test that format function is used only with string.""" + +# pylint: disable=invalid-name, pointless-string-statement, line-too-long, no-member, blacklisted-name, undefined-variable, missing-docstring, too-few-public-methods + +print('value: {}').format(123) # [misplaced-format-function] +print("value: {}").format(123) # [misplaced-format-function] +print('value: {}'.format(123)) +print('{} Come Forth!'.format('Lazarus')) +print('Der Hem ist mein Licht und mein Heil, vor wem sollte ich mich furchten? => {}'.format('Psalm 27, 1')) +print('123') +print() +s = 'value: {}'.format(123) +a = 'value: {}' +a.format(123) + +def foo(arg): + """The World is Yours""" + return arg.format(123) # we don't know if arg is str or not, don't raise error. + +def goo(arg): + """The World is Yours""" + TextWriter.format(arg) + +def bar(arg, TextWriter): + """The World is Yours""" + TextWriter().format(arg) + +def foobar(arg, TextWriter): + """The World is Yours""" + TextWriter.format(arg) + +def barfoo(arg): + """The World is Yours""" + TextWriter().format(arg) + +def _display(self, layout): + """launch layouts display""" + print(file=self.out) + TextWriter().format(layout, self.out) + + +class FakeClass: + def __init__(self, string): + self.string = string + + def get_string(self): + return self.string + + def format_string(self): + self.string.format() + self.get_string().format() + print(self.get_string()).format() # [misplaced-format-function] + print(self.get_string().format()) + +obj = FakeClass('Voila!!!') +obj.get_string().format() +print(obj.get_string().format()) +print(obj.get_string()).format() # [misplaced-format-function] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_format_function.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_format_function.txt new file mode 100644 index 0000000..91a1874 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_format_function.txt @@ -0,0 +1,4 @@ +misplaced-format-function:5::format function is not called on str +misplaced-format-function:6::format function is not called on str +misplaced-format-function:52:FakeClass.format_string:format function is not called on str +misplaced-format-function:58::format function is not called on str diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_future.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_future.py new file mode 100644 index 0000000..3440485 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_future.py @@ -0,0 +1,6 @@ +"""Test that __future__ is not the first statement after the docstring.""" +import collections +from __future__ import print_function # [misplaced-future] +from __future__ import with_statement + +DATA = collections diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_future.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_future.txt new file mode 100644 index 0000000..bc874cf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/misplaced_future.txt @@ -0,0 +1 @@ +misplaced-future:3::"__future__ import is not the first non docstring statement" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_docstring.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_docstring.py new file mode 100644 index 0000000..172c357 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_docstring.py @@ -0,0 +1,54 @@ +# [missing-docstring] +# pylint: disable=too-few-public-methods, useless-object-inheritance + +def public_documented(): + """It has a docstring.""" + + +def _private_undocumented(): + # Doesn't need a docstring + pass + + +def _private_documented(): + """It has a docstring.""" + + +class ClassDocumented(object): + """It has a docstring.""" + + +class ClassUndocumented(object): # [missing-docstring] + pass + + +def public_undocumented(): # [missing-docstring] + pass + + +def __sizeof__(): + # Special + pass + + +def __mangled(): + pass + + +class Property(object): + """Don't warn about setters and deleters.""" + + def __init__(self): + self._value = None + + @property + def test(self): + """Default docstring for setters and deleters.""" + + @test.setter + def test(self, value): + self._value = value + + @test.deleter + def test(self): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_docstring.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_docstring.txt new file mode 100644 index 0000000..2680319 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_docstring.txt @@ -0,0 +1,3 @@ +missing-docstring:1::Missing module docstring +missing-docstring:21:ClassUndocumented:Missing class docstring +missing-docstring:25:public_undocumented:Missing function docstring diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_final_newline.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_final_newline.py new file mode 100644 index 0000000..370f902 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_final_newline.py @@ -0,0 +1,4 @@ +"""This file does not have a final newline.""" +from __future__ import print_function +# +1:[missing-final-newline] +print(1) \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_final_newline.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_final_newline.txt new file mode 100644 index 0000000..b53c980 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_final_newline.txt @@ -0,0 +1 @@ +missing-final-newline:4::Final newline missing diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.py new file mode 100644 index 0000000..3b6e1c0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.py @@ -0,0 +1,36 @@ +# pylint: disable=missing-docstring,unused-argument + +def target(pos, *, keyword): + return pos + keyword + + +def forwarding_kwds(pos, **kwds): + target(pos, **kwds) + + +def forwarding_args(*args, keyword): + target(*args, keyword=keyword) + +def forwarding_conversion(*args, **kwargs): + target(*args, **dict(kwargs)) + + +def not_forwarding_kwargs(*args, **kwargs): + target(*args) # [missing-kwoa] + + +target(1, keyword=2) + +PARAM = 1 +target(2, PARAM) # [too-many-function-args, missing-kwoa] + + +def some_function(*, param): + return param + 2 + + +def other_function(**kwargs): + return some_function(**kwargs) # Does not trigger missing-kwoa + + +other_function(param=2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.txt new file mode 100644 index 0000000..734208a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_kwoa_py3.txt @@ -0,0 +1,3 @@ +missing-kwoa:19:not_forwarding_kwargs:Missing mandatory keyword argument 'keyword' in function call +missing-kwoa:25::Missing mandatory keyword argument 'keyword' in function call +too-many-function-args:25::Too many positional arguments for function call \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_self_argument.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_self_argument.py new file mode 100644 index 0000000..79ae348 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_self_argument.py @@ -0,0 +1,21 @@ +"""Checks that missing self in method defs don't crash Pylint.""" +# pylint: disable=useless-object-inheritance + + + +class MyClass(object): + """A class with some methods missing self args.""" + + def __init__(self): + self.var = "var" + + def method(): # [no-method-argument] + """A method without a self argument.""" + + def setup(): # [no-method-argument] + """A method without a self argument, but usage.""" + self.var = 1 # [undefined-variable] + + def correct(self): + """Correct.""" + self.var = "correct" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_self_argument.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_self_argument.txt new file mode 100644 index 0000000..9a47c89 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/missing_self_argument.txt @@ -0,0 +1,6 @@ +no-method-argument:12:MyClass.method:Method has no argument +no-method-argument:14:MyClass.met:"""Method has no argument +"" +" +no-method-argument:15:MyClass.setup:Method has no argument +undefined-variable:17:MyClass.setup:Undefined variable 'self' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mixed_indentation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mixed_indentation.py new file mode 100644 index 0000000..724ecff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mixed_indentation.py @@ -0,0 +1,10 @@ +"""test mixed tabs and spaces""" +from __future__ import print_function + +def spaces_func(): + """yo""" + print("yo") + +def tab_func(): + """yo""" # [mixed-indentation] + print("yo") # [mixed-indentation] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mixed_indentation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mixed_indentation.txt new file mode 100644 index 0000000..d4857e6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/mixed_indentation.txt @@ -0,0 +1,2 @@ +mixed-indentation:9::Found indentation with tabs instead of spaces +mixed-indentation:10::Found indentation with tabs instead of spaces diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/monkeypatch_method.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/monkeypatch_method.py new file mode 100644 index 0000000..e8bd03a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/monkeypatch_method.py @@ -0,0 +1,16 @@ +# pylint: disable=missing-docstring,too-few-public-methods, useless-object-inheritance +'''Test that a function is considered a method when looked up through a class.''' + +class Clazz(object): + 'test class' + + def __init__(self, value): + self.value = value + +def func(arg1, arg2): + 'function that will be used as a method' + return arg1.value + arg2 + +Clazz.method = func + +VAR = Clazz(1).method(2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/monkeypatch_method.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/monkeypatch_method.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/multiple_imports.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/multiple_imports.py new file mode 100644 index 0000000..9008dcc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/multiple_imports.py @@ -0,0 +1,2 @@ +# pylint: disable=missing-docstring, unused-import +import os, socket # [multiple-imports] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/multiple_imports.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/multiple_imports.txt new file mode 100644 index 0000000..a5df51e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/multiple_imports.txt @@ -0,0 +1 @@ +multiple-imports:2::Multiple imports on one line (os, socket) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.py new file mode 100644 index 0000000..e048ec4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,too-few-public-methods +__version__ = "1.0" +SOME_CONSTANT = 42 # [invalid-name] + + +def sayHello(someArgument): + return [someArgument * someValue for someValue in range(10)] + + +class MyClass: # [invalid-name] + def __init__(self, argX): + self._mySecretX = argX + + @property + def myPublicX(self): + return self._mySecretX * 2 + + def __eq__(self, other): + return isinstance(other, MyClass) and self.myPublicX == other.myPublicX + + +def say_hello(): # [invalid-name] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.rc new file mode 100644 index 0000000..29f4450 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.rc @@ -0,0 +1,13 @@ +[BASIC] +function-naming-style=camelCase +const-naming-style=camelCase +attr-naming-style=camelCase +argument-naming-style=camelCase +module-naming-style=camelCase +method-naming-style=camelCase +variable-naming-style=camelCase +class-attribute-naming-style=camelCase +inlinevar-naming-style=camelCase +class-naming-style=camelCase + +include-naming-hint=yes diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.txt new file mode 100644 index 0000000..3c31bbc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namePresetCamelCase.txt @@ -0,0 +1,3 @@ +invalid-name:3::"Constant name ""SOME_CONSTANT"" doesn't conform to camelCase naming style ('(([a-z_][A-Za-z0-9]*)|(__.*__))$' pattern)" +invalid-name:10:MyClass:"Class name ""MyClass"" doesn't conform to camelCase naming style ('[a-z_][a-zA-Z0-9]+$' pattern)" +invalid-name:22:say_hello:"Function name ""say_hello"" doesn't conform to camelCase naming style ('(([a-z_][a-zA-Z0-9]{2,})|(__[a-z][a-zA-Z0-9_]+__))$' pattern)" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.py new file mode 100644 index 0000000..5498887 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,too-few-public-methods +__version__ = "1.0" +SOME_CONSTANT = 42 # [invalid-name] + + +def say_hello(some_argument): + return [some_argument * some_value for some_value in range(10)] + + +class MyClass: # [invalid-name] + def __init__(self, arg_x): + self._my_secret_x = arg_x + + @property + def my_public_x(self): + return self._my_secret_x * 2 + + def __eq__(self, other): + return isinstance(other, MyClass) and self.my_public_x == other.my_public_x + + +def sayHello(): # [invalid-name] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.rc new file mode 100644 index 0000000..0424cdc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.rc @@ -0,0 +1,13 @@ +[BASIC] +function-naming-style=snake_case +const-naming-style=snake_case +attr-naming-style=snake_case +argument-naming-style=snake_case +module-naming-style=snake_case +method-naming-style=snake_case +variable-naming-style=snake_case +class-attribute-naming-style=snake_case +inlinevar-naming-style=snake_case +class-naming-style=snake_case + +include-naming-hint=yes diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.txt new file mode 100644 index 0000000..14a3d65 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_preset_snake_case.txt @@ -0,0 +1,3 @@ +invalid-name:3::"Constant name ""SOME_CONSTANT"" doesn't conform to snake_case naming style ('(([a-z_][a-z0-9_]*)|(__.*__))$' pattern)" +invalid-name:10:MyClass:"Class name ""MyClass"" doesn't conform to snake_case naming style ('[a-z_][a-z0-9_]+$' pattern)" +invalid-name:22:sayHello:"Function name ""sayHello"" doesn't conform to snake_case naming style ('(([a-z_][a-z0-9_]{2,})|(_[a-z0-9_]*)|(__[a-z][a-z0-9_]+__))$' pattern)" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.py new file mode 100644 index 0000000..87b87d9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.py @@ -0,0 +1,140 @@ +"""Test for the invalid-name warning.""" +# pylint: disable=no-absolute-import, useless-object-inheritance, unnecessary-pass +from __future__ import print_function +import abc +import collections + +GOOD_CONST_NAME = '' +bad_const_name = 0 # [invalid-name] + + +def BADFUNCTION_name(): # [invalid-name] + """Bad function name.""" + BAD_LOCAL_VAR = 1 # [invalid-name] + print(BAD_LOCAL_VAR) + + +def func_bad_argname(NOT_GOOD): # [invalid-name] + """Function with a badly named argument.""" + return NOT_GOOD + + +def no_nested_args(arg1, arg21, arg22): + """Well-formed function.""" + print(arg1, arg21, arg22) + + +class bad_class_name(object): # [invalid-name] + """Class with a bad name.""" + + +class CorrectClassName(object): + """Class with a good name.""" + + def __init__(self): + self._good_private_name = 10 + self.__good_real_private_name = 11 + self.good_attribute_name = 12 + self._Bad_AtTR_name = None # [invalid-name] + self.Bad_PUBLIC_name = None # [invalid-name] + + zz = 'Why Was It Bad Class Attribute?' + GOOD_CLASS_ATTR = 'Good Class Attribute' + + def BadMethodName(self): # [invalid-name] + """A Method with a bad name.""" + + def good_method_name(self): + """A method with a good name.""" + + def __DunDER_IS_not_free_for_all__(self): # [invalid-name] + """Another badly named method.""" + + +class DerivedFromCorrect(CorrectClassName): + """A derived class with an invalid inherited members. + + Derived attributes and methods with invalid names do not trigger warnings. + """ + zz = 'Now a good class attribute' + + def __init__(self): + super(DerivedFromCorrect, self).__init__() + self._Bad_AtTR_name = None # Ignored + + def BadMethodName(self): + """Ignored since the method is in the interface.""" + + +V = [WHAT_Ever_inListComp for WHAT_Ever_inListComp in GOOD_CONST_NAME] + +def class_builder(): + """Function returning a class object.""" + + class EmbeddedClass(object): + """Useless class.""" + + return EmbeddedClass + +# +1:[invalid-name] +BAD_NAME_FOR_CLASS = collections.namedtuple('Named', ['tuple']) +NEXT_BAD_NAME_FOR_CLASS = class_builder() # [invalid-name] + +GoodName = collections.namedtuple('Named', ['tuple']) +ToplevelClass = class_builder() + +# Aliases for classes have the same name constraints. +AlsoCorrect = CorrectClassName +NOT_CORRECT = CorrectClassName # [invalid-name] + + +def test_globals(): + """Names in global statements are also checked.""" + global NOT_CORRECT + global AlsoCorrect # [invalid-name] + NOT_CORRECT = 1 + AlsoCorrect = 2 + + +class FooClass(object): + """A test case for property names. + + Since by default, the regex for attributes is the same as the one + for method names, we check the warning messages to contain the + string 'attribute'. + """ + @property + def PROPERTY_NAME(self): # [invalid-name] + """Ignored.""" + pass + + @abc.abstractproperty + def ABSTRACT_PROPERTY_NAME(self): # [invalid-name] + """Ignored.""" + pass + + @PROPERTY_NAME.setter + def PROPERTY_NAME_SETTER(self): # [invalid-name] + """Ignored.""" + pass + + def _nice_and_long_descriptive_private_method_name(self): + """private method with long name""" + pass + + +def good_public_function_name(good_arg_name): + """This is a perfect public function""" + good_variable_name = 1 + return good_variable_name + good_arg_name + + +def _private_scope_function_with_long_descriptive_name(): + """Private scope function are cool with long descriptive names""" + return 12 + +LONG_CONSTANT_NAME_IN_PUBLIC_SCOPE_ARE_OKAY = True + +class _AnExceptionalExceptionThatOccursVeryVeryRarely(Exception): + """A very exceptional exception with a nice descriptive name""" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.rc new file mode 100644 index 0000000..1a63e67 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.rc @@ -0,0 +1,5 @@ +[testoptions] +min_pyver=2.6 + +[Messages Control] +disable=too-few-public-methods,abstract-class-not-used,global-statement diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.txt new file mode 100644 index 0000000..74d4fb8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/name_styles.txt @@ -0,0 +1,16 @@ +invalid-name:8::"Constant name ""bad_const_name"" doesn't conform to UPPER_CASE naming style" +invalid-name:11:BADFUNCTION_name:"Function name ""BADFUNCTION_name"" doesn't conform to snake_case naming style" +invalid-name:13:BADFUNCTION_name:"Variable name ""BAD_LOCAL_VAR"" doesn't conform to snake_case naming style" +invalid-name:17:func_bad_argname:"Argument name ""NOT_GOOD"" doesn't conform to snake_case naming style" +invalid-name:27:bad_class_name:"Class name ""bad_class_name"" doesn't conform to PascalCase naming style" +invalid-name:38:CorrectClassName.__init__:"Attribute name ""_Bad_AtTR_name"" doesn't conform to snake_case naming style" +invalid-name:39:CorrectClassName.__init__:"Attribute name ""Bad_PUBLIC_name"" doesn't conform to snake_case naming style" +invalid-name:44:CorrectClassName.BadMethodName:"Method name ""BadMethodName"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:50:CorrectClassName.__DunDER_IS_not_free_for_all__:"Method name ""__DunDER_IS_not_free_for_all__"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:80::"Class name ""BAD_NAME_FOR_CLASS"" doesn't conform to PascalCase naming style" +invalid-name:81::"Class name ""NEXT_BAD_NAME_FOR_CLASS"" doesn't conform to PascalCase naming style" +invalid-name:88::"Class name ""NOT_CORRECT"" doesn't conform to PascalCase naming style" +invalid-name:94:test_globals:"Constant name ""AlsoCorrect"" doesn't conform to UPPER_CASE naming style" +invalid-name:107:FooClass.PROPERTY_NAME:"Attribute name ""PROPERTY_NAME"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:112:FooClass.ABSTRACT_PROPERTY_NAME:"Attribute name ""ABSTRACT_PROPERTY_NAME"" doesn't conform to snake_case naming style":INFERENCE +invalid-name:117:FooClass.PROPERTY_NAME_SETTER:"Attribute name ""PROPERTY_NAME_SETTER"" doesn't conform to snake_case naming style":INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namedtuple_member_inference.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namedtuple_member_inference.py new file mode 100644 index 0000000..4488ceb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namedtuple_member_inference.py @@ -0,0 +1,22 @@ +"""Test namedtuple attributes. + +Regression test for: +https://bitbucket.org/logilab/pylint/issue/93/pylint-crashes-on-namedtuple-attribute +""" +from __future__ import absolute_import, print_function +from collections import namedtuple + +__revision__ = None + +Thing = namedtuple('Thing', ()) + +Fantastic = namedtuple('Fantastic', ['foo']) + +def test(): + """Test member access in named tuples.""" + print(Thing.x) # [no-member] + fan = Fantastic(1) + print(fan.foo) + # Should not raise protected-access. + fan2 = fan._replace(foo=2) + print(fan2.foo) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namedtuple_member_inference.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namedtuple_member_inference.txt new file mode 100644 index 0000000..1532814 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/namedtuple_member_inference.txt @@ -0,0 +1,2 @@ +no-member:17:test:Class 'Thing' has no 'x' member:INFERENCE +no-member:23:test:Instance of 'Fantastic' has no 'foo' member:INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/names_in__all__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/names_in__all__.py new file mode 100644 index 0000000..9b2840a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/names_in__all__.py @@ -0,0 +1,49 @@ +# pylint: disable=too-few-public-methods,no-self-use, no-absolute-import,import-error, useless-object-inheritance, unnecessary-pass +"""Test Pylint's use of __all__. + +* NonExistant is not defined in this module, and it is listed in + __all__. An error is expected. + +* This module imports path and republished it in __all__. No errors + are expected. +""" +from __future__ import print_function +from os import path +from collections import deque +from missing import Missing + +__all__ = [ + 'Dummy', + '', # [undefined-all-variable] + Missing, + SomeUndefined, # [undefined-variable] + 'NonExistant', # [undefined-all-variable] + 'path', + 'func', # [undefined-all-variable] + 'inner', # [undefined-all-variable] + 'InnerKlass', deque.__name__] # [undefined-all-variable] + + +class Dummy(object): + """A class defined in this module.""" + pass + +DUMMY = Dummy() + +def function(): + """Function docstring + """ + pass + +function() + +class Klass(object): + """A klass which contains a function""" + def func(self): + """A klass method""" + inner = None + print(inner) + + class InnerKlass(object): + """An inner klass""" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/names_in__all__.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/names_in__all__.txt new file mode 100644 index 0000000..9487329 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/names_in__all__.txt @@ -0,0 +1,6 @@ +undefined-all-variable:17::Undefined variable name '' in __all__ +undefined-variable:19::Undefined variable 'SomeUndefined' +undefined-all-variable:20::Undefined variable name 'NonExistant' in __all__ +undefined-all-variable:22::Undefined variable name 'func' in __all__ +undefined-all-variable:23::Undefined variable name 'inner' in __all__ +undefined-all-variable:24::Undefined variable name 'InnerKlass' in __all__ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nested_blocks_issue1088.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nested_blocks_issue1088.py new file mode 100644 index 0000000..d44a9f7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nested_blocks_issue1088.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,too-few-public-methods +def had_bug(num): + if num > 1: # [too-many-nested-blocks] + if num > 2: + if num > 3: + if num > 4: + if num > 5: + if num > 6: + return True + return None + + +def was_correct(num): + if num > 1: # [too-many-nested-blocks] + if num > 2: + if num > 3: + if num > 4: + if num > 5: + if num > 6: + return True + if num == 0: + return False + return None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nested_blocks_issue1088.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nested_blocks_issue1088.txt new file mode 100644 index 0000000..cf226de --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nested_blocks_issue1088.txt @@ -0,0 +1,2 @@ +too-many-nested-blocks:3:had_bug:Too many nested blocks (6/5):HIGH +too-many-nested-blocks:14:was_correct:Too many nested blocks (6/5):HIGH diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_classmethod_decorator.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_classmethod_decorator.py new file mode 100644 index 0000000..66cc0b3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_classmethod_decorator.py @@ -0,0 +1,35 @@ +"""Checks class methods are declared with a decorator if within the class +scope and if classmethod's argument is a member of the class +""" + +# pylint: disable=too-few-public-methods, using-constant-test, no-self-argument, useless-object-inheritance + +class MyClass(object): + """Some class""" + def __init__(self): + pass + + def cmethod(cls): + """class method-to-be""" + cmethod = classmethod(cmethod) # [no-classmethod-decorator] + + if True: + cmethod = classmethod(cmethod) # [no-classmethod-decorator] + + @classmethod + def my_second_method(cls): + """correct class method definition""" + + def other_method(cls): + """some method""" + cmethod2 = classmethod(other_method) # [no-classmethod-decorator] + +def helloworld(): + """says hello""" + + +MyClass.new_class_method = classmethod(helloworld) + +class MyOtherClass(object): + """Some other class""" + _make = classmethod(tuple.__new__) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_classmethod_decorator.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_classmethod_decorator.txt new file mode 100644 index 0000000..ba51f0b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_classmethod_decorator.txt @@ -0,0 +1,3 @@ +no-classmethod-decorator:14:MyClass:Consider using a decorator instead of calling classmethod +no-classmethod-decorator:17:MyClass:Consider using a decorator instead of calling classmethod +no-classmethod-decorator:25:MyClass:Consider using a decorator instead of calling classmethod diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_else_return.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_else_return.py new file mode 100644 index 0000000..24b82f2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_else_return.py @@ -0,0 +1,72 @@ +""" Test that superfluous else return are detected. """ + +# pylint:disable=invalid-name,missing-docstring,unused-variable + +def foo1(x, y, z): + if x: # [no-else-return] + a = 1 + return y + else: + b = 2 + return z + + +def foo2(x, y, w, z): + if x: # [no-else-return] + a = 1 + return y + elif z: + b = 2 + return w + else: + c = 3 + return z + + +def foo3(x, y, z): + if x: # [no-else-return] + a = 1 + if y: # [no-else-return] + b = 2 + return y + else: + c = 3 + return x + else: + d = 4 + return z + + +def bar1(x, y, z): + if x: + return y + return z + + +def bar2(w, x, y, z): + if x: + return y + if z: + a = 1 + else: + return w + return None + + +def bar3(x, y, z): + if x: + if z: + return y + else: + return z + return None + + +def bar4(condition): + if condition: # [no-else-return] + return True + else: + try: + return False + except ValueError: + return None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_else_return.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_else_return.txt new file mode 100644 index 0000000..8e2c923 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_else_return.txt @@ -0,0 +1,5 @@ +no-else-return:6:foo1:Unnecessary "else" after "return" +no-else-return:15:foo2:Unnecessary "elif" after "return" +no-else-return:27:foo3:Unnecessary "else" after "return" +no-else-return:29:foo3:Unnecessary "else" after "return" +no-else-return:66:bar4:Unnecessary "else" after "return" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_name_in_module.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_name_in_module.py new file mode 100644 index 0000000..8b309fd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_name_in_module.py @@ -0,0 +1,66 @@ +#pylint: disable=W0401,W0611,no-absolute-import,invalid-name,import-error,bare-except,broad-except,wrong-import-order,ungrouped-imports,wrong-import-position +"""check unexistant names imported are reported""" +from __future__ import print_function + +import collections.tutu # [no-name-in-module] +from collections import toto # [no-name-in-module] +toto.yo() + +from xml.etree import ElementTree +ElementTree.nonexistant_function() # [no-member] +ElementTree.another.nonexistant.function() # [no-member] + + +import sys +print(sys.stdout, 'hello world') +print(sys.stdoout, 'bye bye world') # [no-member] + + +import re +re.finditer('*', 'yo') + +from rie import * +from re import findiiter, compiile # [no-name-in-module,no-name-in-module] + +import os +'SOMEVAR' in os.environ # [pointless-statement] + +try: + from collections import something +except ImportError: + something = None + +try: + from collections import anything # [no-name-in-module] +except ValueError: + anything = None + +try: + import collections.missing +except ImportError: + pass + +try: + import collections.indeed_missing # [no-name-in-module] +except ValueError: + pass + +try: + import collections.emit # [no-name-in-module] +except Exception: + pass + +try: + import collections.emit1 +except: + pass + +try: + if something: + import collections.emit2 # [no-name-in-module] +except Exception: + pass + +from .no_self_use import Super +from .no_self_use import lala # [no-name-in-module] +from .no_self_use.bla import lala1 # [no-name-in-module] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_name_in_module.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_name_in_module.txt new file mode 100644 index 0000000..7dbc11c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_name_in_module.txt @@ -0,0 +1,14 @@ +no-name-in-module:5::No name 'tutu' in module 'collections' +no-name-in-module:6::No name 'toto' in module 'collections' +no-member:10::Module 'xml.etree.ElementTree' has no 'nonexistant_function' member:INFERENCE +no-member:11::Module 'xml.etree.ElementTree' has no 'another' member:INFERENCE +no-member:16::Module 'sys' has no 'stdoout' member; maybe 'stdout'?:INFERENCE +no-name-in-module:23::No name 'compiile' in module 're' +no-name-in-module:23::No name 'findiiter' in module 're' +pointless-statement:26::Statement seems to have no effect +no-name-in-module:34::No name 'anything' in module 'collections' +no-name-in-module:44::No name 'indeed_missing' in module 'collections' +no-name-in-module:49::No name 'emit' in module 'collections' +no-name-in-module:60::No name 'emit2' in module 'collections' +no-name-in-module:65::No name 'lala' in module 'functional.no_self_use' +no-name-in-module:66::No name 'bla' in module 'functional.no_self_use' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use.py new file mode 100644 index 0000000..3d3cda1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use.py @@ -0,0 +1,78 @@ +# pylint: disable=R0903,W0232,missing-docstring, useless-object-inheritance +"""test detection of method which could be a function""" + +from __future__ import print_function + +class Toto(object): + """bla bal abl""" + + def __init__(self): + self.aaa = 2 + + def regular_method(self): + """this method is a real method since it access to self""" + self.function_method() + + def function_method(self): # [no-self-use] + """this method isn' a real method since it doesn't need self""" + print('hello') + + +class Base(object): + """an abstract class""" + + def __init__(self): + self.aaa = 2 + + def check(self, arg): + """an abstract method, could not be a function""" + raise NotImplementedError + + +class Sub(Base): + """a concrete class""" + + def check(self, arg): + """a concrete method, could not be a function since it need + polymorphism benefits + """ + return arg == 0 + +class Super(object): + """same as before without abstract""" + attr = 1 + def method(self): + """regular""" + print(self.attr) + +class Sub1(Super): + """override method with need for self""" + def method(self): + """no i can not be a function""" + print(42) + + def __len__(self): + """no i can not be a function""" + print(42) + + def __cmp__(self, other): + """no i can not be a function""" + print(42) + + def __copy__(self): + return 24 + + def __getstate__(self): + return 42 + + +class Prop(object): + + @property + def count(self): + """Don't emit no-self-use for properties. + + They can't be functions and they can be part of an + API specification. + """ + return 42 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use.txt new file mode 100644 index 0000000..e68dcff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use.txt @@ -0,0 +1 @@ +no-self-use:16:Toto.function_method:Method could be a function \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.py new file mode 100644 index 0000000..f401508 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring,no-init,unused-argument,invalid-name,too-few-public-methods + +class A: + def __init__(self): + self.store = {} + + def get(self, key, default=None): + return self.store.get(key, default) + +class B(A): + def get_memo(self, obj): + return super().get(obj) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_self_use_py3.txt @@ -0,0 +1 @@ + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_staticmethod_decorator.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_staticmethod_decorator.py new file mode 100644 index 0000000..d0e0eff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_staticmethod_decorator.py @@ -0,0 +1,35 @@ +"""Checks static methods are declared with a decorator if within the class +scope and if static method's argument is a member of the class +""" + +# pylint: disable=too-few-public-methods, using-constant-test, no-method-argument, useless-object-inheritance + +class MyClass(object): + """Some class""" + def __init__(self): + pass + + def smethod(): + """static method-to-be""" + smethod = staticmethod(smethod) # [no-staticmethod-decorator] + + if True: + smethod = staticmethod(smethod) # [no-staticmethod-decorator] + + @staticmethod + def my_second_method(): + """correct static method definition""" + + def other_method(): + """some method""" + smethod2 = staticmethod(other_method) # [no-staticmethod-decorator] + +def helloworld(): + """says hello""" + + +MyClass.new_static_method = staticmethod(helloworld) + +class MyOtherClass(object): + """Some other class""" + _make = staticmethod(tuple.__new__) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_staticmethod_decorator.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_staticmethod_decorator.txt new file mode 100644 index 0000000..c0aea0e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/no_staticmethod_decorator.txt @@ -0,0 +1,3 @@ +no-staticmethod-decorator:14:MyClass:Consider using a decorator instead of calling staticmethod +no-staticmethod-decorator:17:MyClass:Consider using a decorator instead of calling staticmethod +no-staticmethod-decorator:25:MyClass:Consider using a decorator instead of calling staticmethod diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/non_iterator_returned.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/non_iterator_returned.py new file mode 100644 index 0000000..32486f7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/non_iterator_returned.py @@ -0,0 +1,95 @@ +"""Check non-iterators returned by __iter__ """ + +# pylint: disable=too-few-public-methods, missing-docstring, no-self-use, useless-object-inheritance + +import six + +class FirstGoodIterator(object): + """ yields in iterator. """ + + def __iter__(self): + for index in range(10): + yield index + +class SecondGoodIterator(object): + """ __iter__ and next """ + + def __iter__(self): + return self + + def __next__(self): + """ Infinite iterator, but still an iterator """ + return 1 + + def next(self): + """Same as __next__, but for Python 2.""" + return 1 + +class ThirdGoodIterator(object): + """ Returns other iterator, not the current instance """ + + def __iter__(self): + return SecondGoodIterator() + +class FourthGoodIterator(object): + """ __iter__ returns iter(...) """ + + def __iter__(self): + return iter(range(10)) + + +class IteratorMetaclass(type): + def __next__(cls): + return 1 + + def next(cls): + return 2 + + +@six.add_metaclass(IteratorMetaclass) +class IteratorClass(object): + """Iterable through the metaclass.""" + + +class FifthGoodIterator(object): + """__iter__ returns a class which uses an iterator-metaclass.""" + def __iter__(self): + return IteratorClass + +class FileBasedIterator(object): + def __init__(self, path): + self.path = path + self.file = None + + def __iter__(self): + if self.file is not None: + self.file.close() + self.file = open(self.path) + # self file has two infered values: None and <instance of 'file'> + # we don't want to emit error in this case + return self.file + + +class FirstBadIterator(object): + """ __iter__ returns a list """ + + def __iter__(self): # [non-iterator-returned] + return [] + +class SecondBadIterator(object): + """ __iter__ without next """ + + def __iter__(self): # [non-iterator-returned] + return self + +class ThirdBadIterator(object): + """ __iter__ returns an instance of another non-iterator """ + + def __iter__(self): # [non-iterator-returned] + return SecondBadIterator() + +class FourthBadIterator(object): + """__iter__ returns a class.""" + + def __iter__(self): # [non-iterator-returned] + return ThirdBadIterator diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/non_iterator_returned.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/non_iterator_returned.txt new file mode 100644 index 0000000..fa1d5be --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/non_iterator_returned.txt @@ -0,0 +1,4 @@ +non-iterator-returned:76:FirstBadIterator.__iter__:__iter__ returns non-iterator +non-iterator-returned:82:SecondBadIterator.__iter__:__iter__ returns non-iterator +non-iterator-returned:88:ThirdBadIterator.__iter__:__iter__ returns non-iterator +non-iterator-returned:94:FourthBadIterator.__iter__:__iter__ returns non-iterator diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.py new file mode 100644 index 0000000..5573cee --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.py @@ -0,0 +1,34 @@ +# pylint: disable=missing-docstring, too-few-public-methods,pointless-statement +# pylint: disable=expression-not-assigned + +class MetaIterable(type): + __iter__ = None + + +class MetaOldIterable(type): + __getitem__ = None + + +class MetaContainer(type): + __contains__ = None + + +class NonIterableClass(metaclass=MetaOldIterable): + __contains__ = None + + +class OldNonIterableClass(metaclass=MetaOldIterable): + __contains__ = None + + +class NonContainerClass(metaclass=MetaContainer): + __iter__ = None + + +def test(): + 1 in NonIterableClass # [unsupported-membership-test] + 1 in OldNonIterableClass # [unsupported-membership-test] + 1 in NonContainerClass # [unsupported-membership-test] + 1 in NonIterableClass() # [unsupported-membership-test] + 1 in OldNonIterableClass() # [unsupported-membership-test] + 1 in NonContainerClass() # [unsupported-membership-test] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.txt new file mode 100644 index 0000000..0775b4a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/none_dunder_protocols_py36.txt @@ -0,0 +1,6 @@ +unsupported-membership-test:29:test:Value 'NonIterableClass' doesn't support membership test +unsupported-membership-test:30:test:Value 'OldNonIterableClass' doesn't support membership test +unsupported-membership-test:31:test:Value 'NonContainerClass' doesn't support membership test +unsupported-membership-test:32:test:Value 'NonIterableClass()' doesn't support membership test +unsupported-membership-test:33:test:Value 'OldNonIterableClass()' doesn't support membership test +unsupported-membership-test:34:test:Value 'NonContainerClass()' doesn't support membership test diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonexistent_operator.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonexistent_operator.py new file mode 100644 index 0000000..f05a649 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonexistent_operator.py @@ -0,0 +1,15 @@ +"""check operator use""" +# pylint: disable=invalid-name, pointless-statement +a = 1 +a += 5 +a = +a +b = ++a # [nonexistent-operator] +++a # [nonexistent-operator] +c = (++a) * b # [nonexistent-operator] + +a = 1 +a -= 5 +b = --a # [nonexistent-operator] +b = a +--a # [nonexistent-operator] +c = (--a) * b # [nonexistent-operator] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonexistent_operator.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonexistent_operator.txt new file mode 100644 index 0000000..da59f41 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonexistent_operator.txt @@ -0,0 +1,6 @@ +nonexistent-operator:6::"Use of the non-existent ++ operator" +nonexistent-operator:7::"Use of the non-existent ++ operator" +nonexistent-operator:8::"Use of the non-existent ++ operator" +nonexistent-operator:12::"Use of the non-existent -- operator" +nonexistent-operator:14::"Use of the non-existent -- operator" +nonexistent-operator:15::"Use of the non-existent -- operator" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.py new file mode 100644 index 0000000..9c9cf86 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.py @@ -0,0 +1,12 @@ +"""Test that a name is both nonlocal and global in the same scope.""" +# pylint: disable=missing-docstring,global-variable-not-assigned,invalid-name,nonlocal-without-binding + +def bad(): # [nonlocal-and-global] + nonlocal missing + global missing + +def good(): + nonlocal missing + def test(): + global missing + return test diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.txt new file mode 100644 index 0000000..46f0d0f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_and_global.txt @@ -0,0 +1 @@ +nonlocal-and-global:4:bad:"Name 'missing' is nonlocal and global" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.py new file mode 100644 index 0000000..be3c003 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.py @@ -0,0 +1,42 @@ +""" Checks that reversed() receive proper argument """ +# pylint: disable=missing-docstring,invalid-name,unused-variable, useless-object-inheritance +# pylint: disable=too-few-public-methods,no-self-use,no-absolute-import + +def test(): + def parent(): + a = 42 + def stuff(): + nonlocal a + + c = 24 + def parent2(): + a = 42 + def stuff(): + def other_stuff(): + nonlocal a + nonlocal c + +b = 42 +def func(): + def other_func(): + nonlocal b # [nonlocal-without-binding] + +class SomeClass(object): + nonlocal x # [nonlocal-without-binding] + + def func(self): + nonlocal some_attr # [nonlocal-without-binding] + + +def func2(): + nonlocal_ = None + local = None + + class Class: + + nonlocal nonlocal_ + + nonlocal_ = 1 + local = 1 + + return local + nonlocal_ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.txt new file mode 100644 index 0000000..4343d68 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/nonlocal_without_binding.txt @@ -0,0 +1,3 @@ +nonlocal-without-binding:22:func.other_func:nonlocal name b found without binding +nonlocal-without-binding:25:SomeClass:nonlocal name x found without binding +nonlocal-without-binding:28:SomeClass.func:nonlocal name some_attr found without binding \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.py new file mode 100644 index 0000000..652de7c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.py @@ -0,0 +1,71 @@ +"""Test that an async context manager receives a proper object.""" +# pylint: disable=missing-docstring, import-error, too-few-public-methods, useless-object-inheritance +import contextlib + +from ala import Portocala + + +@contextlib.contextmanager +def ctx_manager(): + yield + + +class ContextManager(object): + def __enter__(self): + pass + def __exit__(self, *args): + pass + +class PartialAsyncContextManager(object): + def __aenter__(self): + pass + +class SecondPartialAsyncContextManager(object): + def __aexit__(self, *args): + pass + +class UnknownBases(Portocala): + def __aenter__(self): + pass + + +class AsyncManagerMixin(object): + pass + +class GoodAsyncManager(object): + def __aenter__(self): + pass + def __aexit__(self, *args): + pass + +class InheritExit(object): + def __aexit__(self, *args): + pass + +class SecondGoodAsyncManager(InheritExit): + def __aenter__(self): + pass + + +async def bad_coro(): + async with 42: # [not-async-context-manager] + pass + async with ctx_manager(): # [not-async-context-manager] + pass + async with ContextManager(): # [not-async-context-manager] + pass + async with PartialAsyncContextManager(): # [not-async-context-manager] + pass + async with SecondPartialAsyncContextManager(): # [not-async-context-manager] + pass + + +async def good_coro(): + async with UnknownBases(): + pass + async with AsyncManagerMixin(): + pass + async with GoodAsyncManager(): + pass + async with SecondGoodAsyncManager(): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.rc new file mode 100644 index 0000000..03004f2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.txt new file mode 100644 index 0000000..ae9fad7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_async_context_manager.txt @@ -0,0 +1,5 @@ +not-async-context-manager:51:bad_coro:Async context manager 'int' doesn't implement __aenter__ and __aexit__. +not-async-context-manager:53:bad_coro:Async context manager 'generator' doesn't implement __aenter__ and __aexit__. +not-async-context-manager:55:bad_coro:Async context manager 'ContextManager' doesn't implement __aenter__ and __aexit__. +not-async-context-manager:57:bad_coro:Async context manager 'PartialAsyncContextManager' doesn't implement __aenter__ and __aexit__. +not-async-context-manager:59:bad_coro:Async context manager 'SecondPartialAsyncContextManager' doesn't implement __aenter__ and __aexit__. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_callable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_callable.py new file mode 100644 index 0000000..8d5b000 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_callable.py @@ -0,0 +1,125 @@ +# pylint: disable=missing-docstring,no-self-use,too-few-public-methods,wrong-import-position, useless-object-inheritance + +REVISION = None + +REVISION() # [not-callable] + +def correct(): + return 1 + +REVISION = correct() + +class Correct(object): + """callable object""" + +class MetaCorrect(object): + """callable object""" + def __call__(self): + return self + +INSTANCE = Correct() +CALLABLE_INSTANCE = MetaCorrect() +CORRECT = CALLABLE_INSTANCE() +INCORRECT = INSTANCE() # [not-callable] +LIST = [] +INCORRECT = LIST() # [not-callable] +DICT = {} +INCORRECT = DICT() # [not-callable] +TUPLE = () +INCORRECT = TUPLE() # [not-callable] +INT = 1 +INCORRECT = INT() # [not-callable] + +# Test calling properties. Pylint can detect when using only the +# getter, but it doesn't infer properly when having a getter +# and a setter. +class MyProperty(property): + """ test subclasses """ + +class PropertyTest(object): + """ class """ + + def __init__(self): + self.attr = 4 + + @property + def test(self): + """ Get the attribute """ + return self.attr + + @test.setter + def test(self, value): + """ Set the attribute """ + self.attr = value + + @MyProperty + def custom(self): + """ Get the attribute """ + return self.attr + + @custom.setter + def custom(self, value): + """ Set the attribute """ + self.attr = value + +PROP = PropertyTest() +PROP.test(40) # [not-callable] +PROP.custom() # [not-callable] + +# Safe from not-callable when using properties. + +class SafeProperty(object): + @property + def static(self): + return staticmethod + + @property + def klass(self): + return classmethod + + @property + def get_lambda(self): + return lambda: None + + @property + def other_function(self): + def function(arg): + return arg + return function + + @property + def dict_builtin(self): + return dict + + @property + def range_builtin(self): + return range + + @property + def instance(self): + class Empty(object): + def __call__(self): + return 42 + return Empty() + + @property + def does_not_make_sense(self): + raise NotImplementedError + +PROP1 = SafeProperty() +PROP1.static(2) +PROP1.klass(2) +PROP1.get_lambda() +PROP1.other_function(4) +PROP1.dict_builtin() +PROP1.range_builtin(4) +PROP1.instance() +PROP1.does_not_make_sense() + + +import missing # pylint: disable=import-error + +class UnknownBaseCallable(missing.Blah): + pass + +UnknownBaseCallable()() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_callable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_callable.txt new file mode 100644 index 0000000..4928c8c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_callable.txt @@ -0,0 +1,8 @@ +not-callable:5::REVISION is not callable +not-callable:23::INSTANCE is not callable +not-callable:25::LIST is not callable +not-callable:27::DICT is not callable +not-callable:29::TUPLE is not callable +not-callable:31::INT is not callable +not-callable:66::PROP.test is not callable +not-callable:67::PROP.custom is not callable \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_context_manager.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_context_manager.py new file mode 100644 index 0000000..a59f5a2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_context_manager.py @@ -0,0 +1,135 @@ +"""Tests that onjects used in a with statement implement context manager protocol""" + +# pylint: disable=too-few-public-methods, invalid-name, import-error, missing-docstring +# pylint: disable=no-init,wrong-import-position, useless-object-inheritance +# Tests no messages for objects that implement the protocol +class Manager(object): + def __enter__(self): + pass + def __exit__(self, type_, value, traceback): + pass +with Manager(): + pass + +class AnotherManager(Manager): + pass +with AnotherManager(): + pass + + +# Tests message for class that doesn't implement the protocol +class NotAManager(object): + pass +with NotAManager(): #[not-context-manager] + pass + +# Tests contextlib.contextmanager usage is recognized as correct. +from contextlib import contextmanager +@contextmanager +def dec(): + yield +with dec(): # valid use + pass + + +# Tests a message is produced when a contextlib.contextmanager +# decorated function is used without being called. +with dec: # [not-context-manager] + pass + + +# Tests no messages about context manager protocol +# if the type can't be inferred. +from missing import Missing +with Missing(): + pass + +# Tests context managers as names. + +def penelopa(): + return 42 + +hopa = dec() +tropa = penelopa() + +with tropa: # [not-context-manager] + pass + +with hopa: + pass + + +# Tests that no messages are emitted for function calls +# which return managers + +def wrapper(): + return dec() + +with wrapper(): + pass + +# Tests for properties returning managers. + +class Property(object): + + @property + def ctx(self): + return dec() + + @property + def not_ctx(self): + return 42 + + +lala = Property() +with lala.ctx: + # Don't emit when the context manager is the + # result of accessing a property. + pass + +with lala.not_ctx: # [not-context-manager] + pass + + +class TestKnownBases(Missing): + pass + +with TestKnownBases(): + pass + +# Ignore mixins. +class ManagerMixin(object): + def test(self): + with self: + pass + +class FullContextManager(ManagerMixin): + def __enter__(self): + return self + def __exit__(self, *args): + pass + +# Test a false positive with returning a generator +# from a context manager. +def generator(): + yield 42 + +@contextmanager +def context_manager_returning_generator(): + return generator() + +with context_manager_returning_generator(): + pass + +FIRST = [context_manager_returning_generator()] +with FIRST[0]: + pass + +def other_indirect_func(): + return generator() + +def not_context_manager(): + return other_indirect_func() + +with not_context_manager(): # [not-context-manager] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_context_manager.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_context_manager.txt new file mode 100644 index 0000000..7fad3af --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_context_manager.txt @@ -0,0 +1,5 @@ +not-context-manager:23::Context manager 'NotAManager' doesn't implement __enter__ and __exit__. +not-context-manager:37::Context manager 'dec' doesn't implement __enter__ and __exit__. +not-context-manager:55::Context manager 'int' doesn't implement __enter__ and __exit__. +not-context-manager:90::Context manager 'int' doesn't implement __enter__ and __exit__. +not-context-manager:134::Context manager 'generator' doesn't implement __enter__ and __exit__. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_in_loop.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_in_loop.py new file mode 100644 index 0000000..3ea7573 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_in_loop.py @@ -0,0 +1,54 @@ +"""Test that not-in-loop is detected properly.""" +# pylint: disable=missing-docstring, invalid-name, too-few-public-methods +# pylint: disable=useless-else-on-loop, using-constant-test, useless-object-inheritance + +while True: + def ala(): + continue # [not-in-loop] + +while True: + pass +else: + continue # [not-in-loop] + +def lala(): + continue # [not-in-loop] + +while True: + class A(object): + continue # [not-in-loop] + +for _ in range(10): + pass +else: + continue # [not-in-loop] + +for _ in range(42): + pass +else: + break # [not-in-loop] + +if True: + continue # [not-in-loop] +else: + break # [not-in-loop] + +for _ in range(10): + for _ in range(20): + pass + else: + continue + +while True: + while True: + break + else: + break + break +else: + pass + +for _ in range(1): + continue +for _ in range(42): + break diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_in_loop.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_in_loop.txt new file mode 100644 index 0000000..6730bfc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/not_in_loop.txt @@ -0,0 +1,8 @@ +not-in-loop:7:ala:'continue' not properly in loop +not-in-loop:12::'continue' not properly in loop +not-in-loop:15:lala:'continue' not properly in loop +not-in-loop:19:A:'continue' not properly in loop +not-in-loop:24::'continue' not properly in loop +not-in-loop:29::'break' not properly in loop +not-in-loop:32::'continue' not properly in loop +not-in-loop:34::'break' not properly in loop \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/old_division_manually.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/old_division_manually.py new file mode 100644 index 0000000..aab4bd4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/old_division_manually.py @@ -0,0 +1,2 @@ +from __future__ import division +print 1 / 3 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/old_division_manually.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/old_division_manually.rc new file mode 100644 index 0000000..11dbb8d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/old_division_manually.rc @@ -0,0 +1,6 @@ +[testoptions] +max_pyver=3.0 + +[Messages Control] +disable=all +enable=old-division \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.py new file mode 100644 index 0000000..1a6cd59 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-docstring,no-self-use,unused-argument,pointless-statement +# pylint: disable=too-few-public-methods,no-name-in-module +from __future__ import annotations + +class Class: + @classmethod + def from_string(cls, source) -> Class: + ... + + def validate_b(self, obj: OtherClass) -> bool: + ... + + +class OtherClass: + ... diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.rc new file mode 100644 index 0000000..a17bb22 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_activated.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.py new file mode 100644 index 0000000..f892414 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.py @@ -0,0 +1,14 @@ +# pylint: disable=missing-docstring,no-self-use,unused-argument,pointless-statement +# pylint: disable=too-few-public-methods + +class Class: + @classmethod + def from_string(cls, source) -> Class: # [undefined-variable] + ... + + def validate_b(self, obj: OtherClass) -> bool: # [used-before-assignment] + ... + + +class OtherClass: + ... diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.rc new file mode 100644 index 0000000..a17bb22 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.txt new file mode 100644 index 0000000..cae433c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/postponed_evaluation_not_activated.txt @@ -0,0 +1,2 @@ +undefined-variable:6:Class.from_string:Undefined variable 'Class' +used-before-assignment:9:Class.validate_b:Using variable 'OtherClass' before assignment diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.py new file mode 100644 index 0000000..8b7f2fc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.py @@ -0,0 +1,8 @@ +"""Check print statement always warns even if in Python 2 block """ + +from __future__ import absolute_import + +import six + +if six.PY2: + print "Python 3 fails to parse print statements." # [print-statement] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.rc new file mode 100644 index 0000000..4a0e47a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.rc @@ -0,0 +1,5 @@ +[testoptions] +max_pyver=3.0 + +[Messages Control] +enable=python3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.txt new file mode 100644 index 0000000..c35e118 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/print_always_warns.txt @@ -0,0 +1 @@ +print-statement:8::print statement used diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.py new file mode 100644 index 0000000..dc09aa5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.py @@ -0,0 +1,13 @@ +# pylint: disable=missing-docstring, too-few-public-methods +class MyClass: + + async def method(self): + pass + + +def function(): + assert self.attr # [undefined-variable] + + +def func(): + self.attr += 2 # [undefined-variable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.rc new file mode 100644 index 0000000..71de8b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.txt new file mode 100644 index 0000000..ab8b5be --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/protected_access_access_different_scopes.txt @@ -0,0 +1,2 @@ +undefined-variable:9:function:"Undefined variable 'self'" +undefined-variable:13:func:"Undefined variable 'self'" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_format_tuple.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_format_tuple.py new file mode 100644 index 0000000..cfdda10 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_format_tuple.py @@ -0,0 +1,51 @@ +''' +Complain about multi-argument exception constructors where the first argument +contains a percent sign, thus suggesting a % string formatting was intended +instead. The same holds for a string containing {...} suggesting str.format() +was intended. +''' + +def bad_percent(arg): + '''Raising a percent-formatted string and an argument''' + raise KeyError('Bad key: %r', arg) # [raising-format-tuple] + +def good_percent(arg): + '''Instead of passing multiple arguments, format the message''' + raise KeyError('Bad key: %r' % arg) + +def bad_multiarg(name, value): + '''Raising a formatted string and multiple additional arguments''' + raise ValueError('%s measures %.2f', name, value) # [raising-format-tuple] + +def good_multiarg(name, value): + '''The arguments have to be written as a tuple for formatting''' + raise ValueError('%s measures %.2f' % (name, value)) + +def bad_braces(arg): + '''Curly braces as placeholders''' + raise KeyError('Bad key: {:r}', arg) # [raising-format-tuple] + +def good_braces(arg): + '''Call str.format() instead''' + raise KeyError('Bad key: {:r}'.format(arg)) + +def bad_multistring(arg): + '''Multiple adjacent string literals''' + raise AssertionError( # [raising-format-tuple] + 'Long message about %s ' + "split over several adjacent literals", arg) + +def bad_triplequote(arg): + '''String literals with triple quotes''' + raise AssertionError( # [raising-format-tuple] + '''Long message about %s + split over several adjacent literals''', arg) + +def bad_unicode(arg): + '''Unicode string literal''' + raise ValueError(u'Bad %s', arg) # [raising-format-tuple] + +def raise_something_without_name(arg): + '''Regression test for nodes without .node attribute''' + import standard_exceptions # pylint: disable=import-error + raise standard_exceptions.MyException(u'An %s', arg) # [raising-format-tuple] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_format_tuple.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_format_tuple.txt new file mode 100644 index 0000000..1269715 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_format_tuple.txt @@ -0,0 +1,7 @@ +raising-format-tuple:10:bad_percent:Exception arguments suggest string formatting might be intended +raising-format-tuple:18:bad_multiarg:Exception arguments suggest string formatting might be intended +raising-format-tuple:26:bad_braces:Exception arguments suggest string formatting might be intended +raising-format-tuple:34:bad_multistring:Exception arguments suggest string formatting might be intended +raising-format-tuple:40:bad_triplequote:Exception arguments suggest string formatting might be intended +raising-format-tuple:46:bad_unicode:Exception arguments suggest string formatting might be intended +raising-format-tuple:51:raise_something_without_name:Exception arguments suggest string formatting might be intended diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.py new file mode 100644 index 0000000..7961c52 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.py @@ -0,0 +1,13 @@ +"""The following code should emit a raising-non-exception. + +Previously, it didn't, due to a bug in the check for bad-exception-context, +which prevented further checking on the Raise node. +""" +# pylint: disable=import-error, too-few-public-methods, useless-object-inheritance + +from missing_module import missing + +class Exc(object): + """Not an actual exception.""" + +raise Exc from missing # [raising-non-exception] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.txt new file mode 100644 index 0000000..12c8862 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_non_exception_py3.txt @@ -0,0 +1 @@ +raising-non-exception:13::Raising a new style class which doesn't inherit from BaseException \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_self.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_self.py new file mode 100644 index 0000000..16f244b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_self.py @@ -0,0 +1,10 @@ +# pylint: disable=missing-docstring + +class MultiException(Exception): + def __init__(self): + Exception.__init__(self) + def return_self(self): + return self + + +raise MultiException().return_self() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_self.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/raising_self.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/recursion_error_940.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/recursion_error_940.py new file mode 100644 index 0000000..4a9f346 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/recursion_error_940.py @@ -0,0 +1,13 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance +import datetime + + +class NewDate(datetime.date): + @classmethod + def today(cls): + return cls(2010, 1, 1) + + +class Next(object): + def __init__(self): + datetime.date = NewDate diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.py new file mode 100644 index 0000000..9f56cfb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.py @@ -0,0 +1,68 @@ +"""Test for W0623, overwriting names in exception handlers.""" +# pylint: disable=broad-except,bare-except,print-statement,no-absolute-import,duplicate-except +# pylint: disable=invalid-name, unused-variable +import exceptions + +__revision__ = '' + +class MyError(Exception): + """Special exception class.""" + pass + + +def some_function(): + """A function.""" + exc = None + + try: + {}["a"] + except KeyError, exceptions.RuntimeError: # [redefine-in-handler] + pass + except KeyError, OSError: # [redefine-in-handler] + pass + except KeyError, MyError: # [redefine-in-handler] + pass + except KeyError, exc: # this is fine + print exc + except KeyError, exc1: # this is fine + print exc1 + except KeyError, FOO: # C0103 + print FOO + + try: + pass + except KeyError, exc1: # this is fine + print exc1 + +class MyOtherError(Exception): + """Special exception class.""" + pass + + +exc3 = None + +try: + pass +except KeyError, exceptions.RuntimeError: # [redefine-in-handler] + pass +except KeyError, exceptions.RuntimeError.args: # [redefine-in-handler] + pass +except KeyError, OSError: # [redefine-in-handler] + pass +except KeyError, MyOtherError: # [redefine-in-handler] + pass +except KeyError, exc3: # this is fine + print exc3 +except KeyError, exc4: # this is fine + print exc4 +except KeyError, OOPS: # C0103 + print OOPS + +try: + pass +except KeyError, exc4: # this is fine + print exc4 +except IOError, exc5: # this is fine + print exc5 +except MyOtherError, exc5: # this is fine + print exc5 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.txt new file mode 100644 index 0000000..48674a1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefine_in_handler.txt @@ -0,0 +1,7 @@ +redefine-in-handler:19:some_function:Redefining name 'RuntimeError' from object 'exceptions' in exception handler +redefine-in-handler:21:some_function:Redefining name 'OSError' from builtins in exception handler +redefine-in-handler:23:some_function:Redefining name 'MyError' from outer scope (line 8) in exception handler +redefine-in-handler:46::Redefining name 'RuntimeError' from object 'exceptions' in exception handler +redefine-in-handler:48::Redefining name 'args' from object 'exceptions.RuntimeError' in exception handler +redefine-in-handler:50::Redefining name 'OSError' from builtins in exception handler +redefine-in-handler:52::Redefining name 'MyOtherError' from outer scope (line 37) in exception handler diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_argument_from_local.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_argument_from_local.py new file mode 100644 index 0000000..b1735e9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_argument_from_local.py @@ -0,0 +1,67 @@ +# pylint: disable=missing-docstring, unused-variable, unused-argument +# pylint: disable=redefined-outer-name, invalid-name, redefine-in-handler + +def test_redefined_in_with(name): + with open('something') as name: # [redefined-argument-from-local] + pass + with open('something') as (second, name): # [redefined-argument-from-local] + pass + with open('something') as (second, (name, third)): # [redefined-argument-from-local] + pass + other = None + with open('something') as other: + pass + + + +def test_not_redefined_in_with(name): + with open('something') as test_redefined_in_with: + pass + + + +def test_redefined_in_for(name): + for name in []: # [redefined-argument-from-local] + pass + for (name, is_) in []: # [redefined-argument-from-local] + pass + for (is_, (name, _)) in []: # [redefined-argument-from-local] + pass + for _ in []: + pass + + +def test_not_redefined_in_for(name): + for name_1 in []: + pass + + # This one can be okay if you are interested in the last value + # of the iteration + other = None + for other in []: + pass + + +def test_redefined_in_except_handler(name): + try: + 1 / 0 + except ZeroDivisionError as name: # [redefined-argument-from-local] + pass + + +def test_not_redefined_in_except_handler(name): + try: + 1 / 0 + except ZeroDivisionError as test_redefined_in_except_handler: + pass + + +def test_not_redefined(name): + if not name: + name = '' + + +def apply_filter(objects, filt=lambda obj: True): + for obj in objects: + if filt(obj): + yield obj diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_argument_from_local.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_argument_from_local.txt new file mode 100644 index 0000000..c3c026b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_argument_from_local.txt @@ -0,0 +1,7 @@ +redefined-argument-from-local:5:test_redefined_in_with:Redefining argument with the local name 'name' +redefined-argument-from-local:7:test_redefined_in_with:Redefining argument with the local name 'name' +redefined-argument-from-local:9:test_redefined_in_with:Redefining argument with the local name 'name' +redefined-argument-from-local:24:test_redefined_in_for:Redefining argument with the local name 'name' +redefined-argument-from-local:26:test_redefined_in_for:Redefining argument with the local name 'name' +redefined-argument-from-local:28:test_redefined_in_for:Redefining argument with the local name 'name' +redefined-argument-from-local:48:test_redefined_in_except_handler:Redefining argument with the local name 'name' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_builtin.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_builtin.py new file mode 100644 index 0000000..c840f8d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_builtin.py @@ -0,0 +1,11 @@ +"""Tests for redefining builtins.""" +from __future__ import print_function + +def function(): + """Redefined local.""" + type = 1 # [redefined-builtin] + print(type) + +# pylint:disable=invalid-name +map = {} # [redefined-builtin] +__doc__ = 'reset the doc' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_builtin.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_builtin.txt new file mode 100644 index 0000000..fb11cd3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redefined_builtin.txt @@ -0,0 +1,2 @@ +redefined-builtin:6:function:Redefining built-in 'type' +redefined-builtin:10::Redefining built-in 'map' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redundant_unittest_assert.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redundant_unittest_assert.py new file mode 100644 index 0000000..2eb73e3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redundant_unittest_assert.py @@ -0,0 +1,38 @@ +# pylint: disable=missing-docstring,too-few-public-methods +""" +http://www.logilab.org/ticket/355 +If you are using assertTrue or assertFalse and the first argument is a +constant(like a string), then the assert will always be true. Therefore, +it should emit a warning message. +""" + +import unittest + +@unittest.skip("don't run this") +class Tests(unittest.TestCase): + def test_something(self): + ''' Simple test ''' + some_var = 'It should be assertEqual' + # +1:[redundant-unittest-assert] + self.assertTrue('I meant assertEqual not assertTrue', some_var) + # +1:[redundant-unittest-assert] + self.assertFalse('I meant assertEqual not assertFalse', some_var) + # +1:[redundant-unittest-assert] + self.assertTrue(True, some_var) + # +1:[redundant-unittest-assert] + self.assertFalse(False, some_var) + # +1:[redundant-unittest-assert] + self.assertFalse(None, some_var) + # +1:[redundant-unittest-assert] + self.assertTrue(0, some_var) + + self.assertTrue('should be' in some_var, some_var) + self.assertTrue(some_var, some_var) + + +@unittest.skip("don't run this") +class RegressionWithArgs(unittest.TestCase): + '''Don't fail if the bound method doesn't have arguments.''' + + def test(self): + self.run() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redundant_unittest_assert.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redundant_unittest_assert.txt new file mode 100644 index 0000000..889d395 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/redundant_unittest_assert.txt @@ -0,0 +1,6 @@ +redundant-unittest-assert:17:Tests.test_something:"Redundant use of assertTrue with constant value 'I meant assertEqual not assertTrue'" +redundant-unittest-assert:19:Tests.test_something:"Redundant use of assertFalse with constant value 'I meant assertEqual not assertFalse'" +redundant-unittest-assert:21:Tests.test_something:"Redundant use of assertTrue with constant value True" +redundant-unittest-assert:23:Tests.test_something:"Redundant use of assertFalse with constant value False" +redundant-unittest-assert:25:Tests.test_something:"Redundant use of assertFalse with constant value None" +redundant-unittest-assert:27:Tests.test_something:"Redundant use of assertTrue with constant value 0" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_1326_crash_uninferable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_1326_crash_uninferable.py new file mode 100644 index 0000000..26b8eb7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_1326_crash_uninferable.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring + +import socket + +RETRYABLE_EXCEPTIONS = (socket.error,) + + +def exception_handler(): + try: + yield 1 + except RETRYABLE_EXCEPTIONS + tuple(): + yield 2 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_no_value_for_parameter.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_no_value_for_parameter.py new file mode 100644 index 0000000..30308e6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_no_value_for_parameter.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-docstring,import-error +from Unknown import Unknown + +class ConfigManager(Unknown): + + + RENAMED_SECTIONS = { + 'permissions': 'content' + } + + def test(self): + self.RENAMED_SECTIONS.items() #@ + + def items(self, sectname, raw=True): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_no_value_for_parameter.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/regression_no_value_for_parameter.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reimported.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reimported.py new file mode 100644 index 0000000..4299c1e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reimported.py @@ -0,0 +1,16 @@ +# pylint: disable=missing-docstring,unused-import,import-error, wildcard-import,unused-wildcard-import,redefined-builtin,no-name-in-module,ungrouped-imports,wrong-import-order + +from time import sleep, sleep # [reimported] +from lala import missing, missing # [reimported] + +import missing1 +import missing1 # [reimported] + +from collections import deque +from itertools import deque # [reimported] + +from collections import OrderedDict +from itertools import OrderedDict as NotOrderedDict + +from itertools import * +from os import * diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reimported.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reimported.txt new file mode 100644 index 0000000..b15625e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reimported.txt @@ -0,0 +1,4 @@ +reimported:3::"Reimport 'sleep' (imported line 3)" +reimported:4::"Reimport 'missing' (imported line 4)" +reimported:7::"Reimport 'missing1' (imported line 6)" +reimported:10::"Reimport 'deque' (imported line 9)" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/repeated_keyword.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/repeated_keyword.py new file mode 100644 index 0000000..e683471 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/repeated_keyword.py @@ -0,0 +1,13 @@ +"""Check that a keyword is not repeated in a function call + +This is somehow related to redundant-keyword, but it's not the same. +""" + +# pylint: disable=missing-docstring, invalid-name + +def test(a, b): + return a, b + +test(1, 24) +test(1, b=24, **{}) +test(1, b=24, **{'b': 24}) # [repeated-keyword] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/repeated_keyword.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/repeated_keyword.txt new file mode 100644 index 0000000..1344b15 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/repeated_keyword.txt @@ -0,0 +1 @@ +repeated-keyword:13::"Got multiple values for keyword argument 'b' in function call" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_in_init.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_in_init.py new file mode 100644 index 0000000..bf0aa06 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_in_init.py @@ -0,0 +1,25 @@ +# pylint: disable=missing-docstring,too-few-public-methods,useless-return, useless-object-inheritance + +class MyClass(object): + + def __init__(self): # [return-in-init] + return 1 + +class MyClass2(object): + """dummy class""" + + def __init__(self): + return + + +class MyClass3(object): + """dummy class""" + + def __init__(self): + return None + +class MyClass5(object): + """dummy class""" + + def __init__(self): + self.callable = lambda: (yield None) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_in_init.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_in_init.txt new file mode 100644 index 0000000..5e708d0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_in_init.txt @@ -0,0 +1 @@ +return-in-init:5:MyClass.__init__:Explicit return in __init__ \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_outside_function.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_outside_function.py new file mode 100644 index 0000000..449dafd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_outside_function.py @@ -0,0 +1,2 @@ +"""This is gramatically correct, but it's still a SyntaxError""" +return # [return-outside-function] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_outside_function.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_outside_function.txt new file mode 100644 index 0000000..0c9aa56 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/return_outside_function.txt @@ -0,0 +1 @@ +return-outside-function:2::Return outside function \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable.py new file mode 100644 index 0000000..b244e99 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable.py @@ -0,0 +1,37 @@ +"""Tests for redefining an outer loop variable.""" +from __future__ import print_function +__revision__ = 0 + +# Simple nested loop +for i in range(10): + for i in range(10): #[redefined-outer-name] + print(i) + +# When outer loop unpacks a tuple +for i, i_again in enumerate(range(10)): + for i in range(10): #[redefined-outer-name] + print(i, i_again) + +# When inner loop unpacks a tuple +for i in range(10): + for i, i_again in range(10): #[redefined-outer-name] + print(i, i_again) + +# With nested tuple unpacks +for (a, (b, c)) in [(1, (2, 3))]: + for i, a in range(10): #[redefined-outer-name] + print(i, a, b, c) + +# Ignores when in else +for i in range(10): + print(i) + if i > 5: + break +else: + for i in range(2): + print(i) + +# Ignores dummy variables +for _ in range(10): + for _ in range(10): + print("Hello") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable.txt new file mode 100644 index 0000000..1252ac9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable.txt @@ -0,0 +1,4 @@ +redefined-outer-name:7::Redefining name 'i' from outer scope (line 6) +redefined-outer-name:12::Redefining name 'i' from outer scope (line 11) +redefined-outer-name:17::Redefining name 'i' from outer scope (line 16) +redefined-outer-name:22::Redefining name 'a' from outer scope (line 21) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.py new file mode 100644 index 0000000..6eaa1f5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.py @@ -0,0 +1,5 @@ +"""Python >= 3 tests for redefining an outer loop's variable.""" + +for i, *j in [(1, 2, 3, 4)]: + for j in range(i): #[redefined-outer-name] + print(j) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.txt new file mode 100644 index 0000000..ac3a6ea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/reused_outer_loop_variable_py3.txt @@ -0,0 +1 @@ +redefined-outer-name:4::Redefining name 'j' from outer scope (line 3) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/self_cls_assignment.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/self_cls_assignment.py new file mode 100644 index 0000000..4e63bb4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/self_cls_assignment.py @@ -0,0 +1,47 @@ +"""Warning about assigning self/cls variable.""" +from __future__ import print_function +# pylint: disable=too-few-public-methods, useless-object-inheritance + +class Foo(object): + """Class with methods that check for self/cls assignment""" + + # pylint: disable=no-self-argument,no-self-use + def self_foo(bar_): + """Instance method, should warn for bar""" + bar_ = 10 # [self-cls-assignment] + + # pylint: disable=no-self-use + def self_foofoo(self, lala): + """Instance method, should warn for self""" + self = lala # [self-cls-assignment] + + @classmethod + def cls_foo(cls): + """Class method, should warn for cls""" + cls = 'tada' # [self-cls-assignment] + + # pylint: disable=unused-argument + @staticmethod + def static_foo(lala): + """Static method, no warnings""" + lala = 10 + + +# pylint: disable=unused-argument +def free_foo(bar_, lala): + """Free function, no warnings""" + bar_ = lala + + +class TestNonLocal: + """Test class for nonlocal assignment of self""" + + def function(self, param): + """This function uses nonlocal to reassign self""" + + def _set_param(param): + nonlocal self + self = param # [self-cls-assignment] + + _set_param(param) + return self diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/self_cls_assignment.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/self_cls_assignment.txt new file mode 100644 index 0000000..42a9034 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/self_cls_assignment.txt @@ -0,0 +1,4 @@ +self-cls-assignment:11:Foo.self_foo:Invalid assignment to bar_ in method +self-cls-assignment:16:Foo.self_foofoo:Invalid assignment to self in method +self-cls-assignment:21:Foo.cls_foo:Invalid assignment to cls in method +self-cls-assignment:44:TestNonLocal.function._set_param:Invalid assignment to self in method diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/signature_differs.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/signature_differs.py new file mode 100644 index 0000000..920611f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/signature_differs.py @@ -0,0 +1,22 @@ +# pylint: disable=too-few-public-methods, missing-docstring, no-self-use, useless-object-inheritance + +class Abcd(object): + + def __init__(self): + self.aarg = False + + def abcd(self, aaa=1, bbbb=None): + return aaa, bbbb + + def args(self): + self.aarg = True + + +class Cdef(Abcd): + + def __init__(self, aaa): + Abcd.__init__(self) + self.aaa = aaa + + def abcd(self, aaa, bbbb=None): # [signature-differs] + return aaa, bbbb diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/signature_differs.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/signature_differs.txt new file mode 100644 index 0000000..a9985e5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/signature_differs.txt @@ -0,0 +1 @@ +signature-differs:21:Cdef.abcd:Signature differs from overridden 'abcd' method diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_expression.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_expression.py new file mode 100644 index 0000000..bcfdf89 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_expression.py @@ -0,0 +1,27 @@ +"""Test that some if expressions can be simplified.""" + +# pylint: disable=missing-docstring, invalid-name + + +def test_simplifiable_1(arg): + # Simple test that can be replaced by bool(arg) + return True if arg else False # [simplifiable-if-expression] + +def test_simplifiable_2(arg): + # Simple test that can be replaced by not arg + return False if arg else True # [simplifiable-if-expression] + +def test_simplifiable_3(arg): + # Simple test that can be replaced by arg == 1 + return True if arg == 1 else False # [simplifiable-if-expression] + +def test_simplifiable_4(arg): + # Simple test that can be replaced by not (arg == 1) + return False if arg == 1 else True # [simplifiable-if-expression] + +def test_not_simplifiable(arg): + x = True if arg else True + y = 0 if arg else 1 + t = False if arg != 1 else False + t2 = None if arg > 3 else False + return x, y, t, t2 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_expression.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_expression.txt new file mode 100644 index 0000000..b35e084 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_expression.txt @@ -0,0 +1,4 @@ +simplifiable-if-expression:8:test_simplifiable_1:The if expression can be replaced with 'bool(test)' +simplifiable-if-expression:12:test_simplifiable_2:The if expression can be replaced with 'not test' +simplifiable-if-expression:16:test_simplifiable_3:The if expression can be replaced with 'test' +simplifiable-if-expression:20:test_simplifiable_4:The if expression can be replaced with 'not test' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_statement.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_statement.py new file mode 100644 index 0000000..d306299 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_statement.py @@ -0,0 +1,146 @@ +"""Test that some if statement tests can be simplified.""" + +# pylint: disable=missing-docstring, invalid-name, no-else-return + + +def test_simplifiable_1(arg): + # Simple test that can be replaced by bool(arg) + if arg: # [simplifiable-if-statement] + return True + else: + return False + + +def test_simplifiable_2(arg, arg2): + # Can be reduced to bool(arg and not arg2) + if arg and not arg2: # [simplifiable-if-statement] + return True + else: + return False + + +def test_simplifiable_3(arg, arg2): + # Can be reduced to bool(arg and not arg2) + if arg and not arg2: # [simplifiable-if-statement] + var = True + else: + var = False + return var + + +def test_simplifiable_4(arg): + if arg: + var = True + else: + if arg == "arg1": # [simplifiable-if-statement] + return True + else: + return False + return var + + +def test_not_necessarily_simplifiable_1(arg, arg2): + # Can be reduced to bool(not arg and not arg2) or to + # `not all(N)`, which is a bit harder to understand + # than `any(N)` when var should be False. + if arg or arg2: + var = False + else: + var = True + return var + + +def test_not_necessarily_simplifiabile_2(arg): + # This could theoretically be reduced to `not arg or arg > 3` + # but the net result is that now the condition is harder to understand, + # because it requires understanding of an extra clause: + # * first, there is the negation of truthness with `not arg` + # * the second clause is `arg > 3`, which occurs when arg has a + # a truth value, but it implies that `arg > 3` is equivalent + # with `arg and arg > 3`, which means that the user must + # think about this assumption when evaluating `arg > 3`. + # The original form is easier to grasp. + if arg and arg <= 3: + return False + else: + return True + + +def test_not_simplifiable_3(arg): + if arg: + test_not_necessarily_simplifiabile_2(arg) + test_not_necessarily_simplifiable_1(arg, arg) + return False + else: + if arg < 3: + test_simplifiable_3(arg, 42) + return True + + +def test_not_simplifiable_4(arg): + # Not interested in multiple elifs + if arg == "any": + return True + elif test_not_simplifiable_3(arg) == arg: + return True + else: + return False + + +def test_not_simplifiable_5(arg): + # Different actions in each branch + if arg == "any": + return True + else: + var = 42 + return var + + +def test_not_simplifiable_6(arg): + # Different actions in each branch + if arg == "any": + var = 42 + else: + return True + return var + +def test_not_simplifiable_7(arg): + # Returning something different + if arg == "any": + return 4 + else: + return 5 + + +def test_not_simplifiable_8(arg): + # Only one of the branch returns something boolean + if arg == "any": + return True + else: + return 0 + + +def test_not_simplifiable_9(): + # Not the same targets + first = True + second = 1 + third = [1] + fourth = False + fifth = False + + if first and second in third: + fourth = True + else: + fifth = True + return fourth + fifth + + +def test_not_simplifiable_10(): + # Subscripts are not considered + object_type = 'read' + filter_kwargs = {} + if object_type == 'read': + filter_kwargs['a'] = True + else: + filter_kwargs['b'] = True + return filter_kwargs diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_statement.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_statement.txt new file mode 100644 index 0000000..1c51109 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplifiable_if_statement.txt @@ -0,0 +1,4 @@ +simplifiable-if-statement:8:test_simplifiable_1:The if statement can be replaced with 'return bool(test)' +simplifiable-if-statement:16:test_simplifiable_2:The if statement can be replaced with 'return bool(test)' +simplifiable-if-statement:24:test_simplifiable_3:The if statement can be replaced with 'var = bool(test)' +simplifiable-if-statement:35:test_simplifiable_4:The if statement can be replaced with 'return bool(test)' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplify_chained_comparison.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplify_chained_comparison.py new file mode 100644 index 0000000..a869c45 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplify_chained_comparison.py @@ -0,0 +1,69 @@ +"""Test that some boolean expression statement tests can be simplified.""" + +# pylint: disable=missing-docstring, invalid-name, no-else-return + + +def test_simplify_chained_comparison_1(): + a = 1 + b = 2 + c = 3 + return a < b and b < c # [chained-comparison] + + +def test_simplify_chained_comparison_2(): + a = 1 + return a < 10 and a > 1 # [chained-comparison] + + +def test_simplify_chained_comparison_3(): + a = 1 + b = 2 + c = 3 + if a < 10 and a > 1: # [chained-comparison] + pass + elif a > 1 and a < 10: # [chained-comparison] + pass + elif a > 1 and a <= 10: # [chained-comparison] + pass + elif a > 1 and a < 10 and b == 2: # [chained-comparison] + pass + elif a > 1 and c == b and a < 10: # [chained-comparison] + pass + elif a > 100 and c == b and a < 10: # [chained-comparison] + # In this comparison we are not checking whether left bound is actually + # lower than right bound or not. + pass + elif a < b and b < c: # [chained-comparison] + pass + elif a > b and b > c: # [chained-comparison] + pass + elif a < b and a == 1 and b < c: # [chained-comparison] + pass + elif a < b and b < c and c == 786: # [chained-comparison] + pass + elif a < b and b < 0 and c == 786: # [chained-comparison] + pass + + +def test_not_simplify_chained_comparison_1(): + a = 1 + b = 2 + c = 3 + if a < 10 and b > 1: + pass + elif a > 1 and b < 10: + pass + elif a > 1 and a == 10: + pass + elif a == 1 and b == 2: + pass + elif a > 1 and a > 10: + pass + elif a < 100 and a < 10: + pass + elif a < b and a < c: + pass + elif a < b and a == 1 and a < c: + pass + elif a < b and a < c and c == 786: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplify_chained_comparison.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplify_chained_comparison.txt new file mode 100644 index 0000000..863c420 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/simplify_chained_comparison.txt @@ -0,0 +1,13 @@ +chained-comparison:10:test_simplify_chained_comparison_1:Simplify chained comparison between the operands +chained-comparison:15:test_simplify_chained_comparison_2:Simplify chained comparison between the operands +chained-comparison:22:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:24:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:26:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:28:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:30:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:32:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:36:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:38:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:40:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:42:test_simplify_chained_comparison_3:Simplify chained comparison between the operands +chained-comparison:44:test_simplify_chained_comparison_3:Simplify chained comparison between the operands \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.py new file mode 100644 index 0000000..cfd4d87 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.py @@ -0,0 +1,76 @@ +# pylint: disable=missing-docstring,import-error,unused-import,assignment-from-no-return +# pylint: disable=invalid-name, too-few-public-methods, useless-object-inheritance +from __future__ import print_function +from UNINFERABLE import uninferable_func + +try: + from functools import singledispatch +except ImportError: + from singledispatch import singledispatch + +my_single_dispatch = singledispatch + + +class FakeSingleDispatch(object): + + @staticmethod + def register(function): + return function + + def __call__(self, function): + return function + +fake_singledispatch_decorator = FakeSingleDispatch() + +@singledispatch +def func(arg): + return arg + + +@func.register(str) +def _(arg): + return 42 + + +@func.register(float) +@func.register(int) +def _(arg): + return 42 + + +@my_single_dispatch +def func2(arg): + return arg + + +@func2.register(int) +def _(arg): + return 42 + + +@singledispatch +def with_extra_arg(arg, verbose=False): + if verbose: + print(arg) + return arg + + +@with_extra_arg.register(str) +def _(arg, verbose=False): + unused = 42 # [unused-variable] + return arg[::-1] + + +@fake_singledispatch_decorator +def not_single_dispatch(arg): # [unused-argument] + return 'not yet implemented' + + +@fake_singledispatch_decorator.register(str) +def bad_single_dispatch(arg): # [unused-argument] + return 42 + + +@fake_singledispatch_decorator.register(str) +def bad_single_dispatch(arg): # [unused-argument, function-redefined] + return 24 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.rc new file mode 100644 index 0000000..fc795dc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.rc @@ -0,0 +1,3 @@ +[testoptions] +;http://bugs.python.org/issue10445 +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.txt new file mode 100644 index 0000000..568f41b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions.txt @@ -0,0 +1,5 @@ +unused-variable:60:_:Unused variable 'unused' +unused-argument:65:not_single_dispatch:Unused argument 'arg' +unused-argument:70:bad_single_dispatch:Unused argument 'arg' +function-redefined:75:bad_single_dispatch:function already defined line 70 +unused-argument:75:bad_single_dispatch:Unused argument 'arg' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.py new file mode 100644 index 0000000..cfd4d87 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.py @@ -0,0 +1,76 @@ +# pylint: disable=missing-docstring,import-error,unused-import,assignment-from-no-return +# pylint: disable=invalid-name, too-few-public-methods, useless-object-inheritance +from __future__ import print_function +from UNINFERABLE import uninferable_func + +try: + from functools import singledispatch +except ImportError: + from singledispatch import singledispatch + +my_single_dispatch = singledispatch + + +class FakeSingleDispatch(object): + + @staticmethod + def register(function): + return function + + def __call__(self, function): + return function + +fake_singledispatch_decorator = FakeSingleDispatch() + +@singledispatch +def func(arg): + return arg + + +@func.register(str) +def _(arg): + return 42 + + +@func.register(float) +@func.register(int) +def _(arg): + return 42 + + +@my_single_dispatch +def func2(arg): + return arg + + +@func2.register(int) +def _(arg): + return 42 + + +@singledispatch +def with_extra_arg(arg, verbose=False): + if verbose: + print(arg) + return arg + + +@with_extra_arg.register(str) +def _(arg, verbose=False): + unused = 42 # [unused-variable] + return arg[::-1] + + +@fake_singledispatch_decorator +def not_single_dispatch(arg): # [unused-argument] + return 'not yet implemented' + + +@fake_singledispatch_decorator.register(str) +def bad_single_dispatch(arg): # [unused-argument] + return 42 + + +@fake_singledispatch_decorator.register(str) +def bad_single_dispatch(arg): # [unused-argument, function-redefined] + return 24 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.rc new file mode 100644 index 0000000..d43f6c3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.rc @@ -0,0 +1,3 @@ +[testoptions] +;http://bugs.python.org/issue10445 +min_pyver=3.4 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.txt new file mode 100644 index 0000000..568f41b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singledispatch_functions_py3.txt @@ -0,0 +1,5 @@ +unused-variable:60:_:Unused variable 'unused' +unused-argument:65:not_single_dispatch:Unused argument 'arg' +unused-argument:70:bad_single_dispatch:Unused argument 'arg' +function-redefined:75:bad_single_dispatch:function already defined line 70 +unused-argument:75:bad_single_dispatch:Unused argument 'arg' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singleton_comparison.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singleton_comparison.py new file mode 100644 index 0000000..9a28c0e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singleton_comparison.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-docstring, invalid-name, misplaced-comparison-constant,literal-comparison, comparison-with-itself +x = 42 +a = x is None +b = x == None # [singleton-comparison] +c = x == True # [singleton-comparison] +d = x == False # [singleton-comparison] +e = True == True # [singleton-comparison] +f = x is 1 +g = 123 is "123" +h = None is x +i = None == x # [singleton-comparison] + +j = x != True # [singleton-comparison] +j1 = x != False # [singleton-comparison] +j2 = x != None # [singleton-comparison] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singleton_comparison.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singleton_comparison.txt new file mode 100644 index 0000000..533d71f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/singleton_comparison.txt @@ -0,0 +1,8 @@ +singleton-comparison:4::Comparison to None should be 'expr is None' +singleton-comparison:5::Comparison to True should be just 'expr' +singleton-comparison:6::Comparison to False should be 'not expr' +singleton-comparison:7::Comparison to True should be just 'expr' +singleton-comparison:11::Comparison to None should be 'expr is None' +singleton-comparison:13::Comparison to True should be just 'not expr' +singleton-comparison:14::Comparison to False should be 'expr' +singleton-comparison:15::Comparison to None should be 'expr is not None' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/slots_checks.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/slots_checks.py new file mode 100644 index 0000000..800a45e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/slots_checks.py @@ -0,0 +1,85 @@ +""" Checks that classes uses valid __slots__ """ + +# pylint: disable=too-few-public-methods, missing-docstring, no-absolute-import, useless-object-inheritance +# pylint: disable=using-constant-test, wrong-import-position, no-else-return +from collections import deque + +def func(): + if True: + return ("a", "b", "c") + else: + return [str(var) for var in range(3)] + + +class NotIterable(object): + def __iter_(self): + """ do nothing """ + +class Good(object): + __slots__ = () + +class SecondGood(object): + __slots__ = [] + +class ThirdGood(object): + __slots__ = ['a'] + +class FourthGood(object): + __slots__ = ('a%s' % i for i in range(10)) + +class FifthGood(object): + __slots__ = deque(["a", "b", "c"]) + +class SixthGood(object): + __slots__ = {"a": "b", "c": "d"} + +class Bad(object): # [invalid-slots] + __slots__ = list + +class SecondBad(object): # [invalid-slots] + __slots__ = 1 + +class ThirdBad(object): + __slots__ = ('a', 2) # [invalid-slots-object] + +class FourthBad(object): # [invalid-slots] + __slots__ = NotIterable() + +class FifthBad(object): + __slots__ = ("a", "b", "") # [invalid-slots-object] + +class SixthBad(object): # [single-string-used-for-slots] + __slots__ = "a" + +class SeventhBad(object): # [single-string-used-for-slots] + __slots__ = ('foo') + +class EighthBad(object): # [single-string-used-for-slots] + __slots__ = deque.__name__ + +class PotentiallyGood(object): + __slots__ = func() + +class PotentiallySecondGood(object): + __slots__ = ('a', deque.__name__) + + +import six + + +class Metaclass(type): + + def __iter__(cls): + for value in range(10): + yield str(value) + + +@six.add_metaclass(Metaclass) +class IterableClass(object): + pass + +class PotentiallyThirdGood(object): + __slots__ = IterableClass + +class PotentiallyFourthGood(object): + __slots__ = Good.__slots__ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/slots_checks.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/slots_checks.txt new file mode 100644 index 0000000..90a6a80 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/slots_checks.txt @@ -0,0 +1,8 @@ +invalid-slots:36:Bad:Invalid __slots__ object +invalid-slots:39:SecondBad:Invalid __slots__ object +invalid-slots-object:43:ThirdBad:Invalid object '2' in __slots__, must contain only non empty strings +invalid-slots:45:FourthBad:Invalid __slots__ object +invalid-slots-object:49:FifthBad:"Invalid object ""''"" in __slots__, must contain only non empty strings" +single-string-used-for-slots:51:SixthBad:Class __slots__ should be a non-string iterable +single-string-used-for-slots:54:SeventhBad:Class __slots__ should be a non-string iterable +single-string-used-for-slots:57:EighthBad:Class __slots__ should be a non-string iterable diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/socketerror_import.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/socketerror_import.py new file mode 100644 index 0000000..df5de29 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/socketerror_import.py @@ -0,0 +1,6 @@ +"""ds""" +from __future__ import absolute_import, print_function +from socket import error +__revision__ = '$Id: socketerror_import.py,v 1.2 2005-12-28 14:58:22 syt Exp $' + +print(error) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.py new file mode 100644 index 0000000..dd50568 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.py @@ -0,0 +1,4 @@ +"""Test for a = *b""" + +FIRST = *[1, 2] # [star-needs-assignment-target] +*THIRD, FOURTH = [1, 2, 3,] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.txt new file mode 100644 index 0000000..bd8e324 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target.txt @@ -0,0 +1 @@ +star-needs-assignment-target:3::Can use starred expression only in assignment target diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.py new file mode 100644 index 0000000..58e43db --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.py @@ -0,0 +1,15 @@ +""" +Test PEP 0448 -- Additional Unpacking Generalizations +https://www.python.org/dev/peps/pep-0448/ +""" + +# pylint: disable=superfluous-parens + +UNPACK_TUPLE = (*range(4), 4) +UNPACK_LIST = [*range(4), 4] +UNPACK_SET = {*range(4), 4} +UNPACK_DICT = {'a': 1, **{'b': '2'}} +UNPACK_DICT2 = {**UNPACK_DICT, "x": 1, "y": 2} +UNPACK_DICT3 = {**{'a': 1}, 'a': 2, **{'a': 3}} + +UNPACK_IN_COMP = {elem for elem in (*range(10))} # [star-needs-assignment-target] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.rc new file mode 100644 index 0000000..71de8b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.txt new file mode 100644 index 0000000..0777052 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/star_needs_assignment_target_py35.txt @@ -0,0 +1 @@ +star-needs-assignment-target:15::Can use starred expression only in assignment target \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect.py new file mode 100644 index 0000000..eb87aca --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect.py @@ -0,0 +1,65 @@ +"""Test for statements without effects.""" +# pylint: disable=too-few-public-methods, useless-object-inheritance + +# +1:[pointless-string-statement] +"""inline doc string should use a separated message""" + +__revision__ = '' + +__revision__ # [pointless-statement] + +__revision__ <= 1 # [pointless-statement] + +__revision__.lower() + +[i for i in __revision__] # [pointless-statement] + +# +1:[pointless-string-statement] +"""inline doc string should use a separated message""" + + +__revision__.lower(); # [unnecessary-semicolon] + +list() and tuple() # [expression-not-assigned] + +def to_be(): + """return 42""" + return "42" + +ANSWER = to_be() # ok +ANSWER == to_be() # [expression-not-assigned] + +to_be() or not to_be() # [expression-not-assigned] +to_be().title # [expression-not-assigned] + +GOOD_ATTRIBUTE_DOCSTRING = 42 +"""Module level attribute docstring is fine. """ + +class ClassLevelAttributeTest(object): + """ test attribute docstrings. """ + + good_attribute_docstring = 24 + """ class level attribute docstring is fine either. """ + second_good_attribute_docstring = 42 + # Comments are good. + + # empty lines are good, too. + """ Still a valid class level attribute docstring. """ + + def __init__(self): + self.attr = 42 + """ Good attribute docstring """ + attr = 24 + """ Still a good __init__ level attribute docstring. """ + val = 0 + for val in range(42): + val += attr + # +1:[pointless-string-statement] + """ Invalid attribute docstring """ + self.val = val + + def test(self): + """ invalid attribute docstrings here. """ + self.val = 42 + # +1:[pointless-string-statement] + """ this is an invalid attribute docstring. """ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect.txt new file mode 100644 index 0000000..bda6eae --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect.txt @@ -0,0 +1,60 @@ +pointless-string-statement:5::String statement has no effect +pointless-statement:6::"""Statement seems to have no effect +"" +" +pointless-statement:8::"""Statement seems to have no effect +"" +" +pointless-statement:9::Statement seems to have no effect +pointless-statement:11::Statement seems to have no effect +pointless-statement:12::"""Statement seems to have no effect +"" +" +pointless-statement:15::Statement seems to have no effect +pointless-string-statement:15::"""String statement has no effect +"" +" +unnecessary-semicolon:17::"""Unnecessary semicolon +"" +" +pointless-string-statement:18::String statement has no effect +unnecessary-semicolon:18::"""Unnecessary semicolon +"" +" +expression-not-assigned:19::"""Expression """"list() and tuple()"""" is assigned to nothing +"" +" +expression-not-assigned:20::"""Expression """"list() and tuple()"""" is assigned to nothing +"" +" +unnecessary-semicolon:21::Unnecessary semicolon +expression-not-assigned:23::"Expression ""list() and tuple()"" is assigned to nothing" +expression-not-assigned:26::"""Expression """"ANSWER == to_be()"""" is assigned to nothing +"" +" +expression-not-assigned:27::"""Expression """"ANSWER == to_be()"""" is assigned to nothing +"" +" +expression-not-assigned:28::"""Expression """"to_be() or not to_be()"""" is assigned to nothing +"" +" +expression-not-assigned:29::"""Expression """"to_be() or not to_be()"""" is assigned to nothing +"" +" +expression-not-assigned:30::"Expression ""ANSWER == to_be()"" is assigned to nothing" +expression-not-assigned:32::"Expression ""to_be() or not to_be()"" is assigned to nothing" +expression-not-assigned:33::"Expression ""to_be().title"" is assigned to nothing" +pointless-string-statement:54:ClassLevelAttributeTest.__init__:"""String statement has no effect +"" +" +pointless-string-statement:55:ClassLevelAttributeTest.__init__:"""String statement has no effect +"" +" +pointless-string-statement:58:ClassLevelAttributeTest.__init__:String statement has no effect +pointless-string-statement:61:ClassLevelAttributeTest.test:"""String statement has no effect +"" +" +pointless-string-statement:62:ClassLevelAttributeTest.test:"""String statement has no effect +"" +" +pointless-string-statement:65:ClassLevelAttributeTest.test:String statement has no effect diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.py new file mode 100644 index 0000000..59745ce --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.py @@ -0,0 +1,18 @@ +"""Test for statements without effects.""" +# pylint: disable=too-few-public-methods, useless-object-inheritance + + +class ClassLevelAttributeTest(object): + """ test attribute docstrings. """ + + some_variable: int = 42 + """Data docstring""" + + some_other_variable: int = 42 + """Data docstring""" + + def func(self): + """Some Empty Docstring""" + + # +1: [pointless-string-statement] + """useless""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.txt new file mode 100644 index 0000000..6b78292 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/statement_without_effect_py36.txt @@ -0,0 +1 @@ +pointless-string-statement:18:ClassLevelAttributeTest:String statement has no effect \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.py new file mode 100644 index 0000000..a51f2d3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.py @@ -0,0 +1,129 @@ +""" +Test that no StopIteration is raised inside a generator +""" +# pylint: disable=missing-docstring,invalid-name,import-error, try-except-raise, wrong-import-position +import asyncio + +class RebornStopIteration(StopIteration): + """ + A class inheriting from StopIteration exception + """ + +# This one is ok +def gen_ok(): + yield 1 + yield 2 + yield 3 + +# pylint should warn about this one +# because of a direct raising of StopIteration inside generator +def gen_stopiter(): + yield 1 + yield 2 + yield 3 + raise StopIteration # [stop-iteration-return] + +# pylint should warn about this one +# because of a direct raising of an exception inheriting from StopIteration inside generator +def gen_stopiterchild(): + yield 1 + yield 2 + yield 3 + raise RebornStopIteration # [stop-iteration-return] + +# pylint should warn here +# because of the possibility that next raises a StopIteration exception +def gen_next_raises_stopiter(): + g = gen_ok() + while True: + yield next(g) # [stop-iteration-return] + +# This one is the same as gen_next_raises_stopiter +# but is ok because the next function is inside +# a try/except block handling StopIteration +def gen_next_inside_try_except(): + g = gen_ok() + while True: + try: + yield next(g) + except StopIteration: + return + +# This one is the same as gen_next_inside_try_except +# but is not ok because the next function is inside +# a try/except block that don't handle StopIteration +def gen_next_inside_wrong_try_except(): + g = gen_ok() + while True: + try: + yield next(g) # [stop-iteration-return] + except ValueError: + return + +# This one is the same as gen_next_inside_try_except +# but is not ok because the next function is inside +# a try/except block that handle StopIteration but reraise it +def gen_next_inside_wrong_try_except2(): + g = gen_ok() + while True: + try: + yield next(g) + except StopIteration: + raise StopIteration # [stop-iteration-return] + +# Those two last are ok +def gen_in_for(): + for el in gen_ok(): + yield el + +def gen_yield_from(): + yield from gen_ok() + + +def gen_dont_crash_on_no_exception(): + g = gen_ok() + while True: + try: + yield next(g) # [stop-iteration-return] + except ValueError: + raise + + +def gen_dont_crash_on_uninferable(): + # https://github.com/PyCQA/pylint/issues/1779 + yield from iter() + raise asyncio.TimeoutError() + + +# https://github.com/PyCQA/pylint/issues/1830 +def gen_next_with_sentinel(): + yield next([], 42) # No bad return + + +from itertools import count + +# https://github.com/PyCQA/pylint/issues/2158 +def generator_using_next(): + counter = count() + number = next(counter) + yield number * 2 + + +# pylint: disable=no-self-use,too-few-public-methods +class SomeClassWithNext: + def next(self): + return iter([1, 2, 3]) + def some_gen(self): + for value in self.next(): + yield value + + +SomeClassWithNext().some_gen() + + +def something_invalid(): + raise Exception('cannot iterate this') + + +def invalid_object_passed_to_next(): + yield next(something_invalid()) # [stop-iteration-return] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.txt new file mode 100644 index 0000000..107d563 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/stop_iteration_inside_generator.txt @@ -0,0 +1,7 @@ +stop-iteration-return:24:gen_stopiter:Do not raise StopIteration in generator, use return statement instead +stop-iteration-return:32:gen_stopiterchild:Do not raise StopIteration in generator, use return statement instead +stop-iteration-return:39:gen_next_raises_stopiter:Do not raise StopIteration in generator, use return statement instead +stop-iteration-return:59:gen_next_inside_wrong_try_except:Do not raise StopIteration in generator, use return statement instead +stop-iteration-return:72:gen_next_inside_wrong_try_except2:Do not raise StopIteration in generator, use return statement instead +stop-iteration-return:87:gen_dont_crash_on_no_exception:Do not raise StopIteration in generator, use return statement instead +stop-iteration-return:129:invalid_object_passed_to_next:Do not raise StopIteration in generator, use return statement instead diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting.py new file mode 100644 index 0000000..4378c6b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting.py @@ -0,0 +1,188 @@ +"""test for Python 3 string formatting error +""" +# pylint: disable=too-few-public-methods, import-error, unused-argument, line-too-long, no-absolute-import, useless-object-inheritance +import os +from missing import Missing + +__revision__ = 1 + +class Custom(object): + """ Has a __getattr__ """ + def __getattr__(self, _): + return self + +class Test(object): + """ test format attribute access """ + custom = Custom() + ids = [1, 2, 3, [4, 5, 6]] + +class Getitem(object): + """ test custom getitem for lookup access """ + def __getitem__(self, index): + return 42 + +class ReturnYes(object): + """ can't be properly infered """ + missing = Missing() + +def log(message, message_type="error"): + """ Test """ + return message + +def print_good(): + """ Good format strings """ + "{0} {1}".format(1, 2) + "{0!r:20}".format("Hello") + "{!r:20}".format("Hello") + "{a!r:20}".format(a="Hello") + "{pid}".format(pid=os.getpid()) + str("{}").format(2) + "{0.missing.length}".format(ReturnYes()) + "{1.missing.length}".format(ReturnYes()) + "{a.ids[3][1]}".format(a=Test()) + "{a[0][0]}".format(a=[[1]]) + "{[0][0]}".format({0: {0: 1}}) + "{a.test}".format(a=Custom()) + "{a.__len__}".format(a=[]) + "{a.ids.__len__}".format(a=Test()) + "{a[0]}".format(a=Getitem()) + "{a[0][0]}".format(a=[Getitem()]) + "{[0][0]}".format(["test"]) + # these are skipped + "{0} {1}".format(*[1, 2]) + "{a} {b}".format(**{'a': 1, 'b': 2}) + "{a}".format(a=Missing()) + +def pprint_bad(): + """Test string format """ + "{{}}".format(1) # [too-many-format-args] + "{} {".format() # [bad-format-string] + "{} }".format() # [bad-format-string] + "{0} {}".format(1, 2) # [format-combined-specification] + # +1: [missing-format-argument-key, unused-format-string-argument] + "{a} {b}".format(a=1, c=2) + "{} {a}".format(1, 2) # [missing-format-argument-key] + "{} {}".format(1) # [too-few-format-args] + "{} {}".format(1, 2, 3) # [too-many-format-args] + # +1: [missing-format-argument-key,missing-format-argument-key,missing-format-argument-key] + "{a} {b} {c}".format() + "{} {}".format(a=1, b=2) # [too-few-format-args] + # +1: [missing-format-argument-key, missing-format-argument-key] + "{a} {b}".format(1, 2) + "{0} {1} {a}".format(1, 2, 3) # [missing-format-argument-key] + # +1: [missing-format-attribute] + "{a.ids.__len__.length}".format(a=Test()) + "{a.ids[3][400]}".format(a=Test()) # [invalid-format-index] + "{a.ids[3]['string']}".format(a=Test()) # [invalid-format-index] + "{[0][1]}".format(["a"]) # [invalid-format-index] + "{[0][0]}".format(((1, ))) # [invalid-format-index] + # +1: [missing-format-argument-key, unused-format-string-argument] + "{b[0]}".format(a=23) + "{a[0]}".format(a=object) # [invalid-format-index] + log("{}".format(2, "info")) # [too-many-format-args] + "{0.missing}".format(2) # [missing-format-attribute] + "{0} {1} {2}".format(1, 2) # [too-few-format-args] + "{0} {1}".format(1, 2, 3) # [too-many-format-args] + "{0} {a}".format(a=4) # [too-few-format-args] + "{[0]} {}".format([4]) # [too-few-format-args] + "{[0]} {}".format([4], 5, 6) # [too-many-format-args] + +def good_issue288(*args, **kwargs): + """ Test that using kwargs does not emit a false + positive. + """ + 'Hello John Doe {0[0]}'.format(args) + 'Hello {0[name]}'.format(kwargs) + +def good_issue287(): + """ Test that the string format checker skips + format nodes which don't have a string as a parent + (but a subscript, name etc). + """ + name = 'qwerty' + ret = {'comment': ''} + ret['comment'] = 'MySQL grant {0} is set to be revoked' + ret['comment'] = ret['comment'].format(name) + return ret, name + +def nested_issue294(): + """ Test nested format fields. """ + '{0:>{1}}'.format(42, 24) + '{0:{a[1]}} {a}'.format(1, a=[1, 2]) + '{:>{}}'.format(42, 24) + '{0:>{1}}'.format(42) # [too-few-format-args] + '{0:>{1}}'.format(42, 24, 54) # [too-many-format-args] + '{0:{a[1]}}'.format(1) # [missing-format-argument-key] + '{0:{a.x}}'.format(1, a=2) # [missing-format-attribute] + +def issue310(): + """ Test a regression using duplicate manual position arguments. """ + '{0} {1} {0}'.format(1, 2) + '{0} {1} {0}'.format(1) # [too-few-format-args] + +def issue322(): + """ Test a regression using mixed manual position arguments + and attribute access arguments. + """ + '{0}{1[FOO]}'.format(123, {'FOO': 456}) + '{0}{1[FOO]}'.format(123, {'FOO': 456}, 321) # [too-many-format-args] + '{0}{1[FOO]}'.format(123) # [too-few-format-args] + +def issue338(): + """ + Check that using a namedtuple subclass doesn't crash when + trying to infer EmptyNodes (resulted after mocking the + members of namedtuples). + """ + from collections import namedtuple + + class Crash(namedtuple("C", "foo bar")): + """ Looking for attributes in __str__ will crash, + because EmptyNodes can't be infered. + """ + def __str__(self): + return "{0.foo}: {0.bar}".format(self) + return Crash + +def issue351(): + """ + Check that the format method can be assigned to a variable, ie: + """ + fmt = 'test {} {}'.format + fmt('arg1') # [too-few-format-args] + fmt('arg1', 'arg2') + fmt('arg1', 'arg2', 'arg3') # [too-many-format-args] + +def issue373(): + """ + Ignore any object coming from an argument. + """ + class SomeClass(object): + """ empty docstring. """ + def __init__(self, opts=None): + self.opts = opts + + def dunc(self, arg): + """Don't try to analyze this.""" + return "A{0}{1}".format(arg, self.opts) + + def func(self): + """Don't try to analyze the following string.""" + return 'AAA{0[iface]}BBB{0[port]}'.format(self.opts) + + return SomeClass + +def issue_463(): + """ + Mix positional arguments, `{0}`, with positional + arguments with attribute access, `{0.__x__}`. + """ + data = "{0.__class__.__name__}: {0}".format(42) + data2 = "{0[0]}: {0}".format([1]) + return (data, data2) + + +def avoid_empty_attribute(): + """The following string is invalid, avoid crashing.""" + + return "There are {.:2f} undiscovered errors.".format(1) # [bad-format-string] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting.txt new file mode 100644 index 0000000..9801de1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting.txt @@ -0,0 +1,41 @@ +too-many-format-args:58:pprint_bad:Too many arguments for format string +bad-format-string:59:pprint_bad:Invalid format string +bad-format-string:60:pprint_bad:Invalid format string +format-combined-specification:61:pprint_bad:Format string contains both automatic field numbering and manual field specification +missing-format-argument-key:63:pprint_bad:Missing keyword argument 'b' for format string +unused-format-string-argument:63:pprint_bad:Unused format argument 'c' +missing-format-argument-key:64:pprint_bad:Missing keyword argument 'a' for format string +too-few-format-args:65:pprint_bad:Not enough arguments for format string +too-many-format-args:66:pprint_bad:Too many arguments for format string +missing-format-argument-key:68:pprint_bad:Missing keyword argument 'a' for format string +missing-format-argument-key:68:pprint_bad:Missing keyword argument 'b' for format string +missing-format-argument-key:68:pprint_bad:Missing keyword argument 'c' for format string +too-few-format-args:69:pprint_bad:Not enough arguments for format string +missing-format-argument-key:71:pprint_bad:Missing keyword argument 'a' for format string +missing-format-argument-key:71:pprint_bad:Missing keyword argument 'b' for format string +missing-format-argument-key:72:pprint_bad:Missing keyword argument 'a' for format string +missing-format-attribute:74:pprint_bad:Missing format attribute 'length' in format specifier 'a.ids.__len__.length' +invalid-format-index:75:pprint_bad:Using invalid lookup key 400 in format specifier 'a.ids[3][400]' +invalid-format-index:76:pprint_bad:"Using invalid lookup key ""'string'"" in format specifier 'a.ids[3][""\'string\'""]'" +invalid-format-index:77:pprint_bad:Using invalid lookup key 1 in format specifier '0[0][1]' +invalid-format-index:78:pprint_bad:Using invalid lookup key 0 in format specifier '0[0][0]' +missing-format-argument-key:80:pprint_bad:Missing keyword argument 'b' for format string +unused-format-string-argument:80:pprint_bad:Unused format argument 'a' +invalid-format-index:81:pprint_bad:Using invalid lookup key 0 in format specifier 'a[0]' +too-many-format-args:82:pprint_bad:Too many arguments for format string +missing-format-attribute:83:pprint_bad:Missing format attribute 'missing' in format specifier '0.missing' +too-few-format-args:84:pprint_bad:Not enough arguments for format string +too-many-format-args:85:pprint_bad:Too many arguments for format string +too-few-format-args:86:pprint_bad:Not enough arguments for format string +too-few-format-args:87:pprint_bad:Not enough arguments for format string +too-many-format-args:88:pprint_bad:Too many arguments for format string +too-few-format-args:113:nested_issue294:Not enough arguments for format string +too-many-format-args:114:nested_issue294:Too many arguments for format string +missing-format-argument-key:115:nested_issue294:Missing keyword argument 'a' for format string +missing-format-attribute:116:nested_issue294:Missing format attribute 'x' in format specifier 'a.x' +too-few-format-args:121:issue310:Not enough arguments for format string +too-many-format-args:128:issue322:Too many arguments for format string +too-few-format-args:129:issue322:Not enough arguments for format string +too-few-format-args:152:issue351:Not enough arguments for format string +too-many-format-args:154:issue351:Too many arguments for format string +bad-format-string:188:avoid_empty_attribute:Invalid format string \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.py new file mode 100644 index 0000000..096c847 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.py @@ -0,0 +1 @@ +"a {} {".format(1) # [bad-format-string] \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.rc new file mode 100644 index 0000000..0193339 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.rc @@ -0,0 +1,3 @@ +[Messages Control] +disable=all +enable=bad-format-string diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.txt new file mode 100644 index 0000000..2c8f6db --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_disable.txt @@ -0,0 +1 @@ +bad-format-string:1::Invalid format string \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_failed_inference.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_failed_inference.py new file mode 100644 index 0000000..aa8d24a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_failed_inference.py @@ -0,0 +1,4 @@ +""" Testing string format with a failed inference. This should not crash. """ + +import collections +"{dict[0]}".format(dict=collections.defaultdict(int)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.py new file mode 100644 index 0000000..b3de433 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.py @@ -0,0 +1,22 @@ +"""test for Python 2 string formatting error +""" +from __future__ import unicode_literals +# pylint: disable=line-too-long +__revision__ = 1 + +def pprint_bad(): + """Test string format """ + "{{}}".format(1) # [too-many-format-args] + "{} {".format() # [bad-format-string] + "{} }".format() # [bad-format-string] + "{0} {}".format(1, 2) # [format-combined-specification] + # +1: [missing-format-argument-key, unused-format-string-argument] + "{a} {b}".format(a=1, c=2) + "{} {a}".format(1, 2) # [missing-format-argument-key] + "{} {}".format(1) # [too-few-format-args] + "{} {}".format(1, 2, 3) # [too-many-format-args] + # +1: [missing-format-argument-key,missing-format-argument-key,missing-format-argument-key] + "{a} {b} {c}".format() + "{} {}".format(a=1, b=2) # [too-few-format-args] + # +1: [missing-format-argument-key, missing-format-argument-key] + "{a} {b}".format(1, 2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.rc new file mode 100644 index 0000000..c4f2e66 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=2.7 +max_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.txt new file mode 100644 index 0000000..47f21de --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py27.txt @@ -0,0 +1,15 @@ +too-many-format-args:9:pprint_bad:Too many arguments for format string +bad-format-string:10:pprint_bad:Invalid format string +bad-format-string:11:pprint_bad:Invalid format string +format-combined-specification:12:pprint_bad:Format string contains both automatic field numbering and manual field specification +missing-format-argument-key:14:pprint_bad:Missing keyword argument u'b' for format string +unused-format-string-argument:14:pprint_bad:Unused format argument 'c' +missing-format-argument-key:15:pprint_bad:Missing keyword argument u'a' for format string +too-few-format-args:16:pprint_bad:Not enough arguments for format string +too-many-format-args:17:pprint_bad:Too many arguments for format string +missing-format-argument-key:19:pprint_bad:Missing keyword argument u'a' for format string +missing-format-argument-key:19:pprint_bad:Missing keyword argument u'b' for format string +missing-format-argument-key:19:pprint_bad:Missing keyword argument u'c' for format string +too-few-format-args:20:pprint_bad:Not enough arguments for format string +missing-format-argument-key:22:pprint_bad:Missing keyword argument u'a' for format string +missing-format-argument-key:22:pprint_bad:Missing keyword argument u'b' for format string diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.py new file mode 100644 index 0000000..c27e971 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.py @@ -0,0 +1,21 @@ +# pylint: disable=missing-docstring,import-error + + +def issue_957_good(): + meat = ['spam', 'ham'] + print('%s%s%s' % ('eggs', *meat)) + + +def issue_957_bad1(): + meat = ['spam', 'ham', 'monty python'] + print('%s%s%s' % ('eggs', *meat)) # [too-many-format-args] + + +def issue_957_bad2(): + meat = ['spam'] + print('%s%s%s' % ('eggs', *meat)) # [too-few-format-args] + + +def issue_957_uninferable(): + from butchery import meat + print('%s%s%s' % ('eggs', *meat)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.txt new file mode 100644 index 0000000..4597589 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/string_formatting_py3.txt @@ -0,0 +1,2 @@ +too-many-format-args:11:issue_957_bad1:Too many arguments for format string +too-few-format-args:16:issue_957_bad2:Not enough arguments for format string diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.py new file mode 100644 index 0000000..e785abc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.py @@ -0,0 +1,11 @@ +# pylint: disable=blacklisted-name,no-value-for-parameter,missing-docstring + +import subprocess + +def foo(): + pass + + +subprocess.Popen(preexec_fn=foo) # [subprocess-popen-preexec-fn] + +subprocess.Popen() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.txt new file mode 100644 index 0000000..cd237a4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/subprocess_popen_preexec_fn.txt @@ -0,0 +1 @@ +subprocess-popen-preexec-fn:9::Using preexec_fn keyword which may be unsafe in the presence of threads diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/super_checks.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/super_checks.py new file mode 100644 index 0000000..3888488 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/super_checks.py @@ -0,0 +1,125 @@ +# pylint: disable=too-few-public-methods,import-error, no-absolute-import,missing-docstring, useless-object-inheritance +# pylint: disable=useless-super-delegation,wrong-import-position,invalid-name, wrong-import-order + +from unknown import Missing + +class Aaaa: + """old style""" + def hop(self): + """hop""" + super(Aaaa, self).hop() # >=3.0:[no-member] + + def __init__(self): + super(Aaaa, self).__init__() + +class NewAaaa(object): + """old style""" + def hop(self): + """hop""" + super(NewAaaa, self).hop() # [no-member] + + def __init__(self): + super(Aaaa, self).__init__() # [bad-super-call] + +class Py3kAaaa(NewAaaa): + """new style""" + def __init__(self): + super().__init__() # <3.0:[missing-super-argument] + +class Py3kWrongSuper(Py3kAaaa): + """new style""" + def __init__(self): + super(NewAaaa, self).__init__() # [bad-super-call] + +class WrongNameRegression(Py3kAaaa): + """ test a regression with the message """ + def __init__(self): + super(Missing, self).__init__() # [bad-super-call] + +class Getattr(object): + """ crash """ + name = NewAaaa + +class CrashSuper(object): + """ test a crash with this checker """ + def __init__(self): + super(Getattr.name, self).__init__() # [bad-super-call] + +class Empty(object): + """Just an empty class.""" + +class SuperDifferentScope(object): + """Don'emit bad-super-call when the super call is in another scope. + For reference, see https://bitbucket.org/logilab/pylint/issue/403. + """ + @staticmethod + def test(): + """Test that a bad-super-call is not emitted for this case.""" + class FalsePositive(Empty): + """The following super is in another scope than `test`.""" + def __init__(self, arg): + super(FalsePositive, self).__init__(arg) + super(object, 1).__init__() # [bad-super-call] + + +class UnknownBases(Missing): + """Don't emit if we don't know all the bases.""" + def __init__(self): + super(UnknownBases, self).__init__() + super(UnknownBases, self).test() + super(Missing, self).test() # [bad-super-call] + + +# Test that we are detecting proper super errors. + +class BaseClass(object): + + not_a_method = 42 + + def function(self, param): + return param + self.not_a_method + + def __getattr__(self, attr): + return attr + + +class InvalidSuperChecks(BaseClass): + + def __init__(self): + super(InvalidSuperChecks, self).not_a_method() # [not-callable] + super(InvalidSuperChecks, self).attribute_error() # [no-member] + super(InvalidSuperChecks, self).function(42) + super(InvalidSuperChecks, self).function() # [no-value-for-parameter] + super(InvalidSuperChecks, self).function(42, 24, 24) # [too-many-function-args] + # +1: [unexpected-keyword-arg,no-value-for-parameter] + super(InvalidSuperChecks, self).function(lala=42) + # Even though BaseClass has a __getattr__, that won't + # be called. + super(InvalidSuperChecks, self).attribute_error() # [no-member] + + + +# Regression for PyCQA/pylint/issues/773 +import subprocess + +# The problem was related to astroid not filtering statements +# at scope level properly, basically not doing strong updates. +try: + TimeoutExpired = subprocess.TimeoutExpired +except AttributeError: + class TimeoutExpired(subprocess.CalledProcessError): + def __init__(self): + returncode = -1 + self.timeout = -1 + super(TimeoutExpired, self).__init__(returncode) + + +class SuperWithType(object): + """type(self) may lead to recursion loop in derived classes""" + def __init__(self): + super(type(self), self).__init__() # [bad-super-call] + +class SuperWithSelfClass(object): + """self.__class__ may lead to recursion loop in derived classes""" + def __init__(self): + super(self.__class__, self).__init__() # [bad-super-call] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/super_checks.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/super_checks.txt new file mode 100644 index 0000000..4911a6c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/super_checks.txt @@ -0,0 +1,18 @@ +no-member:10:Aaaa.hop:Super of 'Aaaa' has no 'hop' member:INFERENCE +no-member:19:NewAaaa.hop:Super of 'NewAaaa' has no 'hop' member:INFERENCE +bad-super-call:22:NewAaaa.__init__:Bad first argument 'Aaaa' given to super() +missing-super-argument:27:Py3kAaaa.__init__:Missing argument to super() +bad-super-call:32:Py3kWrongSuper.__init__:Bad first argument 'NewAaaa' given to super() +bad-super-call:37:WrongNameRegression.__init__:Bad first argument 'Missing' given to super() +bad-super-call:46:CrashSuper.__init__:Bad first argument 'NewAaaa' given to super() +bad-super-call:62:SuperDifferentScope.test:Bad first argument 'object' given to super() +bad-super-call:70:UnknownBases.__init__:Bad first argument 'Missing' given to super() +not-callable:89:InvalidSuperChecks.__init__:super(InvalidSuperChecks, self).not_a_method is not callable +no-member:90:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE +no-value-for-parameter:92:InvalidSuperChecks.__init__:No value for argument 'param' in method call +too-many-function-args:93:InvalidSuperChecks.__init__:Too many positional arguments for method call +no-value-for-parameter:95:InvalidSuperChecks.__init__:No value for argument 'param' in method call +unexpected-keyword-arg:95:InvalidSuperChecks.__init__:Unexpected keyword argument 'lala' in method call +no-member:98:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE +bad-super-call:120:SuperWithType.__init__:Bad first argument 'type' given to super() +bad-super-call:125:SuperWithSelfClass.__init__:Bad first argument 'self.__class__' given to super() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/superfluous_parens.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/superfluous_parens.py new file mode 100644 index 0000000..13418cd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/superfluous_parens.py @@ -0,0 +1,19 @@ +"""Test the superfluous-parens warning.""" +from __future__ import print_function +# pylint: disable=unneeded-not +i = 3 +if (i == 5): # [superfluous-parens] + pass +if not (i == 5): # [superfluous-parens] + pass +if not (3 or 5): + pass +for (x) in (1, 2, 3): # [superfluous-parens] + print(x) +if (1) in (1, 2, 3): # [superfluous-parens] + pass +if (1, 2) in (1, 2, 3): + pass +DICT = {'a': 1, 'b': 2} +del(DICT['b']) # [superfluous-parens] +del DICT['a'] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/superfluous_parens.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/superfluous_parens.txt new file mode 100644 index 0000000..57e1019 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/superfluous_parens.txt @@ -0,0 +1,5 @@ +superfluous-parens:5::Unnecessary parens after 'if' keyword +superfluous-parens:7::Unnecessary parens after 'not' keyword +superfluous-parens:11::Unnecessary parens after 'for' keyword +superfluous-parens:13::Unnecessary parens after 'if' keyword +superfluous-parens:18::Unnecessary parens after 'del' keyword diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.py new file mode 100644 index 0000000..e859f25 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.py @@ -0,0 +1,9 @@ +"""Suspicious str.strip calls.""" +__revision__ = 1 + +''.strip('yo') +''.strip() + +u''.strip('http://') # [bad-str-strip-call] +u''.lstrip('http://') # [bad-str-strip-call] +b''.rstrip('http://') # [bad-str-strip-call] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.rc new file mode 100644 index 0000000..a650233 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.rc @@ -0,0 +1,2 @@ +[testoptions] +max_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.txt new file mode 100644 index 0000000..ad714cc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call.txt @@ -0,0 +1,3 @@ +bad-str-strip-call:7::Suspicious argument in unicode.strip call +bad-str-strip-call:8::Suspicious argument in unicode.lstrip call +bad-str-strip-call:9::Suspicious argument in str.rstrip call diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.py new file mode 100644 index 0000000..e859f25 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.py @@ -0,0 +1,9 @@ +"""Suspicious str.strip calls.""" +__revision__ = 1 + +''.strip('yo') +''.strip() + +u''.strip('http://') # [bad-str-strip-call] +u''.lstrip('http://') # [bad-str-strip-call] +b''.rstrip('http://') # [bad-str-strip-call] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.txt new file mode 100644 index 0000000..81f32cf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/suspicious_str_strip_call_py3.txt @@ -0,0 +1,3 @@ +bad-str-strip-call:7::Suspicious argument in str.strip call +bad-str-strip-call:8::Suspicious argument in str.lstrip call +bad-str-strip-call:9::Suspicious argument in bytes.rstrip call diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.py new file mode 100644 index 0000000..c93df6b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.py @@ -0,0 +1 @@ +def toto # [syntax-error] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.rc new file mode 100644 index 0000000..58b5a94 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.rc @@ -0,0 +1 @@ +[testoptions] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.txt new file mode 100644 index 0000000..f14ae39 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error.txt @@ -0,0 +1 @@ +syntax-error:1::invalid syntax (<unknown>, line 1) \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.py new file mode 100644 index 0000000..c93df6b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.py @@ -0,0 +1 @@ +def toto # [syntax-error] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.rc new file mode 100644 index 0000000..29bd3fa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.rc @@ -0,0 +1,2 @@ +[testoptions] +except_implementations=CPython, PyPy diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.txt new file mode 100644 index 0000000..e532aec --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/syntax_error_jython.txt @@ -0,0 +1 @@ +syntax-error:1::"mismatched input '\n\n\n\n' expecting LPAREN" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.py new file mode 100644 index 0000000..c039185 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.py @@ -0,0 +1,7 @@ +'''Regression for issue https://github.com/PyCQA/pylint/issues/1004''' +# pylint: disable=missing-docstring, pointless-statement + +import sys +sys.__stdout__.buffer.write('test') +sys.__stdout__.buff # [no-member] +sys.__stdout__.buffer.write1 # [no-member] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.rc new file mode 100644 index 0000000..182fae8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.5 +except_implementations=PyPy \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.txt new file mode 100644 index 0000000..b68af46 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/sys_stream_regression_1004.txt @@ -0,0 +1,2 @@ +no-member:6::Instance of 'TextIOWrapper' has no 'buff' member:INFERENCE +no-member:7::Instance of 'BufferedWriter' has no 'write1' member; maybe 'write'?:INFERENCE \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ternary.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ternary.py new file mode 100644 index 0000000..835eb73 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ternary.py @@ -0,0 +1,33 @@ +"""Test for old tenrary constructs""" +from UNINFERABLE import condition, true_value, false_value, some_callable # pylint: disable=import-error + +SOME_VALUE1 = true_value if condition else false_value +SOME_VALUE2 = condition and true_value or false_value # [consider-using-ternary] +SOME_VALUE3 = condition + +def func1(): + """Ternary return value correct""" + return true_value if condition else false_value + + +def func2(): + """Ternary return value incorrect""" + return condition and true_value or false_value # [consider-using-ternary] + + +SOME_VALUE4 = some_callable(condition) and 'ERROR' or 'SUCCESS' # [consider-using-ternary] +SOME_VALUE5 = SOME_VALUE1 > 3 and 'greater' or 'not greater' # [consider-using-ternary] +SOME_VALUE6 = (SOME_VALUE2 > 4 and SOME_VALUE3) and 'both' or 'not' # [consider-using-ternary] +SOME_VALUE7 = 'both' if (SOME_VALUE2 > 4) and (SOME_VALUE3) else 'not' +SOME_VALUE8 = SOME_VALUE1 and SOME_VALUE2 and SOME_VALUE3 or SOME_VALUE4 +SOME_VALUE9 = SOME_VALUE1 and False or SOME_VALUE2 # [simplify-boolean-expression] + +YEAR = 1992 +# Cannot be simplified with a ternary. +IS_LEAP_YEAR = YEAR % 4 == 0 and YEAR % 100 != 0 or YEAR % 400 == 0 + + +def func4(): + """"Using a Name as a condition but still emits""" + truth_value = 42 + return condition and truth_value or false_value # [consider-using-ternary] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ternary.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ternary.txt new file mode 100644 index 0000000..0008e16 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ternary.txt @@ -0,0 +1,7 @@ +consider-using-ternary:5::Consider using ternary (true_value if condition else false_value):HIGH +consider-using-ternary:15:func2:Consider using ternary (true_value if condition else false_value):HIGH +consider-using-ternary:18::Consider using ternary ('ERROR' if some_callable(condition) else 'SUCCESS'):HIGH +consider-using-ternary:19::Consider using ternary ('greater' if SOME_VALUE1 > 3 else 'not greater'):HIGH +consider-using-ternary:20::Consider using ternary ('both' if SOME_VALUE2 > 4 and SOME_VALUE3 else 'not'):HIGH +simplify-boolean-expression:23::Boolean expression may be simplified to SOME_VALUE2:HIGH +consider-using-ternary:33:func4:Consider using ternary (truth_value if condition else false_value):HIGH diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/test_compile.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/test_compile.py new file mode 100644 index 0000000..d4a4ac2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/test_compile.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring, unused-variable, pointless-statement, too-few-public-methods, useless-object-inheritance + +class WrapperClass(object): + def method(self): + var = +4294967296 + self.method.__code__.co_consts diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.py new file mode 100644 index 0000000..323950d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.py @@ -0,0 +1,6 @@ +"""A module that is accepted by Python but rejected by tokenize. + +The problem is the trailing line continuation at the end of the line, +which produces a TokenError.""" +# +2: [syntax-error] +""\ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.rc new file mode 100644 index 0000000..58b5a94 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.rc @@ -0,0 +1 @@ +[testoptions] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.txt new file mode 100644 index 0000000..4e65f71 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error.txt @@ -0,0 +1 @@ +syntax-error:7::EOF in multi-line statement diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.py new file mode 100644 index 0000000..205f5fc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.py @@ -0,0 +1,7 @@ +# [syntax-error] +"""A module that is accepted by Python but rejected by tokenize. + +The problem is the trailing line continuation at the end of the line, +which produces a TokenError.""" + +""\ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.rc new file mode 100644 index 0000000..79ffac0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.rc @@ -0,0 +1,2 @@ +[testoptions] +except_implementations=CPython,PyPy,IronPython \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.txt new file mode 100644 index 0000000..82e662e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/tokenize_error_jython.txt @@ -0,0 +1 @@ +syntax-error:1::unexpected character after line continuation character \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods.py new file mode 100644 index 0000000..0b30035 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods.py @@ -0,0 +1,50 @@ +# pylint: disable=missing-docstring, useless-object-inheritance +from __future__ import print_function + + +from enum import Enum + + +class Aaaa(object): # [too-few-public-methods] + + def __init__(self): + pass + + def meth1(self): + print(self) + + def _dontcount(self): + print(self) + + +# Don't emit for these cases. +class Klass(object): + """docstring""" + + def meth1(self): + """first""" + + def meth2(self): + """second""" + + +class EnoughPublicMethods(Klass): + """We shouldn't emit too-few-public-methods for this.""" + + +class BossMonster(Enum): + """An enum does not need methods to be useful.""" + megashark = 1 + octopus = 2 + + +class DumbList: + """A class can define only special methods.""" + def __init__(self, iterable): + self._list = list(iterable) + + def __len__(self): + return len(self._list) + + def __getitem__(self, index): + return self._list[index] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods.txt new file mode 100644 index 0000000..79362d1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods.txt @@ -0,0 +1 @@ +too-few-public-methods:8:Aaaa:Too few public methods (1/2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.py new file mode 100644 index 0000000..0bb3a3c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.py @@ -0,0 +1,24 @@ +# pylint: disable=missing-docstring +import typing +import dataclasses +from dataclasses import dataclass + + +@dataclasses.dataclass +class ScheduledTxSearchModel: + date_from = None + date_to = None + + +@dataclass +class ScheduledTxSearchModelOne: + date = None + + +@dataclass(frozen=True) +class Test: + some_integer: int + + +class Example(typing.NamedTuple): + some_int: int diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.rc new file mode 100644 index 0000000..5d05724 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_few_public_methods_37.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_ancestors.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_ancestors.py new file mode 100644 index 0000000..a0ae18a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_ancestors.py @@ -0,0 +1,24 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance + +class Aaaa(object): + pass +class Bbbb(object): + pass +class Cccc(object): + pass +class Dddd(object): + pass +class Eeee(object): + pass +class Ffff(object): + pass +class Gggg(object): + pass +class Hhhh(object): + pass + +class Iiii(Aaaa, Bbbb, Cccc, Dddd, Eeee, Ffff, Gggg, Hhhh): # [too-many-ancestors] + pass + +class Jjjj(Iiii): # [too-many-ancestors] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_ancestors.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_ancestors.txt new file mode 100644 index 0000000..e9f0841 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_ancestors.txt @@ -0,0 +1,2 @@ +too-many-ancestors:20:Iiii:Too many ancestors (9/7) +too-many-ancestors:23:Jjjj:Too many ancestors (10/7) \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments.py new file mode 100644 index 0000000..71015ab --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments.py @@ -0,0 +1,17 @@ +# pylint: disable=missing-docstring + +def stupid_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9): # [too-many-arguments] + return arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + + +class MyClass: + text = "MyText" + + def mymethod1(self): + return self.text + + def mymethod2(self): + return self.mymethod1.__get__(self, MyClass) + + +MyClass().mymethod2()() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments.txt new file mode 100644 index 0000000..8f99a46 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments.txt @@ -0,0 +1 @@ +too-many-arguments:3:stupid_function:Too many arguments (9/5) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.py new file mode 100644 index 0000000..e5aa76d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.py @@ -0,0 +1,13 @@ +# pylint: disable=missing-docstring + +# pylint: disable=unused-import, undefined-variable; false positives :-( + +import functools + + +@functools.lru_cache() +def func(): + pass + + +func.cache_clear() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.rc new file mode 100644 index 0000000..46032f6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.2 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_arguments_issue_1045.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_boolean_expressions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_boolean_expressions.py new file mode 100644 index 0000000..68214ab --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_boolean_expressions.py @@ -0,0 +1,20 @@ +"""Checks for if statements containing too many boolean expressions""" + +# pylint: disable=invalid-name, comparison-with-itself, chained-comparison + +x = y = z = 5 +if x > -5 and x < 5 and y > -5 and y < 5 and z > -5 and z < 5: # [too-many-boolean-expressions] + pass +elif True and False and 1 and 2 and 3: + pass +elif True and False and 1 and 2 and 3 and 4 and 5: # [too-many-boolean-expressions] + pass +elif True and (True and True) and (x == 5 or True or True): # [too-many-boolean-expressions] + pass +elif True and (True or (x > -5 and x < 5 and (z > -5 or z < 5))): # [too-many-boolean-expressions] + pass +elif True == True == True == True == True == True: + pass + +if True and False and 1 and 2 and 3: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_boolean_expressions.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_boolean_expressions.txt new file mode 100644 index 0000000..0bb0086 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_boolean_expressions.txt @@ -0,0 +1,4 @@ +too-many-boolean-expressions:6::Too many boolean expressions in if statement (6/5) +too-many-boolean-expressions:10::Too many boolean expressions in if statement (7/5) +too-many-boolean-expressions:12::Too many boolean expressions in if statement (6/5) +too-many-boolean-expressions:14::Too many boolean expressions in if statement (6/5) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_branches.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_branches.py new file mode 100644 index 0000000..023d8ee --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_branches.py @@ -0,0 +1,69 @@ +""" Test for too many branches. """ +# pylint: disable=using-constant-test +def wrong(): # [too-many-branches] + """ Has too many branches. """ + if 1: + pass + elif 1: + pass + elif 1: + pass + elif 1: + pass + elif 1: + pass + elif 1: + pass + try: + pass + finally: + pass + if 2: + pass + while True: + pass + if 1: + pass + elif 2: + pass + elif 3: + pass + +def good(): + """ Too many branches only if we take + into consideration the nested functions. + """ + def nested_1(): + """ empty """ + if 1: + pass + elif 2: + pass + elif 3: + pass + elif 4: + pass + + nested_1() + try: + pass + finally: + pass + try: + pass + finally: + pass + if 1: + pass + elif 2: + pass + elif 3: + pass + elif 4: + pass + elif 5: + pass + elif 6: + pass + elif 7: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_branches.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_branches.txt new file mode 100644 index 0000000..fbc82cc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_branches.txt @@ -0,0 +1 @@ +too-many-branches:3:wrong:Too many branches (13/12) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_instance_attributes.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_instance_attributes.py new file mode 100644 index 0000000..f6703e0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_instance_attributes.py @@ -0,0 +1,26 @@ +# pylint: disable=missing-docstring, too-few-public-methods, useless-object-inheritance + +class Aaaa(object): # [too-many-instance-attributes] + + def __init__(self): + self.aaaa = 1 + self.bbbb = 2 + self.cccc = 3 + self.dddd = 4 + self.eeee = 5 + self.ffff = 6 + self.gggg = 7 + self.hhhh = 8 + self.iiii = 9 + self.jjjj = 10 + self._aaaa = 1 + self._bbbb = 2 + self._cccc = 3 + self._dddd = 4 + self._eeee = 5 + self._ffff = 6 + self._gggg = 7 + self._hhhh = 8 + self._iiii = 9 + self._jjjj = 10 + self.tomuch = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_instance_attributes.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_instance_attributes.txt new file mode 100644 index 0000000..652ccea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_instance_attributes.txt @@ -0,0 +1 @@ +too-many-instance-attributes:3:Aaaa:Too many instance attributes (21/7) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines.py new file mode 100644 index 0000000..78e568c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines.py @@ -0,0 +1,1015 @@ +# pylint: disable=missing-docstring +# -1: [too-many-lines] +__revision__ = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ZERFZAER = 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +HEHEHE = 2 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines.txt new file mode 100644 index 0000000..0374f0c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines.txt @@ -0,0 +1 @@ +too-many-lines:1::Too many lines in module (1015/1000) \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines_disabled.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines_disabled.py new file mode 100644 index 0000000..1b0866d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_lines_disabled.py @@ -0,0 +1,1018 @@ +"""Test that disabling too-many-lines on any line works.""" + + + +# pylint: disable=too-many-lines +__revision__ = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ZERFZAER = 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +HEHEHE = 2 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_locals.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_locals.py new file mode 100644 index 0000000..ac38a9e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_locals.py @@ -0,0 +1,60 @@ +# pylint: disable=missing-docstring +from __future__ import print_function + +def function(arg1, arg2, arg3, arg4, arg5): # [too-many-locals] + arg6, arg7, arg8, arg9 = arg1, arg2, arg3, arg4 + print(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) + loc1, loc2, loc3, loc4, loc5, loc6, loc7 = arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 + print(loc1, loc2, loc3, loc4, loc5, loc6, loc7) + + +def too_many_locals_function(): # [too-many-locals] + """pylint will complains about too many local variables""" + args0 = 0 + args1 = args0 * 1 + args2 = args1 * 2 + args3 = args2 * 3 + args4 = args3 * 4 + args5 = args4 * 5 + args6 = args5 * 6 + args7 = args6 * 7 + args8 = args7 * 8 + args9 = args8 * 9 + args10 = args9 * 10 + args11 = args10 * 11 + args12 = args11 * 12 + args13 = args12 * 13 + args14 = args13 * 14 + args15 = args14 * 15 + return args15 + +def too_many_arguments_function(arga, argu, argi, arge, argt, args): # [too-many-arguments] + """pylint will complains about too many arguments.""" + arga = argu + arga += argi + arga += arge + arga += argt + arga += args + return arga + +def ignored_arguments_function(arga, argu, argi, + _arge=0, _argt=1, _args=None): + """pylint will ignore _arge, _argt, _args. + + Consequently pylint will only coun 13 arguments. + """ + arg0 = 0 + arg1 = arg0 * 1 + arga + arg2 = arg1 * 2 + argu + arg3 = arg2 * 3 + argi + arg4 = arg3 * 4 + _arge + arg5 = arg4 * 5 + _argt + arg6 = arg5 * 6 + arg7 = arg6 * 7 + arg8 = arg7 * 8 + arg9 = arg8 * 9 + arg9 += arg0 + if _args: + arg9 += sum(_args) + return arg9 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_locals.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_locals.txt new file mode 100644 index 0000000..cce2332 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_locals.txt @@ -0,0 +1,3 @@ +too-many-locals:4:function:Too many local variables (16/15) +too-many-locals:12:too_many_locals_function:Too many local variables (16/15) +too-many-arguments:32:too_many_arguments_function:Too many arguments (6/5) \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_nested_blocks.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_nested_blocks.py new file mode 100644 index 0000000..e7c0079 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_nested_blocks.py @@ -0,0 +1,97 @@ +"""Checks the maximum block level is smaller than 6 in function definitions""" + +#pylint: disable=using-constant-test, missing-docstring, too-many-return-statements,no-else-return + +def my_function(): + if 1: # [too-many-nested-blocks] + for i in range(10): + if i == 2: + while True: + try: + if True: + i += 1 + except IOError: + pass + + if 1: + for i in range(10): + if i == 2: + while True: + try: + i += 1 + except IOError: + pass + + def nested_func(): + if True: + for i in range(10): + while True: + if True: + if True: + yield i + + nested_func() + +def more_complex_function(): + attr1 = attr2 = attr3 = [1, 2, 3] + if attr1: + for i in attr1: + if attr2: + return i + else: + return 'duh' + elif attr2: + for i in attr2: + if attr2: + return i + else: + return 'duh' + else: + for i in range(15): + if attr3: + return i + else: + return 'doh' + return None + +def elif_function(): + arg = None + if arg == 1: + return 1 + elif arg == 2: + return 2 + elif arg == 3: + return 3 + elif arg == 4: + return 4 + elif arg == 5: + return 5 + elif arg == 6: + return 6 + elif arg == 7: + return 7 + return None + +def else_if_function(): + arg = None + if arg == 1: # [too-many-nested-blocks] + return 1 + else: + if arg == 2: + return 2 + else: + if arg == 3: + return 3 + else: + if arg == 4: + return 4 + else: + if arg == 5: + return 5 + else: + if arg == 6: + return 6 + else: + if arg == 7: + return 7 + return None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_nested_blocks.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_nested_blocks.txt new file mode 100644 index 0000000..b2a30fd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_nested_blocks.txt @@ -0,0 +1,2 @@ +too-many-nested-blocks:6:my_function:Too many nested blocks (6/5) +too-many-nested-blocks:77:else_if_function:Too many nested blocks (7/5) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_public_methods.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_public_methods.py new file mode 100644 index 0000000..11b4b36 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_public_methods.py @@ -0,0 +1,79 @@ +# pylint: disable=missing-docstring, useless-object-inheritance + +class Aaaa(object): # [too-many-public-methods] + + def __init__(self): + pass + + def meth1(self): + """hehehe""" + + def meth2(self): + """hehehe""" + + def meth3(self): + """hehehe""" + + def meth4(self): + """hehehe""" + + def meth5(self): + """hehehe""" + + def meth6(self): + """hehehe""" + + def meth7(self): + """hehehe""" + + def meth8(self): + """hehehe""" + + def meth9(self): + """hehehe""" + + def meth10(self): + """hehehe""" + + def meth11(self): + """hehehe""" + + def meth12(self): + """hehehe""" + + def meth13(self): + """hehehe""" + + def meth14(self): + """hehehe""" + + def meth15(self): + """hehehe""" + + def meth16(self): + """hehehe""" + + def meth17(self): + """hehehe""" + + def meth18(self): + """hehehe""" + + def meth19(self): + """hehehe""" + + def meth20(self): + """hehehe""" + + def meth21(self): + """hehehe""" + + def _dontcount(self): + """not public""" + +class BBB(Aaaa): + """Don't emit for methods defined in the parent.""" + def meth1(self): + """trop""" + def meth2(self): + """tzop""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_public_methods.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_public_methods.txt new file mode 100644 index 0000000..1b5a250 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_public_methods.txt @@ -0,0 +1 @@ +too-many-public-methods:3:Aaaa:Too many public methods (21/20) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_return_statements.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_return_statements.py new file mode 100644 index 0000000..66a85da --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_return_statements.py @@ -0,0 +1,40 @@ +# pylint: disable=missing-docstring + +def stupid_function(arg): # [too-many-return-statements] + if arg == 1: + return 1 + if arg == 2: + return 2 + if arg == 3: + return 3 + if arg == 4: + return 4 + if arg == 5: + return 5 + if arg == 6: + return 6 + if arg == 7: + return 7 + if arg == 8: + return 8 + if arg == 9: + return 9 + if arg == 10: + return 10 + return None + + +def many_yield(text): + """Not a problem""" + if text: + yield " line 1: %s\n" % text + yield " line 2\n" + yield " line 3\n" + yield " line 4\n" + yield " line 5\n" + else: + yield " line 6\n" + yield " line 7\n" + yield " line 8\n" + yield " line 9\n" + yield " line 10\n" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_return_statements.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_return_statements.txt new file mode 100644 index 0000000..4f65db2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_return_statements.txt @@ -0,0 +1 @@ +too-many-return-statements:3:stupid_function:Too many return statements (11/6) \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.py new file mode 100644 index 0000000..4721d3f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.py @@ -0,0 +1,7 @@ +"""Test for too-many-star-expressions.""" +# pylint: disable=unbalanced-tuple-unpacking +*FIRST, *SECOND = [1, 2, 3] # [too-many-star-expressions] +(FIRST, *SECOND), *THIRD = ((1, 2, 3), 4, 5) +*FIRST_1, SECOND = (1, 2, 3) +(*FIRST, *SECOND), THIRD = [...] # [too-many-star-expressions] +((*FIRST, SECOND), *THIRD), *FOURTH = [...] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.txt new file mode 100644 index 0000000..97af352 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_star_expressions.txt @@ -0,0 +1,2 @@ +too-many-star-expressions:3::More than one starred expression in assignment +too-many-star-expressions:6::More than one starred expression in assignment diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_statements.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_statements.py new file mode 100644 index 0000000..b3e2fd7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_statements.py @@ -0,0 +1,125 @@ +# pylint: disable=missing-docstring + +from __future__ import print_function + +def stupid_function(arg): # [too-many-statements] + if arg == 1: + print(1) + elif arg == 2: + print(1) + elif arg == 3: + print(1) + elif arg == 4: + print(1) + elif arg == 5: + print(1) + elif arg == 6: + print(1) + elif arg == 7: + print(1) + elif arg == 8: + print(1) + elif arg == 9: + print(1) + elif arg == 10: + print(1) + elif arg < 1: + print(1) + print(1) + arg = 0 + for _ in range(arg): + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + print(1) + +def long_function_with_inline_def(fake): # [too-many-statements] + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + def an_inline_function(var): + return var + var + fake = an_inline_function(fake) + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 + fake += 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_statements.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_statements.txt new file mode 100644 index 0000000..9a8abfc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/too_many_statements.txt @@ -0,0 +1,2 @@ +too-many-statements:5:stupid_function:Too many statements (55/50) +too-many-statements:62:long_function_with_inline_def:Too many statements (62/50) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.py new file mode 100644 index 0000000..a832ccc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.py @@ -0,0 +1,38 @@ +"""Check trailing comma one element tuples.""" +# pylint: disable=bad-whitespace, missing-docstring +AAA = 1, # [trailing-comma-tuple] +BBB = "aaaa", # [trailing-comma-tuple] +CCC="aaa", # [trailing-comma-tuple] +FFF=['f'], # [trailing-comma-tuple] + +BBB = 1, 2 +CCC = (1, 2, 3) +DDD = ( + 1, 2, 3, +) +EEE = ( + "aaa", +) + + +def test(*args, **kwargs): + return args, kwargs + + +test(widget=1, label='test') +test(widget=1, + label='test') +test(widget=1, \ + label='test') + + +def some_func(first, second): + if first: + return first, # [trailing-comma-tuple] + if second: + return (first, second,) + return first, second, # [trailing-comma-tuple] + + +def some_other_func(): + yield 'hello', # [trailing-comma-tuple] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.txt new file mode 100644 index 0000000..bdf53a2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_comma_tuple.txt @@ -0,0 +1,7 @@ +trailing-comma-tuple:3::Disallow trailing comma tuple +trailing-comma-tuple:4::Disallow trailing comma tuple +trailing-comma-tuple:5::Disallow trailing comma tuple +trailing-comma-tuple:6::Disallow trailing comma tuple +trailing-comma-tuple:31::Disallow trailing comma tuple +trailing-comma-tuple:34::Disallow trailing comma tuple +trailing-comma-tuple:38::Disallow trailing comma tuple diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_newlines.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_newlines.py new file mode 100644 index 0000000..8fbadbb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_newlines.py @@ -0,0 +1,3 @@ +"""Regression test for trailing-newlines (C0304).""" +# +1: [trailing-newlines] + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_newlines.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_newlines.txt new file mode 100644 index 0000000..254f49d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_newlines.txt @@ -0,0 +1 @@ +trailing-newlines:3::Trailing newlines diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_whitespaces.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_whitespaces.py new file mode 100644 index 0000000..0e7a116 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_whitespaces.py @@ -0,0 +1,11 @@ +"""Regression test for trailing-whitespace (C0303).""" +# pylint: disable=mixed-line-endings +from __future__ import print_function + +# +1: [trailing-whitespace] +print('some trailing whitespace') +# +1: [trailing-whitespace] +print('trailing whitespace does not count towards the line length limit') +print('windows line ends are ok') +# +1: [trailing-whitespace] +print('but trailing whitespace on win is not') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_whitespaces.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_whitespaces.txt new file mode 100644 index 0000000..38fc2c3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/trailing_whitespaces.txt @@ -0,0 +1,3 @@ +trailing-whitespace:6::Trailing whitespace +trailing-whitespace:8::Trailing whitespace +trailing-whitespace:11::Trailing whitespace diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/try_except_raise.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/try_except_raise.py new file mode 100644 index 0000000..2a9bed7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/try_except_raise.py @@ -0,0 +1,120 @@ +# pylint:disable=missing-docstring, unreachable, bad-except-order, bare-except, unnecessary-pass +# pylint: disable=undefined-variable, broad-except +try: + int("9a") +except: # [try-except-raise] + raise + +try: + int("9a") +except: + raise ValueError('Invalid integer') + + +try: + int("9a") +except: # [try-except-raise] + raise + print('caught exception') + +try: + int("9a") +except: + print('caught exception') + raise + + +class AAAException(Exception): + """AAAException""" + pass + +class BBBException(AAAException): + """BBBException""" + pass + +def ccc(): + """try-except-raise test function""" + + try: + raise BBBException("asdf") + except BBBException: + raise + except AAAException: + raise BBBException("raised from AAAException") + + +def ddd(): + """try-except-raise test function""" + + try: + raise BBBException("asdf") + except AAAException: + raise BBBException("raised from AAAException") + except: # [try-except-raise] + raise + +try: + pass +except RuntimeError: + raise +except: + print("a failure") + +try: + pass +except: + print("a failure") +except RuntimeError: # [try-except-raise] + raise + +try: + pass +except: # [try-except-raise] + raise +except RuntimeError: + print("a failure") + +try: + pass +except (FileNotFoundError, PermissionError): + raise +except OSError: + print("a failure") + +# also consider tuples for subsequent exception handler instead of just bare except handler +try: + pass +except (FileNotFoundError, PermissionError): + raise +except (OverflowError, OSError): + print("a failure") + +try: + pass +except (FileNotFoundError, PermissionError): # [try-except-raise] + raise +except (OverflowError, ZeroDivisionError): + print("a failure") + + +try: + pass +except invalid_name: # [try-except-raise] + raise +except TypeError: + pass + +try: + pass +except (FileNotFoundError, PermissionError): + raise +except Exception: + print("a failure") + +try: + pass +except (FileNotFoundError, PermissionError): + raise +except (Exception,): + print("a failure") + \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/try_except_raise.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/try_except_raise.txt new file mode 100644 index 0000000..ccf8f11 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/try_except_raise.txt @@ -0,0 +1,7 @@ +try-except-raise:5::The except handler raises immediately +try-except-raise:16::The except handler raises immediately +try-except-raise:53:ddd:The except handler raises immediately +try-except-raise:67::The except handler raises immediately +try-except-raise:72::The except handler raises immediately +try-except-raise:94::The except handler raises immediately +try-except-raise:102::The except handler raises immediately diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.py new file mode 100644 index 0000000..afa217f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.py @@ -0,0 +1,108 @@ +"""Check possible unbalanced tuple unpacking """ +from __future__ import absolute_import +from functional.unpacking import unpack + +# pylint: disable=using-constant-test, useless-object-inheritance + +def do_stuff(): + """This is not right.""" + first, second = 1, 2, 3 # [unbalanced-tuple-unpacking] + return first + second + +def do_stuff1(): + """This is not right.""" + first, second = [1, 2, 3] # [unbalanced-tuple-unpacking] + return first + second + +def do_stuff2(): + """This is not right.""" + (first, second) = 1, 2, 3 # [unbalanced-tuple-unpacking] + return first + second + +def do_stuff3(): + """This is not right.""" + first, second = range(100) + return first + second + +def do_stuff4(): + """ This is right """ + first, second = 1, 2 + return first + second + +def do_stuff5(): + """ This is also right """ + first, second = (1, 2) + return first + second + +def do_stuff6(): + """ This is right """ + (first, second) = (1, 2) + return first + second + +def temp(): + """ This is not weird """ + if True: + return [1, 2] + return [2, 3, 4] + +def do_stuff7(): + """ This is not right, but we're not sure """ + first, second = temp() + return first + second + +def temp2(): + """ This is weird, but correct """ + if True: + return (1, 2) + + if True: + return (2, 3) + return (4, 5) + +def do_stuff8(): + """ This is correct """ + first, second = temp2() + return first + second + +def do_stuff9(): + """ This is not correct """ + first, second = unpack() # [unbalanced-tuple-unpacking] + return first + second + +class UnbalancedUnpacking(object): + """ Test unbalanced tuple unpacking in instance attributes. """ + # pylint: disable=attribute-defined-outside-init, invalid-name, too-few-public-methods + def test(self): + """ unpacking in instance attributes """ + # we're not sure if temp() returns two or three values + # so we shouldn't emit an error + self.a, self.b = temp() + self.a, self.b = temp2() + self.a, self.b = unpack() # [unbalanced-tuple-unpacking] + + +def issue329(*args): + """ Don't emit unbalanced tuple unpacking if the + rhs of the assignment is a variable-length argument, + because we don't know the actual length of the tuple. + """ + first, second, third = args + return first, second, third + + +def test_decimal(): + """Test a false positive with decimal.Decimal.as_tuple + + See astroid https://bitbucket.org/logilab/astroid/issues/92/ + """ + from decimal import Decimal + dec = Decimal(2) + first, second, third = dec.as_tuple() + return first, second, third + + +def test_issue_559(): + """Test that we don't have a false positive wrt to issue #559.""" + from ctypes import c_int + root_x, root_y, win_x, win_y = [c_int()] * 4 + return root_x, root_y, win_x, win_y diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.txt new file mode 100644 index 0000000..e904209 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking.txt @@ -0,0 +1,6 @@ +unbalanced-tuple-unpacking:9:do_stuff:"Possible unbalanced tuple unpacking with sequence (1, 2, 3): left side has 2 label(s), right side has 3 value(s)" +unbalanced-tuple-unpacking:14:do_stuff1:"Possible unbalanced tuple unpacking with sequence [1, 2, 3]: left side has 2 label(s), right side has 3 value(s)" +unbalanced-tuple-unpacking:19:do_stuff2:"Possible unbalanced tuple unpacking with sequence (1, 2, 3): left side has 2 label(s), right side has 3 value(s)" +unbalanced-tuple-unpacking:24:do_stuff3:"Possible unbalanced tuple unpacking with sequence (1, 2, 3): left side has 2 label(s), right side has 3 value(s)" +unbalanced-tuple-unpacking:69:do_stuff9:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.unpacking: left side has 2 label(s), right side has 3 value(s)" +unbalanced-tuple-unpacking:81:UnbalancedUnpacking.test:"Possible unbalanced tuple unpacking with sequence defined at line 7 of functional.unpacking: left side has 2 label(s), right side has 3 value(s)" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.py new file mode 100644 index 0000000..68f5fb7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.py @@ -0,0 +1,11 @@ +""" Test that using starred nodes in unpacking +does not trigger a false positive on Python 3. +""" + +__revision__ = 1 + +def test(): + """ Test that starred expressions don't give false positives. """ + first, second, *last = (1, 2, 3, 4) + *last, = (1, 2) + return (first, second, last) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.rc new file mode 100644 index 0000000..a2ab06c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unbalanced_tuple_unpacking_py30.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_loop_variable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_loop_variable.py new file mode 100644 index 0000000..a984898 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_loop_variable.py @@ -0,0 +1,75 @@ +# pylint: disable=missing-docstring,redefined-builtin + +def do_stuff(some_random_list): + for var in some_random_list: + pass + return var # [undefined-loop-variable] + + +def do_else(some_random_list): + for var in some_random_list: + if var == 42: + break + else: + var = 84 + return var + +__revision__ = 'yo' + +TEST_LC = [C for C in __revision__ if C.isalpha()] +B = [B for B in __revision__ if B.isalpha()] +VAR2 = B # nor this one + +for var1, var2 in TEST_LC: + var1 = var2 + 4 +VAR3 = var1 # [undefined-loop-variable] + +for note in __revision__: + note.something() +for line in __revision__: + for note in line: + A = note.anotherthing() + + +for x in []: + pass +for x in range(3): + VAR5 = (lambda: x)() + + +def do_stuff_with_a_list(): + for var in [1, 2, 3]: + pass + return var + + +def do_stuff_with_a_set(): + for var in {1, 2, 3}: + pass + return var + + +def do_stuff_with_a_dict(): + for var in {1: 2, 3: 4}: + pass + return var + + +def do_stuff_with_a_tuple(): + for var in (1, 2, 3): + pass + return var + + +def do_stuff_with_a_range(): + for var in range(1, 2): + pass + return var + + +def do_stuff_with_redefined_range(): + def range(key): + yield from [1, key] + for var in range(3): + pass + return var # [undefined-loop-variable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_loop_variable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_loop_variable.txt new file mode 100644 index 0000000..64cf638 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_loop_variable.txt @@ -0,0 +1,3 @@ +undefined-loop-variable:6:do_stuff:Using possibly undefined loop variable 'var' +undefined-loop-variable:25::Using possibly undefined loop variable 'var1' +undefined-loop-variable:75:do_stuff_with_redefined_range:Using possibly undefined loop variable 'var' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable.py new file mode 100644 index 0000000..59af47e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable.py @@ -0,0 +1,247 @@ +# pylint: disable=missing-docstring, multiple-statements, useless-object-inheritance +# pylint: disable=too-few-public-methods, no-init, no-self-use,bare-except,broad-except, import-error +from __future__ import print_function +DEFINED = 1 + +if DEFINED != 1: + if DEFINED in (unknown, DEFINED): # [undefined-variable] + DEFINED += 1 + + +def in_method(var): + """method doc""" + var = nomoreknown # [undefined-variable] + assert var + +DEFINED = {DEFINED:__revision__} # [undefined-variable] +# +1:[undefined-variable] +DEFINED[__revision__] = OTHER = 'move this is astroid test' + +OTHER += '$' + +def bad_default(var, default=unknown2): # [undefined-variable] + """function with defaut arg's value set to an unexistant name""" + print(var, default) + print(xxxx) # [undefined-variable] + augvar += 1 # [undefined-variable] + del vardel # [undefined-variable] + +LMBD = lambda x, y=doesnotexist: x+y # [undefined-variable] +LMBD2 = lambda x, y: x+z # [undefined-variable] + +try: + POUET # don't catch me +except NameError: + POUET = 'something' + +try: + POUETT # [used-before-assignment] +except Exception: # pylint:disable = broad-except + POUETT = 'something' + +try: + POUETTT # don't catch me +except: # pylint:disable = bare-except + POUETTT = 'something' + +print(POUET, POUETT, POUETTT) + + +try: + PLOUF # [used-before-assignment] +except ValueError: + PLOUF = 'something' + +print(PLOUF) + +def if_branch_test(something): + """hop""" + if something == 0: + if xxx == 1: # [used-before-assignment] + pass + else: + print(xxx) + xxx = 3 + + +def decorator(arg): + """Decorator with one argument.""" + return lambda: list(arg) + + +@decorator(arg=[i * 2 for i in range(15)]) +def func1(): + """A function with a decorator that contains a listcomp.""" + +@decorator(arg=(i * 2 for i in range(15))) +def func2(): + """A function with a decorator that contains a genexpr.""" + +@decorator(lambda x: x > 0) +def main(): + """A function with a decorator that contains a lambda.""" + +# Test shared scope. + +def test_arguments(arg=TestClass): # [used-before-assignment] + """ TestClass isn't defined yet. """ + return arg + +class TestClass(Ancestor): # [used-before-assignment] + """ contains another class, which uses an undefined ancestor. """ + + class MissingAncestor(Ancestor1): # [used-before-assignment] + """ no op """ + + def test1(self): + """ It should trigger here, because the two classes + have the same scope. + """ + class UsingBeforeDefinition(Empty): # [used-before-assignment] + """ uses Empty before definition """ + class Empty(object): + """ no op """ + return UsingBeforeDefinition + + def test(self): + """ Ancestor isn't defined yet, but we don't care. """ + class MissingAncestor1(Ancestor): + """ no op """ + return MissingAncestor1 + +class Self(object): + """ Detect when using the same name inside the class scope. """ + obj = Self # [undefined-variable] + +class Self1(object): + """ No error should be raised here. """ + + def test(self): + """ empty """ + return Self1 + + +class Ancestor(object): + """ No op """ + +class Ancestor1(object): + """ No op """ + +NANA = BAT # [undefined-variable] +del BAT + + +class KeywordArgument(object): + """Test keyword arguments.""" + + enable = True + def test(self, is_enabled=enable): + """do nothing.""" + + def test1(self, is_enabled=enabled): # [used-before-assignment] + """enabled is undefined at this point, but it is used before assignment.""" + + def test2(self, is_disabled=disabled): # [undefined-variable] + """disabled is undefined""" + + enabled = True + + func = lambda arg=arg: arg * arg # [undefined-variable] + + arg2 = 0 + func2 = lambda arg2=arg2: arg2 * arg2 + +# Don't emit if the code is protected by NameError +try: + unicode_1 +except NameError: + pass + +try: + unicode_2 # [undefined-variable] +except Exception: + pass + +try: + unicode_3 +except: + pass + +try: + unicode_4 # [undefined-variable] +except ValueError: + pass + +# See https://bitbucket.org/logilab/pylint/issue/111/ +try: raise IOError(1, "a") +except IOError as err: print(err) + + +def test_conditional_comprehension(): + methods = ['a', 'b', '_c', '_d'] + my_methods = sum(1 for method in methods + if not method.startswith('_')) + return my_methods + + +class MyError(object): + pass + + +class MyClass(object): + class MyError(MyError): + pass + + +def dec(inp): + def inner(func): + print(inp) + return func + return inner + +# Make sure lambdas with expressions +# referencing parent class do not raise undefined variable +# because at the time of their calling, the class name will +# be populated +# See https://github.com/PyCQA/pylint/issues/704 +class LambdaClass: + myattr = 1 + mylambda = lambda: LambdaClass.myattr + +# Need different classes to make sure +# consumed variables don't get in the way +class LambdaClass2: + myattr = 1 + # Different base_scope scope but still applies + mylambda2 = lambda: [LambdaClass2.myattr for _ in [1, 2]] + +class LambdaClass3: + myattr = 1 + # Nested default argument in lambda + # Should not raise error + mylambda3 = lambda: lambda a=LambdaClass3: a + +class LambdaClass4: + myattr = 1 + mylambda4 = lambda a=LambdaClass4: lambda: a # [undefined-variable] + +# Make sure the first lambda does not consume the LambdaClass5 class +# name although the expression is is valid +# Consuming the class would cause the subsequent undefined-variable to be masked +class LambdaClass5: + myattr = 1 + mylambda = lambda: LambdaClass5.myattr + mylambda4 = lambda a=LambdaClass5: lambda: a # [undefined-variable] + + +def nonlocal_in_ifexp(): + import matplotlib.pyplot as plt + def onclick(event): + if event: + nonlocal i + i += 1 + print(i) + i = 0 + fig = plt.figure() + fig.canvas.mpl_connect('button_press_event', onclick) + plt.show(block=True) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable.txt new file mode 100644 index 0000000..bc935c1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable.txt @@ -0,0 +1,26 @@ +undefined-variable:7::Undefined variable 'unknown' +undefined-variable:13:in_method:Undefined variable 'nomoreknown' +undefined-variable:16::Undefined variable '__revision__' +undefined-variable:18::Undefined variable '__revision__' +undefined-variable:22:bad_default:Undefined variable 'unknown2' +undefined-variable:25:bad_default:Undefined variable 'xxxx' +undefined-variable:26:bad_default:Undefined variable 'augvar' +undefined-variable:27:bad_default:Undefined variable 'vardel' +undefined-variable:29:<lambda>:Undefined variable 'doesnotexist' +undefined-variable:30:<lambda>:Undefined variable 'z' +used-before-assignment:38::Using variable 'POUETT' before assignment +used-before-assignment:51::Using variable 'PLOUF' before assignment +used-before-assignment:60:if_branch_test:Using variable 'xxx' before assignment +used-before-assignment:86:test_arguments:Using variable 'TestClass' before assignment +used-before-assignment:90:TestClass:Using variable 'Ancestor' before assignment +used-before-assignment:93:TestClass.MissingAncestor:Using variable 'Ancestor1' before assignment +used-before-assignment:100:TestClass.test1.UsingBeforeDefinition:Using variable 'Empty' before assignment +undefined-variable:114:Self:Undefined variable 'Self' +undefined-variable:130::Undefined variable 'BAT' +used-before-assignment:141:KeywordArgument.test1:Using variable 'enabled' before assignment +undefined-variable:144:KeywordArgument.test2:Undefined variable 'disabled' +undefined-variable:149:KeywordArgument.<lambda>:Undefined variable 'arg' +undefined-variable:161::Undefined variable 'unicode_2' +undefined-variable:171::Undefined variable 'unicode_4' +undefined-variable:226:LambdaClass4.<lambda>:Undefined variable 'LambdaClass4' +undefined-variable:234:LambdaClass5.<lambda>:Undefined variable 'LambdaClass5' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.py new file mode 100644 index 0000000..3ccdfa6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.py @@ -0,0 +1,82 @@ +"""Test warnings about access to undefined variables +for various Python 3 constructs. """ +# pylint: disable=too-few-public-methods, no-init, no-self-use +# pylint: disable=wrong-import-position, invalid-metaclass, useless-object-inheritance +class Undefined: + """ test various annotation problems. """ + + def test(self)->Undefined: # [undefined-variable] + """ used Undefined, which is Undefined in this scope. """ + + Undefined = True + + def test1(self)->Undefined: + """ This Undefined exists at local scope. """ + + def test2(self): + """ This should not emit. """ + def func()->Undefined: + """ empty """ + return 2 + return func + + +class Undefined1: + """ Other annotation problems. """ + + Undef = 42 + ABC = 42 + + class InnerScope: + """ Test inner scope definition. """ + + def test_undefined(self)->Undef: # [undefined-variable] + """ Looking at a higher scope is impossible. """ + + def test1(self)->ABC: # [undefined-variable] + """ Triggers undefined-variable. """ + + +class FalsePositive342(object): + # pylint: disable=line-too-long + """ Fix some false positives found in + https://bitbucket.org/logilab/pylint/issue/342/spurious-undefined-variable-for-class + """ + + top = 42 + + def test_good(self, bac: top): + """ top is defined at this moment. """ + + def test_bad(self, bac: trop): # [undefined-variable] + """ trop is undefined at this moment. """ + + def test_bad1(self, *args: trop1): # [undefined-variable] + """ trop1 is undefined at this moment. """ + + def test_bad2(self, **bac: trop2): # [undefined-variable] + """ trop2 is undefined at this moment. """ + +from abc import ABCMeta + +class Bad(metaclass=ABCMet): # [undefined-variable] + """ Notice the typo """ + +class SecondBad(metaclass=ab.ABCMeta): # [undefined-variable] + """ Notice the `ab` module. """ + +class Good(metaclass=int): + """ int is not a proper metaclass, but it is defined. """ + +class SecondGood(metaclass=Good): + """ empty """ + +class ThirdGood(metaclass=ABCMeta): + """ empty """ + +class FourthGood(ThirdGood): + """ This should not trigger anything. """ + +# The following used to raise used-before-assignment +# pylint: disable=missing-docstring, multiple-statements +def used_before_assignment(*, arg): return arg + 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.txt new file mode 100644 index 0000000..61ae565 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/undefined_variable_py30.txt @@ -0,0 +1,8 @@ +undefined-variable:8:Undefined.test:Undefined variable 'Undefined' +undefined-variable:33:Undefined1.InnerScope.test_undefined:Undefined variable 'Undef' +undefined-variable:36:Undefined1.InnerScope.test1:Undefined variable 'ABC' +undefined-variable:51:FalsePositive342.test_bad:Undefined variable 'trop' +undefined-variable:54:FalsePositive342.test_bad1:Undefined variable 'trop1' +undefined-variable:57:FalsePositive342.test_bad2:Undefined variable 'trop2' +undefined-variable:62:Bad:Undefined variable 'ABCMet' +undefined-variable:65:SecondBad:Undefined variable 'ab.ABCMeta' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unexpected_special_method_signature.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unexpected_special_method_signature.py new file mode 100644 index 0000000..2a5036a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unexpected_special_method_signature.py @@ -0,0 +1,120 @@ +"""Test for special methods implemented incorrectly.""" + +# pylint: disable=missing-docstring, unused-argument, too-few-public-methods +# pylint: disable=invalid-name,too-many-arguments,bad-staticmethod-argument, useless-object-inheritance + +class Invalid(object): + + def __enter__(self, other): # [unexpected-special-method-signature] + pass + + def __del__(self, other): # [unexpected-special-method-signature] + pass + + def __format__(self, other, other2): # [unexpected-special-method-signature] + pass + + def __setattr__(self): # [unexpected-special-method-signature] + pass + + def __round__(self, invalid, args): # [unexpected-special-method-signature] + pass + + def __deepcopy__(self, memo, other): # [unexpected-special-method-signature] + pass + + def __iter__(): # [no-method-argument] + pass + + @staticmethod + def __getattr__(self, nanana): # [unexpected-special-method-signature] + pass + + +class FirstBadContextManager(object): + def __enter__(self): + return self + def __exit__(self, exc_type): # [unexpected-special-method-signature] + pass + +class SecondBadContextManager(object): + def __enter__(self): + return self + def __exit__(self, exc_type, value, tb, stack): # [unexpected-special-method-signature] + pass + +class ThirdBadContextManager(object): + def __enter__(self): + return self + + # +1: [unexpected-special-method-signature] + def __exit__(self, exc_type, value, tb, stack, *args): + pass + + +class Async(object): + + def __aiter__(self, extra): # [unexpected-special-method-signature] + pass + def __anext__(self, extra, argument): # [unexpected-special-method-signature] + pass + def __await__(self, param): # [unexpected-special-method-signature] + pass + def __aenter__(self, first): # [unexpected-special-method-signature] + pass + def __aexit__(self): # [unexpected-special-method-signature] + pass + + +class Valid(object): + + def __new__(cls, test, multiple, args): + pass + + def __init__(self, this, can, have, multiple, args, as_well): + pass + + def __call__(self, also, trv, for_this): + pass + + def __round__(self, n): + pass + + def __index__(self, n=42): + """Expects 0 args, but we are taking in account arguments with defaults.""" + + def __deepcopy__(self, memo): + pass + + def __format__(self, format_specification=''): + pass + + def __copy__(self, this=None, is_not=None, necessary=None): + pass + + @staticmethod + def __enter__(): + pass + + @staticmethod + def __getitem__(index): + pass + + +class FirstGoodContextManager(object): + def __enter__(self): + return self + def __exit__(self, exc_type, value, tb): + pass + +class SecondGoodContextManager(object): + def __enter__(self): + return self + def __exit__(self, exc_type=None, value=None, tb=None): + pass + +class ThirdGoodContextManager(object): + def __enter__(self): + return self + def __exit__(self, exc_type, *args): + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unexpected_special_method_signature.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unexpected_special_method_signature.txt new file mode 100644 index 0000000..4fb52df --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unexpected_special_method_signature.txt @@ -0,0 +1,16 @@ +unexpected-special-method-signature:8:Invalid.__enter__:The special method '__enter__' expects 0 param(s), 1 was given +unexpected-special-method-signature:11:Invalid.__del__:The special method '__del__' expects 0 param(s), 1 was given +unexpected-special-method-signature:14:Invalid.__format__:The special method '__format__' expects 1 param(s), 2 were given +unexpected-special-method-signature:17:Invalid.__setattr__:The special method '__setattr__' expects 2 param(s), 0 was given +unexpected-special-method-signature:20:Invalid.__round__:The special method '__round__' expects between 0 or 1 param(s), 2 were given +unexpected-special-method-signature:23:Invalid.__deepcopy__:The special method '__deepcopy__' expects 1 param(s), 2 were given +no-method-argument:26:Invalid.__iter__:Method has no argument +unexpected-special-method-signature:30:Invalid.__getattr__:The special method '__getattr__' expects 1 param(s), 2 were given +unexpected-special-method-signature:37:FirstBadContextManager.__exit__:The special method '__exit__' expects 3 param(s), 1 was given +unexpected-special-method-signature:43:SecondBadContextManager.__exit__:The special method '__exit__' expects 3 param(s), 4 were given +unexpected-special-method-signature:51:ThirdBadContextManager.__exit__:The special method '__exit__' expects 3 param(s), 4 were given +unexpected-special-method-signature:57:Async.__aiter__:The special method '__aiter__' expects 0 param(s), 1 was given +unexpected-special-method-signature:59:Async.__anext__:The special method '__anext__' expects 0 param(s), 2 were given +unexpected-special-method-signature:61:Async.__await__:The special method '__await__' expects 0 param(s), 1 was given +unexpected-special-method-signature:63:Async.__aenter__:The special method '__aenter__' expects 0 param(s), 1 was given +unexpected-special-method-signature:65:Async.__aexit__:The special method '__aexit__' expects 3 param(s), 0 was given \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ungrouped_imports.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ungrouped_imports.py new file mode 100644 index 0000000..e631e60 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ungrouped_imports.py @@ -0,0 +1,20 @@ +"""Checks import order rule""" +# pylint: disable=unused-import,relative-import,wrong-import-position,wrong-import-order,using-constant-test +# pylint: disable=import-error +import six +import logging.config +import os.path +from astroid import are_exclusive +import logging # [ungrouped-imports] +import unused_import +try: + import os # [ungrouped-imports] +except ImportError: + pass +from os import pardir +import scipy +from os import sep +import astroid # [ungrouped-imports] +if True: + import logging.handlers # [ungrouped-imports] +from os.path import join # [ungrouped-imports] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ungrouped_imports.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ungrouped_imports.txt new file mode 100644 index 0000000..c29bb18 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/ungrouped_imports.txt @@ -0,0 +1,5 @@ +ungrouped-imports:8::Imports from package logging are not grouped +ungrouped-imports:11::Imports from package os are not grouped +ungrouped-imports:17::Imports from package astroid are not grouped +ungrouped-imports:19::Imports from package logging are not grouped +ungrouped-imports:20::Imports from package os are not grouped diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unhashable_dict_key.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unhashable_dict_key.py new file mode 100644 index 0000000..1b469f3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unhashable_dict_key.py @@ -0,0 +1,11 @@ +# pylint: disable=missing-docstring,expression-not-assigned,too-few-public-methods,pointless-statement, useless-object-inheritance + + +class Unhashable(object): + __hash__ = list.__hash__ + +{}[[1, 2, 3]] # [unhashable-dict-key] +{}[{}] # [unhashable-dict-key] +{}[Unhashable()] # [unhashable-dict-key] +{'foo': 'bar'}['foo'] +{'foo': 'bar'}[42] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unhashable_dict_key.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unhashable_dict_key.txt new file mode 100644 index 0000000..77c3b92 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unhashable_dict_key.txt @@ -0,0 +1,3 @@ +unhashable-dict-key:7::Dict key is unhashable +unhashable-dict-key:8::Dict key is unhashable +unhashable-dict-key:9::Dict key is unhashable diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unidiomatic_typecheck.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unidiomatic_typecheck.py new file mode 100644 index 0000000..008456b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unidiomatic_typecheck.py @@ -0,0 +1,76 @@ +"""Warnings for using type(x) == Y or type(x) is Y instead of isinstance(x, Y).""" +# pylint: disable=missing-docstring,expression-not-assigned,redefined-builtin,invalid-name + +def simple_positives(): + type(42) is int # [unidiomatic-typecheck] + type(42) is not int # [unidiomatic-typecheck] + type(42) == int # [unidiomatic-typecheck] + type(42) != int # [unidiomatic-typecheck] + type(42) in [int] # [unidiomatic-typecheck] + type(42) not in [int] # [unidiomatic-typecheck] + +def simple_inference_positives(): + alias = type + alias(42) is int # [unidiomatic-typecheck] + alias(42) is not int # [unidiomatic-typecheck] + alias(42) == int # [unidiomatic-typecheck] + alias(42) != int # [unidiomatic-typecheck] + alias(42) in [int] # [unidiomatic-typecheck] + alias(42) not in [int] # [unidiomatic-typecheck] + +def type_creation_negatives(): + type('Q', (object,), dict(a=1)) is int + type('Q', (object,), dict(a=1)) is not int + type('Q', (object,), dict(a=1)) == int + type('Q', (object,), dict(a=1)) != int + type('Q', (object,), dict(a=1)) in [int] + type('Q', (object,), dict(a=1)) not in [int] + +def invalid_type_call_negatives(**kwargs): + type(bad=7) is int + type(bad=7) is not int + type(bad=7) == int + type(bad=7) != int + type(bad=7) in [int] + type(bad=7) not in [int] + type('bad', 7) is int + type('bad', 7) is not int + type('bad', 7) == int + type('bad', 7) != int + type('bad', 7) in [int] + type('bad', 7) not in [int] + type(**kwargs) is int + type(**kwargs) is not int + type(**kwargs) == int + type(**kwargs) != int + type(**kwargs) in [int] + type(**kwargs) not in [int] + +def local_var_shadowing_inference_negatives(): + type = lambda dummy: 7 + type(42) is int + type(42) is not int + type(42) == int + type(42) != int + type(42) in [int] + type(42) not in [int] + +def parameter_shadowing_inference_negatives(type): + type(42) is int + type(42) is not int + type(42) == int + type(42) != int + type(42) in [int] + type(42) not in [int] + +def deliberate_subclass_check_negatives(b): + type(42) is type(b) + type(42) is not type(b) + +def type_of_literals_positives(a): + type(a) is type([]) # [unidiomatic-typecheck] + type(a) is not type([]) # [unidiomatic-typecheck] + type(a) is type({}) # [unidiomatic-typecheck] + type(a) is not type({}) # [unidiomatic-typecheck] + type(a) is type("") # [unidiomatic-typecheck] + type(a) is not type("") # [unidiomatic-typecheck] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unidiomatic_typecheck.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unidiomatic_typecheck.txt new file mode 100644 index 0000000..23c0f6f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unidiomatic_typecheck.txt @@ -0,0 +1,18 @@ +unidiomatic-typecheck:5:simple_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:6:simple_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:7:simple_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:8:simple_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:9:simple_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:10:simple_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:14:simple_inference_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:15:simple_inference_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:16:simple_inference_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:17:simple_inference_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:18:simple_inference_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:19:simple_inference_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:71:type_of_literals_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:72:type_of_literals_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:73:type_of_literals_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:74:type_of_literals_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:75:type_of_literals_positives:Using type() instead of isinstance() for a typecheck. +unidiomatic-typecheck:76:type_of_literals_positives:Using type() instead of isinstance() for a typecheck. \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/uninferable_all_object.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/uninferable_all_object.py new file mode 100644 index 0000000..3e565f9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/uninferable_all_object.py @@ -0,0 +1,9 @@ +"""Test that non-inferable __all__ variables do not make Pylint crash.""" + +__all__ = sorted([ + 'Dummy', + 'NonExistant', + 'path', + 'func', + 'inner', + 'InnerKlass']) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_lambda.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_lambda.py new file mode 100644 index 0000000..eacb33d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_lambda.py @@ -0,0 +1,51 @@ +# pylint: disable=undefined-variable +"""test suspicious lambda expressions +""" + +__revision__ = '' + +# Some simple examples of the most commonly encountered forms. +# +1: [unnecessary-lambda] +_ = lambda: list() # replaceable with "list" +# +1: [unnecessary-lambda] +_ = lambda x: hash(x) # replaceable with "hash" +# +1: [unnecessary-lambda] +_ = lambda x, y: min(x, y) # replaceable with "min" + +# A function that can take any arguments given to it. +_ANYARGS = lambda *args, **kwargs: 'completely arbitrary return value' + +# Some more complex forms of unnecessary lambda expressions. +# +1: [unnecessary-lambda] +_ = lambda *args: _ANYARGS(*args) +# +1: [unnecessary-lambda] +_ = lambda **kwargs: _ANYARGS(**kwargs) +# +1: [unnecessary-lambda] +_ = lambda *args, **kwargs: _ANYARGS(*args, **kwargs) +# +1: [unnecessary-lambda] +_ = lambda x, y, z, *args, **kwargs: _ANYARGS(x, y, z, *args, **kwargs) + +# Lambdas that are *not* unnecessary and should *not* trigger warnings. +_ = lambda x: x +_ = lambda x: x() +_ = lambda x=4: hash(x) +_ = lambda x, y: list(range(y, x)) +_ = lambda x: list(range(5, x)) +_ = lambda x, y: list(range(x, 5)) +_ = lambda x, y, z: x.y(z) +_ = lambda: 5 +_ = lambda **kwargs: _ANYARGS() +_ = lambda **kwargs: _ANYARGS(**dict([('three', 3)])) +_ = lambda **kwargs: _ANYARGS(**{'three': 3}) +_ = lambda dict_arg, **kwargs: _ANYARGS(kwargs, **dict_arg) +_ = lambda *args: _ANYARGS() +_ = lambda *args: _ANYARGS(*list([3, 4])) +_ = lambda *args: _ANYARGS(*[3, 4]) +_ = lambda list_arg, *args: _ANYARGS(args, *list_arg) +_ = lambda: _ANYARGS(*[3]) +_ = lambda: _ANYARGS(**{'three': 3}) +_ = lambda: _ANYARGS(*[3], **{'three': 3}) +_ = lambda: _ANYARGS(func=42) + +# Don't warn about this. +_ = lambda: code().analysis() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_lambda.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_lambda.txt new file mode 100644 index 0000000..de13882 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_lambda.txt @@ -0,0 +1,7 @@ +unnecessary-lambda:9:<lambda>:Lambda may not be necessary +unnecessary-lambda:11:<lambda>:Lambda may not be necessary +unnecessary-lambda:13:<lambda>:Lambda may not be necessary +unnecessary-lambda:20:<lambda>:Lambda may not be necessary +unnecessary-lambda:22:<lambda>:Lambda may not be necessary +unnecessary-lambda:24:<lambda>:Lambda may not be necessary +unnecessary-lambda:26:<lambda>:Lambda may not be necessary diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_pass.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_pass.py new file mode 100644 index 0000000..c273309 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_pass.py @@ -0,0 +1,49 @@ +# pylint: disable=missing-docstring, too-few-public-methods + +try: + A = 2 +except ValueError: + A = 24 + pass # [unnecessary-pass] + +def docstring_only(): + '''In Python, stubbed functions often have a body that contains just a + single `pass` statement, indicating that the function doesn't do + anything. However, a stubbed function can also have just a + docstring, and function with a docstring and no body also does + nothing. + ''' + + +# This function has no docstring, so it needs a `pass` statement. +def pass_only(): + pass + + +def docstring_and_pass(): + '''This function doesn't do anything, but it has a docstring, so its + `pass` statement is useless clutter. + + NEW CHECK: useless-pass + + This would check for stubs with both docstrings and `pass` + statements, suggesting the removal of the useless `pass` + statements + ''' + pass # [unnecessary-pass] + + +class DocstringOnly: + '''The same goes for class stubs: docstring, or `pass`, but not both. + ''' + + +# No problem +class PassOnly: + pass + + +class DocstringAndPass: + '''Whoops! Mark this one as bad too. + ''' + pass # [unnecessary-pass] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_pass.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_pass.txt new file mode 100644 index 0000000..dbbc094 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unnecessary_pass.txt @@ -0,0 +1,3 @@ +unnecessary-pass:7::Unnecessary pass statement +unnecessary-pass:33:docstring_and_pass:Unnecessary pass statement +unnecessary-pass:49:DocstringAndPass:Unnecessary pass statement diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unneeded_not.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unneeded_not.py new file mode 100644 index 0000000..97acecd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unneeded_not.py @@ -0,0 +1,63 @@ +"""Check exceeding negations in boolean expressions trigger warnings""" + +# pylint: disable=singleton-comparison,too-many-branches,too-few-public-methods,undefined-variable +# pylint: disable=literal-comparison, comparison-with-itself, useless-object-inheritance +def unneeded_not(): + """This is not ok + """ + bool_var = True + someint = 2 + if not not bool_var: # [unneeded-not] + pass + if not someint == 1: # [unneeded-not] + pass + if not someint != 1: # [unneeded-not] + pass + if not someint < 1: # [unneeded-not] + pass + if not someint > 1: # [unneeded-not] + pass + if not someint <= 1: # [unneeded-not] + pass + if not someint >= 1: # [unneeded-not] + pass + if not not someint: # [unneeded-not] + pass + if not bool_var == True: # [unneeded-not] + pass + if not bool_var == False: # [unneeded-not] + pass + if not bool_var != True: # [unneeded-not] + pass + if not True == True: # [unneeded-not] + pass + if not 2 in [3, 4]: # [unneeded-not] + pass + if not someint is 'test': # [unneeded-not] + pass + + +def tolerated_statements(): + """This is ok""" + bool_var = True + someint = 2 + if not(bool_var == False and someint == 1): + pass + if 2 not in [3, 4]: + pass + if not someint == bool_var == 2: + pass + if not 2 <= someint < 3 < 4: + pass + if not set('bar') <= set('foobaz'): + pass + if not set(something) <= 3: + pass + if not frozenset(something) <= 3: + pass + + +class Klass(object): + """This is also ok""" + def __ne__(self, other): + return not self == other diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unneeded_not.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unneeded_not.txt new file mode 100644 index 0000000..13b3512 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unneeded_not.txt @@ -0,0 +1,14 @@ +unneeded-not:10:unneeded_not:Consider changing "not not bool_var" to "bool_var" +unneeded-not:12:unneeded_not:Consider changing "not someint == 1" to "someint != 1" +unneeded-not:14:unneeded_not:Consider changing "not someint != 1" to "someint == 1" +unneeded-not:16:unneeded_not:Consider changing "not someint < 1" to "someint >= 1" +unneeded-not:18:unneeded_not:Consider changing "not someint > 1" to "someint <= 1" +unneeded-not:20:unneeded_not:Consider changing "not someint <= 1" to "someint > 1" +unneeded-not:22:unneeded_not:Consider changing "not someint >= 1" to "someint < 1" +unneeded-not:24:unneeded_not:Consider changing "not not someint" to "someint" +unneeded-not:26:unneeded_not:Consider changing "not bool_var == True" to "bool_var != True" +unneeded-not:28:unneeded_not:Consider changing "not bool_var == False" to "bool_var != False" +unneeded-not:30:unneeded_not:Consider changing "not bool_var != True" to "bool_var == True" +unneeded-not:32:unneeded_not:Consider changing "not True == True" to "True != True" +unneeded-not:34:unneeded_not:Consider changing "not 2 in [3, 4]" to "2 not in [3, 4]" +unneeded-not:36:unneeded_not:Consider changing "not someint is 'test'" to "someint is not 'test'" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.py new file mode 100644 index 0000000..ec3599c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.py @@ -0,0 +1,11 @@ +"""Test for redefine-in-handler, overwriting names in exception handlers.""" + +def new_style(): + """Some exceptions can be unpacked.""" + try: + pass + except IOError, (errno, message): # [unpacking-in-except] + print errno, message # pylint: disable=print-statement + # +1: [redefine-in-handler,redefine-in-handler,unpacking-in-except] + except IOError, (new_style, tuple): # pylint: disable=duplicate-except + print new_style, tuple # pylint: disable=print-statement diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.rc new file mode 100644 index 0000000..9540bc9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.rc @@ -0,0 +1,5 @@ +[testoptions] +max_pyver=3.0 + +[Messages Control] +enable=python3 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.txt new file mode 100644 index 0000000..1a1b034 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacked_exceptions.txt @@ -0,0 +1,4 @@ +unpacking-in-except:7:new_style:Implicit unpacking of exceptions is not supported in Python 3 +redefine-in-handler:10:new_style:Redefining name 'new_style' from outer scope (line 3) in exception handler +redefine-in-handler:10:new_style:Redefining name 'tuple' from builtins in exception handler +unpacking-in-except:10:new_style:Implicit unpacking of exceptions is not supported in Python 3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking.py new file mode 100644 index 0000000..920caaa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking.py @@ -0,0 +1,11 @@ +""" Code for checking the display of the module +for unbalanced-tuple-unpacking and unpacking-non-sequence +""" + +def unpack(): + """ Return something""" + return (1, 2, 3) + +def nonseq(): + """ Return non sequence """ + return 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.py new file mode 100644 index 0000000..3a9d817 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.py @@ -0,0 +1,29 @@ +"""Various tests for unpacking generalizations added in Python 3.5""" + +# pylint: disable=missing-docstring, invalid-name + +def func_variadic_args(*args): + return args + + +def func_variadic_positional_args(a, b, *args): + return a, b, args + +def func_positional_args(a, b, c, d): + return a, b, c, d + + +func_variadic_args(*(2, 3), *(3, 4), *(4, 5)) +func_variadic_args(1, 2, *(2, 3), 2, 3, *(4, 5)) +func_variadic_positional_args(1, 2, *(4, 5), *(5, 6)) +func_variadic_positional_args(*(2, 3), *(4, 5), *(5, 6)) +func_variadic_positional_args(*(2, 3)) +func_variadic_positional_args(*(2, 3, 4)) +func_variadic_positional_args(1, 2, 3, *(3, 4)) + +func_positional_args(*(2, 3, 4), *(2, 3)) # [too-many-function-args] +func_positional_args(*(1, 2), 3) # [no-value-for-parameter] +func_positional_args(1, *(2, ), 3, *(4, 5)) # [too-many-function-args] +func_positional_args(1, 2, c=24, d=32, **{'d': 32}) # [repeated-keyword] +# +1: [repeated-keyword,repeated-keyword] +func_positional_args(1, 2, c=24, **{'c': 34, 'd': 33}, **{'d': 24}) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.rc new file mode 100644 index 0000000..03004f2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.txt new file mode 100644 index 0000000..d92fcc9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_generalizations.txt @@ -0,0 +1,6 @@ +too-many-function-args:24::Too many positional arguments for function call +no-value-for-parameter:25::"No value for argument 'd' in function call" +too-many-function-args:26::Too many positional arguments for function call +repeated-keyword:27::Got multiple values for keyword argument 'd' in function call +repeated-keyword:29::Got multiple values for keyword argument 'c' in function call +repeated-keyword:29::Got multiple values for keyword argument 'd' in function call \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_non_sequence.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_non_sequence.py new file mode 100644 index 0000000..06a840b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_non_sequence.py @@ -0,0 +1,140 @@ +"""Check unpacking non-sequences in assignments. """ + +# pylint: disable=too-few-public-methods, invalid-name, attribute-defined-outside-init, unused-variable, no-absolute-import +# pylint: disable=using-constant-test, no-init, missing-docstring, wrong-import-order,wrong-import-position,no-else-return, useless-object-inheritance +from os import rename as nonseq_func +from six import with_metaclass +from functional.unpacking import nonseq + +__revision__ = 0 + +# Working + +class Seq(object): + """ sequence """ + def __init__(self): + self.items = range(2) + + def __getitem__(self, item): + return self.items[item] + + def __len__(self): + return len(self.items) + +class Iter(object): + """ Iterator """ + def __iter__(self): + for number in range(2): + yield number + +def good_unpacking(): + """ returns should be unpackable """ + if True: + return [1, 2] + else: + return (3, 4) + +def good_unpacking2(): + """ returns should be unpackable """ + return good_unpacking() + +class MetaIter(type): + "metaclass that makes classes that use it iterables" + def __iter__(cls): + return iter((1, 2)) + +class IterClass(with_metaclass(MetaIter)): + "class that is iterable (and unpackable)" + +class AbstrClass(object): + "abstract class" + pair = None + + def setup_pair(self): + "abstract method" + raise NotImplementedError + + def __init__(self): + "error should not be emitted because setup_pair is abstract" + self.setup_pair() + x, y = self.pair + +a, b = [1, 2] +a, b = (1, 2) +a, b = set([1, 2]) +a, b = {1: 2, 2: 3} +a, b = "xy" +a, b = Seq() +a, b = Iter() +a, b = (number for number in range(2)) +a, b = good_unpacking() +a, b = good_unpacking2() +a, b = IterClass + +# Not working +class NonSeq(object): + """ does nothing """ + +a, b = NonSeq() # [unpacking-non-sequence] +a, b = ValueError # [unpacking-non-sequence] +a, b = None # [unpacking-non-sequence] +a, b = 1 # [unpacking-non-sequence] +a, b = nonseq # [unpacking-non-sequence] +a, b = nonseq() # [unpacking-non-sequence] +a, b = nonseq_func # [unpacking-non-sequence] + +class ClassUnpacking(object): + """ Check unpacking as instance attributes. """ + + def test(self): + """ test unpacking in instance attributes. """ + + self.a, self.b = 1, 2 + self.a, self.b = {1: 2, 2: 3} + self.a, self.b = "xy" + self.a, c = "xy" + c, self.a = good_unpacking() + self.a, self.b = Iter() + + self.a, self.b = NonSeq() # [unpacking-non-sequence] + self.a, self.b = ValueError # [unpacking-non-sequence] + self.a, c = nonseq_func # [unpacking-non-sequence] + +class TestBase(object): + 'base class with `test` method implementation' + @staticmethod + def test(data): + 'default implementation' + return data + +class Test(TestBase): + 'child class that overrides `test` method' + def __init__(self): + # no error should be emitted here as `test` is overridden in this class + (self.aaa, self.bbb, self.ccc) = self.test(None) + + @staticmethod + def test(data): + 'overridden implementation' + return (1, 2, 3) + + +import platform + + +def flow_control_false_positive(): + # This used to trigger an unpacking-non-sequence error. The problem was + # partially related to the fact that pylint does not understand flow control, + # but now it does not emit anymore, for this example, due to skipping it when + # determining an inference of multiple potential values. + # In any case, it is good having this repro as a test. + system, node, release, version, machine, processor = platform.uname() + # The previous line raises W0633 + return system, node, release, version, machine, processor + + +def flow_control_unpacking(var=None): + if var is not None: + var0, var1 = var + return var0, var1 + return None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_non_sequence.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_non_sequence.txt new file mode 100644 index 0000000..0a21fab --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unpacking_non_sequence.txt @@ -0,0 +1,10 @@ +unpacking-non-sequence:78::Attempting to unpack a non-sequence defined at line 75 +unpacking-non-sequence:79::Attempting to unpack a non-sequence +unpacking-non-sequence:80::Attempting to unpack a non-sequence None +unpacking-non-sequence:81::Attempting to unpack a non-sequence 1 +unpacking-non-sequence:82::Attempting to unpack a non-sequence defined at line 9 of functional.unpacking +unpacking-non-sequence:83::Attempting to unpack a non-sequence defined at line 11 of functional.unpacking +unpacking-non-sequence:84::Attempting to unpack a non-sequence +unpacking-non-sequence:99:ClassUnpacking.test:Attempting to unpack a non-sequence defined at line 75 +unpacking-non-sequence:100:ClassUnpacking.test:Attempting to unpack a non-sequence +unpacking-non-sequence:101:ClassUnpacking.test:Attempting to unpack a non-sequence diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unreachable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unreachable.py new file mode 100644 index 0000000..b03dec8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unreachable.py @@ -0,0 +1,22 @@ +# pylint: disable=missing-docstring + +from __future__ import print_function + +def func1(): + return 1 + print('unreachable') # [unreachable] + +def func2(): + while 1: + break + print('unreachable') # [unreachable] + +def func3(): + for i in (1, 2, 3): + print(i) + continue + print('unreachable') # [unreachable] + +def func4(): + raise Exception + return 1 / 0 # [unreachable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unreachable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unreachable.txt new file mode 100644 index 0000000..469cd01 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unreachable.txt @@ -0,0 +1,4 @@ +unreachable:7:func1:Unreachable code +unreachable:12:func2:Unreachable code +unreachable:18:func3:Unreachable code +unreachable:22:func4:Unreachable code \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unrecognized_inline_option.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unrecognized_inline_option.py new file mode 100644 index 0000000..1d7ec26 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unrecognized_inline_option.py @@ -0,0 +1,3 @@ +# +1: [unrecognized-inline-option] +# pylint:bouboule=1 +"""Check unknown option""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unrecognized_inline_option.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unrecognized_inline_option.txt new file mode 100644 index 0000000..922cc92 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unrecognized_inline_option.txt @@ -0,0 +1 @@ +unrecognized-inline-option:2::"Unrecognized file option 'bouboule'" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsubscriptable_value.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsubscriptable_value.py new file mode 100644 index 0000000..eddb621 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsubscriptable_value.py @@ -0,0 +1,114 @@ +""" +Checks that value used in a subscript supports subscription +(i.e. defines __getitem__ method). +""" +# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position +# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance +import six + +# primitives +numbers = [1, 2, 3] +numbers[0] +"123"[0] +u"123"[0] +b"123"[0] +bytearray(b"123")[0] +dict(a=1, b=2)['a'] +(1, 2, 3)[0] + +# list/dict comprehensions are fine +[x for x in range(10)][0] +{x: 10 - x for x in range(10)}[0] + + +# instances +class NonSubscriptable(object): + pass + +class Subscriptable(object): + def __getitem__(self, key): + return key + key + +NonSubscriptable()[0] # [unsubscriptable-object] +NonSubscriptable[0] # [unsubscriptable-object] +Subscriptable()[0] +Subscriptable[0] # [unsubscriptable-object] + +# generators are not subscriptable +def powers_of_two(): + k = 0 + while k < 10: + yield 2 ** k + k += 1 + +powers_of_two()[0] # [unsubscriptable-object] +powers_of_two[0] # [unsubscriptable-object] + + +# check that primitive non subscriptable types are caught +True[0] # [unsubscriptable-object] +None[0] # [unsubscriptable-object] +8.5[0] # [unsubscriptable-object] +10[0] # [unsubscriptable-object] + +# sets are not subscriptable +{x ** 2 for x in range(10)}[0] # [unsubscriptable-object] +set(numbers)[0] # [unsubscriptable-object] +frozenset(numbers)[0] # [unsubscriptable-object] + +# skip instances with unknown base classes +from some_missing_module import LibSubscriptable + +class MaybeSubscriptable(LibSubscriptable): + pass + +MaybeSubscriptable()[0] + +# subscriptable classes (through metaclasses) + +class MetaSubscriptable(type): + def __getitem__(cls, key): + return key + key + +class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)): + pass + +SubscriptableClass[0] +SubscriptableClass()[0] # [unsubscriptable-object] + +# functions are not subscriptable +def test(*args, **kwargs): + return args, kwargs + +test()[0] +test[0] # [unsubscriptable-object] + +# deque +from collections import deque +deq = deque(maxlen=10) +deq.append(42) +deq[0] + + +class AbstractClass(object): + + def __init__(self): + self.ala = {i for i in range(10)} + self.bala = [i for i in range(10)] + self.portocala = None + + def test_unsubscriptable(self): + self.bala[0] + self.portocala[0] + + +class ClassMixin(object): + + def __init__(self): + self.ala = {i for i in range(10)} + self.bala = [i for i in range(10)] + self.portocala = None + + def test_unsubscriptable(self): + self.bala[0] + self.portocala[0] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsubscriptable_value.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsubscriptable_value.txt new file mode 100644 index 0000000..d324394 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsubscriptable_value.txt @@ -0,0 +1,14 @@ +unsubscriptable-object:32::Value 'NonSubscriptable()' is unsubscriptable +unsubscriptable-object:33::Value 'NonSubscriptable' is unsubscriptable +unsubscriptable-object:35::Value 'Subscriptable' is unsubscriptable +unsubscriptable-object:44::Value 'powers_of_two()' is unsubscriptable +unsubscriptable-object:45::Value 'powers_of_two' is unsubscriptable +unsubscriptable-object:49::Value 'True' is unsubscriptable +unsubscriptable-object:50::Value 'None' is unsubscriptable +unsubscriptable-object:51::Value '8.5' is unsubscriptable +unsubscriptable-object:52::Value '10' is unsubscriptable +unsubscriptable-object:55::Value '{x**2 for x in range(10)}' is unsubscriptable +unsubscriptable-object:56::Value 'set(numbers)' is unsubscriptable +unsubscriptable-object:57::Value 'frozenset(numbers)' is unsubscriptable +unsubscriptable-object:77::Value 'SubscriptableClass()' is unsubscriptable +unsubscriptable-object:84::Value 'test' is unsubscriptable diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_assignment_operation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_assignment_operation.py new file mode 100644 index 0000000..ad2deab --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_assignment_operation.py @@ -0,0 +1,94 @@ +""" +Checks that value used in a subscript support assignments +(i.e. defines __setitem__ method). +""" +# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position +# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance +import six + +# primitives +numbers = [1, 2, 3] +numbers[0] = 42 + + +bytearray(b"123")[0] = 42 +dict(a=1, b=2)['a'] = 42 +(1, 2, 3)[0] = 42 # [unsupported-assignment-operation] + +# list/dict comprehensions are fine +[x for x in range(10)][0] = 42 +{x: 10 - x for x in range(10)}[0] = 42 + + +# instances +class NonSubscriptable(object): + pass + +class Subscriptable(object): + def __setitem__(self, key, value): + return key + value + +NonSubscriptable()[0] = 24 # [unsupported-assignment-operation] +NonSubscriptable[0] = 24 # [unsupported-assignment-operation] +Subscriptable()[0] = 24 +Subscriptable[0] = 24 # [unsupported-assignment-operation] + +# generators are not subscriptable +def powers_of_two(): + k = 0 + while k < 10: + yield 2 ** k + k += 1 + +powers_of_two()[0] = 42 # [unsupported-assignment-operation] +powers_of_two[0] = 42 # [unsupported-assignment-operation] + + +# check that primitive non subscriptable types are caught +True[0] = 24 # [unsupported-assignment-operation] +None[0] = 42 # [unsupported-assignment-operation] +8.5[0] = 24 # [unsupported-assignment-operation] +10[0] = 24 # [unsupported-assignment-operation] + +# sets are not subscriptable +{x ** 2 for x in range(10)}[0] = 24 # [unsupported-assignment-operation] +set(numbers)[0] = 24 # [unsupported-assignment-operation] +frozenset(numbers)[0] = 42 # [unsupported-assignment-operation] + +# skip instances with unknown base classes +from some_missing_module import LibSubscriptable + +class MaybeSubscriptable(LibSubscriptable): + pass + +MaybeSubscriptable()[0] = 42 + +# subscriptable classes (through metaclasses) + +class MetaSubscriptable(type): + def __setitem__(cls, key, value): + return key + value + +class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)): + pass + +SubscriptableClass[0] = 24 +SubscriptableClass()[0] = 24 # [unsupported-assignment-operation] + +# functions are not subscriptable +def test(*args, **kwargs): + return args, kwargs + +test()[0] = 24 # [unsupported-assignment-operation] +test[0] = 24 # [unsupported-assignment-operation] + +# deque +from collections import deque +deq = deque(maxlen=10) +deq.append(42) +deq[0] = 42 + +# tuples assignment +values = [1, 2, 3, 4] +(values[0], values[1]) = 3, 4 +(values[0], SubscriptableClass()[0]) = 42, 42 # [unsupported-assignment-operation] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_assignment_operation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_assignment_operation.txt new file mode 100644 index 0000000..27a11e4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_assignment_operation.txt @@ -0,0 +1,17 @@ +unsupported-assignment-operation:16::'(1, 2, 3)' does not support item assignment +unsupported-assignment-operation:31::'NonSubscriptable()' does not support item assignment +unsupported-assignment-operation:32::'NonSubscriptable' does not support item assignment +unsupported-assignment-operation:34::'Subscriptable' does not support item assignment +unsupported-assignment-operation:43::'powers_of_two()' does not support item assignment +unsupported-assignment-operation:44::'powers_of_two' does not support item assignment +unsupported-assignment-operation:48::'True' does not support item assignment +unsupported-assignment-operation:49::'None' does not support item assignment +unsupported-assignment-operation:50::'8.5' does not support item assignment +unsupported-assignment-operation:51::'10' does not support item assignment +unsupported-assignment-operation:54::'{x**2 for x in range(10)}' does not support item assignment +unsupported-assignment-operation:55::'set(numbers)' does not support item assignment +unsupported-assignment-operation:56::'frozenset(numbers)' does not support item assignment +unsupported-assignment-operation:76::'SubscriptableClass()' does not support item assignment +unsupported-assignment-operation:82::'test()' does not support item assignment +unsupported-assignment-operation:83::'test' does not support item assignment +unsupported-assignment-operation:94::'SubscriptableClass()' does not support item assignment diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.py new file mode 100644 index 0000000..4813125 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.py @@ -0,0 +1,66 @@ +"""Test for unsupported-binary-operation.""" +# pylint: disable=missing-docstring,too-few-public-methods,pointless-statement +# pylint: disable=expression-not-assigned, invalid-name, useless-object-inheritance + + +import collections + + +1 + "a" # [unsupported-binary-operation] +1 - [] # [unsupported-binary-operation] +1 * {} # [unsupported-binary-operation] +1 / collections # [unsupported-binary-operation] +1 ** (lambda x: x) # [unsupported-binary-operation] +{} * {} # [unsupported-binary-operation] +{} - {} # [unsupported-binary-operation] +{} | {} # [unsupported-binary-operation] +{} >> {} # [unsupported-binary-operation] +[] + () # [unsupported-binary-operation] +() + [] # [unsupported-binary-operation] +[] * 2.0 # [unsupported-binary-operation] +() * 2.0 # [unsupported-binary-operation] +2.0 >> 2.0 # [unsupported-binary-operation] +class A(object): + pass +class B(object): + pass +A() + B() # [unsupported-binary-operation] +class A1(object): + def __add__(self, other): + return NotImplemented + +A1() + A1() # [unsupported-binary-operation] + +class A2(object): + def __add__(self, other): + return NotImplemented +class B2(object): + def __radd__(self, other): + return NotImplemented +A2() + B2() # [unsupported-binary-operation] + +class Parent(object): + pass +class Child(Parent): + def __add__(self, other): + return NotImplemented +Child() + Parent() # [unsupported-binary-operation] +class A3(object): + def __add__(self, other): + return NotImplemented +class B3(A3): + def __radd__(self, other): + return NotImplemented +A3() + B3() # [unsupported-binary-operation] +# Augmented +FFF = 1 +FFF += A() # [unsupported-binary-operation] +TTT = 1 +TTT += [] # [unsupported-binary-operation] + + +# Don't emit for this case since we don't know what unknown is. +from unknown import Unknown +class Base(Unknown): + pass +Base() * 23 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.rc new file mode 100644 index 0000000..401ccfe --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=4.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.txt new file mode 100644 index 0000000..8f232f7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_binary_operation.txt @@ -0,0 +1,21 @@ +unsupported-binary-operation:9::"unsupported operand type(s) for +: 'int' and 'str'" +unsupported-binary-operation:10::"unsupported operand type(s) for -: 'int' and 'list'" +unsupported-binary-operation:11::"unsupported operand type(s) for *: 'int' and 'dict'" +unsupported-binary-operation:12::"unsupported operand type(s) for /: 'int' and 'module'" +unsupported-binary-operation:13::"unsupported operand type(s) for **: 'int' and 'function'" +unsupported-binary-operation:14::"unsupported operand type(s) for *: 'dict' and 'dict'" +unsupported-binary-operation:15::"unsupported operand type(s) for -: 'dict' and 'dict'" +unsupported-binary-operation:16::"unsupported operand type(s) for |: 'dict' and 'dict'" +unsupported-binary-operation:17::"unsupported operand type(s) for >>: 'dict' and 'dict'" +unsupported-binary-operation:18::"unsupported operand type(s) for +: 'list' and 'tuple'" +unsupported-binary-operation:19::"unsupported operand type(s) for +: 'tuple' and 'list'" +unsupported-binary-operation:20::"unsupported operand type(s) for *: 'list' and 'float'" +unsupported-binary-operation:21::"unsupported operand type(s) for *: 'tuple' and 'float'" +unsupported-binary-operation:22::"unsupported operand type(s) for >>: 'float' and 'float'" +unsupported-binary-operation:27::"unsupported operand type(s) for +: 'A' and 'B'" +unsupported-binary-operation:32::"unsupported operand type(s) for +: 'A1' and 'A1'" +unsupported-binary-operation:40::"unsupported operand type(s) for +: 'A2' and 'B2'" +unsupported-binary-operation:47::"unsupported operand type(s) for +: 'Child' and 'Parent'" +unsupported-binary-operation:54::"unsupported operand type(s) for +: 'A3' and 'B3'" +unsupported-binary-operation:57::"unsupported operand type(s) for +=: 'int' and 'A'" +unsupported-binary-operation:59::"unsupported operand type(s) for +=: 'int' and 'list'" \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_delete_operation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_delete_operation.py new file mode 100644 index 0000000..c9bab62 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_delete_operation.py @@ -0,0 +1,94 @@ +""" +Checks that value used in a subscript support deletion +(i.e. defines __delitem__ method). +""" +# pylint: disable=missing-docstring,pointless-statement,expression-not-assigned,wrong-import-position +# pylint: disable=too-few-public-methods,import-error,invalid-name,wrong-import-order, useless-object-inheritance +import six + +# primitives +numbers = [1, 2, 3] +del numbers[0] + + +del bytearray(b"123")[0] +del dict(a=1, b=2)['a'] +del (1, 2, 3)[0] # [unsupported-delete-operation] + +# list/dict comprehensions are fine +del [x for x in range(10)][0] +del {x: 10 - x for x in range(10)}[0] + + +# instances +class NonSubscriptable(object): + pass + +class Subscriptable(object): + def __delitem__(self, key): + pass + +del NonSubscriptable()[0] # [unsupported-delete-operation] +del NonSubscriptable[0] # [unsupported-delete-operation] +del Subscriptable()[0] +del Subscriptable[0] # [unsupported-delete-operation] + +# generators are not subscriptable +def powers_of_two(): + k = 0 + while k < 10: + yield 2 ** k + k += 1 + +del powers_of_two()[0] # [unsupported-delete-operation] +del powers_of_two[0] # [unsupported-delete-operation] + + +# check that primitive non subscriptable types are caught +del True[0] # [unsupported-delete-operation] +del None[0] # [unsupported-delete-operation] +del 8.5[0] # [unsupported-delete-operation] +del 10[0] # [unsupported-delete-operation] + +# sets are not subscriptable +del {x ** 2 for x in range(10)}[0] # [unsupported-delete-operation] +del set(numbers)[0] # [unsupported-delete-operation] +del frozenset(numbers)[0] # [unsupported-delete-operation] + +# skip instances with unknown base classes +from some_missing_module import LibSubscriptable + +class MaybeSubscriptable(LibSubscriptable): + pass + +del MaybeSubscriptable()[0] + +# subscriptable classes (through metaclasses) + +class MetaSubscriptable(type): + def __delitem__(cls, key): + pass + +class SubscriptableClass(six.with_metaclass(MetaSubscriptable, object)): + pass + +del SubscriptableClass[0] +del SubscriptableClass()[0] # [unsupported-delete-operation] + +# functions are not subscriptable +def test(*args, **kwargs): + return args, kwargs + +del test()[0] # [unsupported-delete-operation] +del test[0] # [unsupported-delete-operation] + +# deque +from collections import deque +deq = deque(maxlen=10) +deq.append(42) +del deq[0] + +# tuples assignment +values = [1, 2, 3, 4] +del (values[0], values[1]) +del (values[0], SubscriptableClass()[0]) # [unsupported-delete-operation] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_delete_operation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_delete_operation.txt new file mode 100644 index 0000000..6c3078e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unsupported_delete_operation.txt @@ -0,0 +1,17 @@ +unsupported-delete-operation:16::'(1, 2, 3)' does not support item deletion +unsupported-delete-operation:31::'NonSubscriptable()' does not support item deletion +unsupported-delete-operation:32::'NonSubscriptable' does not support item deletion +unsupported-delete-operation:34::'Subscriptable' does not support item deletion +unsupported-delete-operation:43::'powers_of_two()' does not support item deletion +unsupported-delete-operation:44::'powers_of_two' does not support item deletion +unsupported-delete-operation:48::'True' does not support item deletion +unsupported-delete-operation:49::'None' does not support item deletion +unsupported-delete-operation:50::'8.5' does not support item deletion +unsupported-delete-operation:51::'10' does not support item deletion +unsupported-delete-operation:54::'{x**2 for x in range(10)}' does not support item deletion +unsupported-delete-operation:55::'set(numbers)' does not support item deletion +unsupported-delete-operation:56::'frozenset(numbers)' does not support item deletion +unsupported-delete-operation:76::'SubscriptableClass()' does not support item deletion +unsupported-delete-operation:82::'test()' does not support item deletion +unsupported-delete-operation:83::'test' does not support item deletion +unsupported-delete-operation:94::'SubscriptableClass()' does not support item deletion diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument.py new file mode 100644 index 0000000..013d4b3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument.py @@ -0,0 +1,48 @@ +# pylint: disable=missing-docstring,too-few-public-methods, useless-object-inheritance + +def test_unused(first, second, _not_used): # [unused-argument, unused-argument] + pass + + +def test_prefixed_with_ignored(first, ignored_second): + first() + + +def test_prefixed_with_unused(first, unused_second): + first() + +# for Sub.inherited, only the warning for "aay" is desired. +# The warnings for "aab" and "aac" are most likely false positives though, +# because there could be another subclass that overrides the same method and does +# use the arguments (eg Sub2) + + +class Base(object): + "parent" + def inherited(self, aaa, aab, aac): + "abstract method" + raise NotImplementedError + +class Sub(Base): + "child 1" + def inherited(self, aaa, aab, aac): + "overridden method, though don't use every argument" + return aaa + + def newmethod(self, aax, aay): # [unused-argument] + "another method, warning for aay desired" + return self, aax + +class Sub2(Base): + "child 1" + + def inherited(self, aaa, aab, aac): + "overridden method, use every argument" + return aaa + aab + aac + +def metadata_from_dict(key): + """ + Should not raise unused-argument message because key is + used inside comprehension dict + """ + return {key: str(value) for key, value in key.items()} diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument.txt new file mode 100644 index 0000000..d583438 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument.txt @@ -0,0 +1,3 @@ +unused-argument:3:test_unused:Unused argument 'first' +unused-argument:3:test_unused:Unused argument 'second' +unused-argument:32:Sub.newmethod:Unused argument 'aay':INFERENCE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.py new file mode 100644 index 0000000..65af3e7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.py @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring + +def func(first, *, second): # [unused-argument, unused-argument] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.txt new file mode 100644 index 0000000..f575e43 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_argument_py3.txt @@ -0,0 +1,2 @@ +unused-argument:3:func:Unused argument 'first' +unused-argument:3:func:Unused argument 'second' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable1.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable1.py new file mode 100644 index 0000000..e630c33 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable1.py @@ -0,0 +1,2 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.py new file mode 100644 index 0000000..6222409 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.py @@ -0,0 +1,2 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' # [unused-variable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.rc new file mode 100644 index 0000000..5dcd4a8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.rc @@ -0,0 +1,2 @@ +[variables] +allow-global-unused-variables=no diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.txt new file mode 100644 index 0000000..27019cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable2.txt @@ -0,0 +1 @@ +unused-variable:2::Unused variable 'VAR':HIGH diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable3.py new file mode 100644 index 0000000..896789e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable3.py @@ -0,0 +1,6 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' + + +def func(argument): + return VAR + argument diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.py new file mode 100644 index 0000000..aef49d6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.py @@ -0,0 +1,3 @@ +# pylint: disable=missing-docstring +VAR = 'pylint' # [unused-variable] +VAR = 'pylint2' # [unused-variable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.rc new file mode 100644 index 0000000..5dcd4a8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.rc @@ -0,0 +1,2 @@ +[variables] +allow-global-unused-variables=no diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.txt new file mode 100644 index 0000000..61e3b28 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_global_variable4.txt @@ -0,0 +1,2 @@ +unused-variable:2::Unused variable 'VAR':HIGH +unused-variable:3::Unused variable 'VAR':HIGH diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import.py new file mode 100644 index 0000000..e551db5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import.py @@ -0,0 +1,35 @@ +"""unused import""" +# pylint: disable=undefined-all-variable, import-error, no-absolute-import, too-few-public-methods, missing-docstring,wrong-import-position, useless-object-inheritance +import xml.etree # [unused-import] +import xml.sax # [unused-import] +import os.path as test # [unused-import] +from sys import argv as test2 # [unused-import] +from sys import flags # [unused-import] +# +1:[unused-import,unused-import] +from collections import deque, OrderedDict, Counter +DATA = Counter() + +from fake import SomeName, SomeOtherName # [unused-import] +class SomeClass(object): + SomeName = SomeName # https://bitbucket.org/logilab/pylint/issue/475 + SomeOtherName = 1 + SomeOtherName = SomeOtherName + +from never import __all__ +# pylint: disable=wrong-import-order,ungrouped-imports +import typing +from typing import TYPE_CHECKING + + +if typing.TYPE_CHECKING: + import collections +if TYPE_CHECKING: + import itertools + + +def get_ordered_dict() -> 'collections.OrderedDict': + return [] + + +def get_itertools_obj() -> 'itertools.count': + return [] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import.txt new file mode 100644 index 0000000..9d6497f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import.txt @@ -0,0 +1,8 @@ +unused-import:3::Unused import xml.etree +unused-import:4::Unused import xml.sax +unused-import:5::Unused os.path imported as test +unused-import:6::Unused argv imported from sys as test2 +unused-import:7::Unused flags imported from sys +unused-import:9::Unused OrderedDict imported from collections +unused-import:9::Unused deque imported from collections +unused-import:12::Unused SomeOtherName imported from fake diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import_assigned_to.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import_assigned_to.py new file mode 100644 index 0000000..81d3e2c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_import_assigned_to.py @@ -0,0 +1,25 @@ +# pylint: disable=missing-docstring, import-error, invalid-name +# pylint: disable=too-few-public-methods, blacklisted-name, no-member, useless-object-inheritance + +import uuid + +# Note this import doesn't actually exist +import foo + +from .a import x + + +class Y(object): + x = x[0] + + +def test(default=None): + return default + + +class BaseModel(object): + uuid = test(default=uuid.uuid4) + + +class bar(object): + foo = foo.baz diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_typing_imports.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_typing_imports.py new file mode 100644 index 0000000..e2fd4ae --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_typing_imports.py @@ -0,0 +1,39 @@ +# pylint: disable=missing-docstring, bad-whitespace +"""Regression test for https://github.com/PyCQA/pylint/issues/1168 + +The problem was that we weren't handling keyword-only arguments annotations, +which means we were never processing them. +""" + +import re +from typing import Optional, Callable, Iterable, Any, List, Tuple, Set, NamedTuple, Pattern + + +def func1(arg: Optional[Callable]=None): + return arg + + +def func2(*, arg: Optional[Iterable]=None): + return arg + + +SOME_VALUE = [1] # type: List[Any] +for VALUE in [[1], [2], [3]]: # type: Tuple[Any] + print(VALUE) + + +class ContextManager: + def __enter__(self): + return {1} + + def __exit__(self, *_args): + pass + + +with ContextManager() as SOME_DICT: # type: Set[int] + print(SOME_DICT) + + +def func_test_type_comment(param): + # type: (NamedTuple) -> Tuple[NamedTuple, Pattern] + return param, re.compile('good') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_typing_imports.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_typing_imports.rc new file mode 100644 index 0000000..dca4945 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_typing_imports.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.6 +max_pyver=3.7 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_variable.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_variable.py new file mode 100644 index 0000000..4e6d58f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_variable.py @@ -0,0 +1,55 @@ +# pylint: disable=missing-docstring, invalid-name, too-few-public-methods, no-self-use, useless-object-inheritance + +def test_regression_737(): + import xml # [unused-import] + +def test_regression_923(): + import unittest.case # [unused-import] + import xml as sql # [unused-import] + +def test_unused_with_prepended_underscore(): + _foo = 42 + _ = 24 + __a = 24 + dummy = 24 + _a_ = 42 # [unused-variable] + __a__ = 24 # [unused-variable] + __never_used = 42 + +def test_local_field_prefixed_with_unused_or_ignored(): + flagged_local_field = 42 # [unused-variable] + unused_local_field = 42 + ignored_local_field = 42 + + +class HasUnusedDunderClass(object): + + def test(self): + __class__ = 42 # [unused-variable] + + def best(self): + self.test() + + +def locals_example_defined_before(): + value = 42 # [possibly-unused-variable] + return locals() + + +def locals_example_defined_after(): + local_variables = locals() + value = 42 # [unused-variable] + return local_variables + + +def locals_does_not_account_for_subscopes(): + value = 42 # [unused-variable] + + def some_other_scope(): + return locals() + return some_other_scope + + +def unused_import_from(): + from functools import wraps as abc # [unused-import] + from collections import namedtuple # [unused-import] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_variable.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_variable.txt new file mode 100644 index 0000000..231528b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/unused_variable.txt @@ -0,0 +1,12 @@ +unused-import:4:test_regression_737:Unused import xml +unused-import:7:test_regression_923:Unused import unittest.case +unused-import:8:test_regression_923:Unused xml imported as sql +unused-variable:15:test_unused_with_prepended_underscore:Unused variable '_a_' +unused-variable:16:test_unused_with_prepended_underscore:Unused variable '__a__' +unused-variable:20:test_local_field_prefixed_with_unused_or_ignored:Unused variable 'flagged_local_field' +unused-variable:28:HasUnusedDunderClass.test:Unused variable '__class__' +possibly-unused-variable:35:locals_example_defined_before:Possibly unused variable 'value' +unused-variable:41:locals_example_defined_after:Unused variable 'value' +unused-variable:46:locals_does_not_account_for_subscopes:Unused variable 'value' +unused-import:54:unused_import_from:Unused wraps imported from functools as abc +unused-import:55:unused_import_from:Unused namedtuple imported from collections diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_488.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_488.py new file mode 100644 index 0000000..efc133c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_488.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-docstring +def func(): + """Test that a variable defined in a finally clause does not trigger a false positive""" + try: + variable = 1 + yield variable + finally: + variable = 2 + yield variable diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue1081.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue1081.py new file mode 100644 index 0000000..0c59cce --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue1081.py @@ -0,0 +1,40 @@ +# pylint: disable=missing-docstring,invalid-name,too-few-public-methods, useless-object-inheritance + +x = 24 + + +def used_before_assignment_1(a): + if x == a: # [used-before-assignment] + for x in [1, 2]: # [redefined-outer-name] + pass + + +def used_before_assignment_2(a): + if x == a: # [used-before-assignment] + pass + x = 2 # [redefined-outer-name] + + +def used_before_assignment_3(a): + if x == a: # [used-before-assignment] + if x > 3: + x = 2 # [redefined-outer-name] + + +def not_used_before_assignment(a): + if x == a: + pass + + +def not_used_before_assignment_2(a): + x = 3 # [redefined-outer-name] + if x == a: + pass + + +def func(something): + return something ** 3 + + +class FalsePositive(object): + x = func(x) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue1081.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue1081.txt new file mode 100644 index 0000000..9b05aac --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue1081.txt @@ -0,0 +1,7 @@ +used-before-assignment:7:used_before_assignment_1:Using variable 'x' before assignment +redefined-outer-name:8:used_before_assignment_1:Redefining name 'x' from outer scope (line 3) +used-before-assignment:13:used_before_assignment_2:Using variable 'x' before assignment +redefined-outer-name:15:used_before_assignment_2:Redefining name 'x' from outer scope (line 3) +used-before-assignment:19:used_before_assignment_3:Using variable 'x' before assignment +redefined-outer-name:21:used_before_assignment_3:Redefining name 'x' from outer scope (line 3) +redefined-outer-name:30:not_used_before_assignment_2:Redefining name 'x' from outer scope (line 3) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue853.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue853.py new file mode 100644 index 0000000..f8b4122 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_issue853.py @@ -0,0 +1,23 @@ +# pylint: disable=missing-docstring,bare-except,pointless-statement,superfluous-parens +def strangeproblem(): + try: + for _ in range(0, 4): + message = object() + print(type(message)) + finally: + message = object() + + +try: + MY_INT = 1 + print("MY_INT = %d" % MY_INT) +finally: + MY_INT = 2 + +try: + pass +except: + FALSE_POSITIVE = 1 + FALSE_POSITIVE # here pylint claims used-before-assignment +finally: + FALSE_POSITIVE = 2 # this line is needed to reproduce the issue diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.py new file mode 100644 index 0000000..32d22b3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.py @@ -0,0 +1,60 @@ +"""Check for nonlocal and used-before-assignment""" +# pylint: disable=missing-docstring, unused-variable, no-init, too-few-public-methods + +__revision__ = 0 + +def test_ok(): + """ uses nonlocal """ + cnt = 1 + def wrap(): + nonlocal cnt + cnt = cnt + 1 + wrap() + +def test_fail(): + """ doesn't use nonlocal """ + cnt = 1 + def wrap(): + cnt = cnt + 1 # [used-before-assignment] + wrap() + +def test_fail2(): + """ use nonlocal, but for other variable """ + cnt = 1 + count = 1 + def wrap(): + nonlocal count + cnt = cnt + 1 # [used-before-assignment] + wrap() + +def test_fail3(arg: test_fail4): # [used-before-assignment] + """ Depends on `test_fail4`, in argument annotation. """ + return arg +# +1: [used-before-assignment, used-before-assignment] +def test_fail4(*args: test_fail5, **kwargs: undefined): + """ Depends on `test_fail5` and `undefined` in + variable and named arguments annotations. + """ + return args, kwargs + +def test_fail5()->undefined1: # [used-before-assignment] + """ Depends on `undefined1` in function return annotation. """ + +def undefined(): + """ no op """ + +def undefined1(): + """ no op """ + + +def nonlocal_in_ifexp(): + """bar""" + bug2 = True + def on_click(event): + """on_click""" + if event: + nonlocal bug2 + bug2 = not bug2 + on_click(True) + +nonlocal_in_ifexp() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.txt new file mode 100644 index 0000000..7c51b1c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_before_assignment_nonlocal.txt @@ -0,0 +1,6 @@ +used-before-assignment:18:test_fail.wrap:Using variable 'cnt' before assignment +used-before-assignment:27:test_fail2.wrap:Using variable 'cnt' before assignment +used-before-assignment:30:test_fail3:Using variable 'test_fail4' before assignment +used-before-assignment:34:test_fail4:Using variable 'test_fail5' before assignment +used-before-assignment:34:test_fail4:Using variable 'undefined' before assignment +used-before-assignment:40:test_fail5:Using variable 'undefined1' before assignment \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.py new file mode 100644 index 0000000..0795010 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.py @@ -0,0 +1,39 @@ +# pylint: disable=missing-docstring, pointless-statement, global-variable-not-assigned, global-statement + + +CONST = 1 + + +def test(): + CONST # [used-prior-global-declaration] + + global CONST + + +def other_test(): + CONST + + global SOMETHING + + +def other_test_1(): + global SOMETHING + + CONST + + +def other_test_2(): + CONST + + def inner(): + global CONST + + return inner + + +def other_test_3(): + def inner(): + return CONST + + global CONST + return inner diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.txt new file mode 100644 index 0000000..861ba17 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/used_prior_global_declaration.txt @@ -0,0 +1 @@ +used-prior-global-declaration:8:test:Name 'CONST' is used prior to global declaration \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless-import-alias.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless-import-alias.py new file mode 100644 index 0000000..c8ef837 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless-import-alias.py @@ -0,0 +1,21 @@ +# pylint: disable=unused-import, missing-docstring, invalid-name, reimported, import-error, wrong-import-order, no-name-in-module, relative-beyond-top-level +from collections import OrderedDict as OrderedDict # [useless-import-alias] +from collections import OrderedDict as o_dict +import os.path as path +import os.path as p +import foo.bar.foobar as foobar +import os +import os as OS +from sys import version +from . import bar as bar # [useless-import-alias] +from . import bar as Bar +from . import bar +from ..foo import bar as bar # [useless-import-alias] +from ..foo.bar import foobar as foobar # [useless-import-alias] +from ..foo.bar import foobar as anotherfoobar +from . import foo as foo, foo2 as bar2 # [useless-import-alias] +from . import foo as bar, foo2 as foo2 # [useless-import-alias] +from . import foo as bar, foo2 as bar2 +from foo.bar import foobar as foobar # [useless-import-alias] +from foo.bar import foobar as foo +from .foo.bar import f as foobar diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless-import-alias.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless-import-alias.txt new file mode 100644 index 0000000..6f90b1c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless-import-alias.txt @@ -0,0 +1,9 @@ +useless-import-alias:2::Import alias does not rename original package +useless-import-alias:4::Import alias does not rename original package +useless-import-alias:6::Import alias does not rename original package +useless-import-alias:10::Import alias does not rename original package +useless-import-alias:13::Import alias does not rename original package +useless-import-alias:14::Import alias does not rename original package +useless-import-alias:16::Import alias does not rename original package +useless-import-alias:17::Import alias does not rename original package +useless-import-alias:19::Import alias does not rename original package diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_else_on_loop.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_else_on_loop.py new file mode 100644 index 0000000..465f659 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_else_on_loop.py @@ -0,0 +1,89 @@ +"""Check for else branches on loops with break and return only.""" +from __future__ import print_function +__revision__ = 0 + +def test_return_for(): + """else + return is not accetable.""" + for i in range(10): + if i % 2: + return i + else: # [useless-else-on-loop] + print('math is broken') + return None + +def test_return_while(): + """else + return is not accetable.""" + while True: + return 1 + else: # [useless-else-on-loop] + print('math is broken') + return None + + +while True: + def short_fun(): + """A function with a loop.""" + for _ in range(10): + break +else: # [useless-else-on-loop] + print('or else!') + + +while True: + while False: + break +else: # [useless-else-on-loop] + print('or else!') + +for j in range(10): + pass +else: # [useless-else-on-loop] + print('fat chance') + for j in range(10): + break + + +def test_return_for2(): + """no false positive for break in else + + https://bitbucket.org/logilab/pylint/issue/117/useless-else-on-loop-false-positives + """ + for i in range(10): + for _ in range(i): + if i % 2: + break + else: + break + else: + print('great math') + + +def test_break_in_orelse_deep(): + """no false positive for break in else deeply nested + """ + for _ in range(10): + if 1 < 2: + for _ in range(3): + if 3 < 2: + break + else: + break + else: + return True + return False + + +def test_break_in_orelse_deep2(): + """should rise a useless-else-on-loop message, as the break statement is only + for the inner for loop + """ + for _ in range(10): + if 1 < 2: + for _ in range(3): + if 3 < 2: + break + else: + print("all right") + else: # [useless-else-on-loop] + return True + return False diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_else_on_loop.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_else_on_loop.txt new file mode 100644 index 0000000..efa1161 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_else_on_loop.txt @@ -0,0 +1,6 @@ +useless-else-on-loop:10:test_return_for:Else clause on loop without a break statement +useless-else-on-loop:18:test_return_while:Else clause on loop without a break statement +useless-else-on-loop:28::Else clause on loop without a break statement +useless-else-on-loop:35::Else clause on loop without a break statement +useless-else-on-loop:40::Else clause on loop without a break statement +useless-else-on-loop:87:test_break_in_orelse_deep2:Else clause on loop without a break statement diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_object_inheritance.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_object_inheritance.py new file mode 100644 index 0000000..562c81f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_object_inheritance.py @@ -0,0 +1,27 @@ +"""Check if a class inherits from object. +In python3 every class implicitly inherits from object, therefore give refactoring message to + remove object from bases""" +# pylint: disable=no-init, invalid-name, missing-docstring, too-few-public-methods +# pylint: disable=inconsistent-mro +import abc + +class A(object): # [useless-object-inheritance] + pass + +class B: + pass + +class C(B, object): # [useless-object-inheritance] + pass + +class D(object, C, metaclass=abc.ABCMeta): # [useless-object-inheritance] + pass + +class E(D, C, object, metaclass=abc.ABCMeta): # [useless-object-inheritance] + pass + +class F(A): # positive test case + pass + +class G(B): # positive test case + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_object_inheritance.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_object_inheritance.txt new file mode 100644 index 0000000..2e00673 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_object_inheritance.txt @@ -0,0 +1,4 @@ +useless-object-inheritance:8:A:Class 'A' inherits from object, can be safely removed from bases in python3 +useless-object-inheritance:14:C:Class 'C' inherits from object, can be safely removed from bases in python3 +useless-object-inheritance:17:D:Class 'D' inherits from object, can be safely removed from bases in python3 +useless-object-inheritance:20:E:Class 'E' inherits from object, can be safely removed from bases in python3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_return.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_return.py new file mode 100644 index 0000000..61aaebe --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_return.py @@ -0,0 +1,15 @@ +# pylint: disable=missing-docstring,too-few-public-methods,no-self-use,bad-option-value, useless-object-inheritance +from __future__ import print_function + +def myfunc(): # [useless-return] + print('---- testing ---') + return + +class SomeClass(object): + def mymethod(self): # [useless-return] + print('---- testing ---') + return None + + # These are not emitted + def item_at(self): + return None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_return.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_return.txt new file mode 100644 index 0000000..c28c6d4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_return.txt @@ -0,0 +1,2 @@ +useless-return:4:myfunc:Useless return at end of function or method +useless-return:9:SomeClass.mymethod:Useless return at end of function or method diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation.py new file mode 100644 index 0000000..421f667 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation.py @@ -0,0 +1,252 @@ +# pylint: disable=missing-docstring, no-member, no-self-use, bad-super-call +# pylint: disable=too-few-public-methods, unused-argument, invalid-name, too-many-public-methods +# pylint: disable=line-too-long, useless-object-inheritance + + +def not_a_method(param, param2): + return super(None, None).not_a_method(param, param2) + + +class SuperBase(object): + def with_default_arg(self, first, default_arg="only_in_super_base"): + pass + + def with_default_arg_bis(self, first, default_arg="only_in_super_base"): + pass + + def with_default_arg_ter(self, first, default_arg="will_be_changed"): + pass + + def with_default_arg_quad(self, first, default_arg="will_be_changed"): + pass + + +class Base(SuperBase): + + fake_method = not_a_method + + def something(self): + pass + + def with_default_argument(self, first, default_arg="default"): + pass + + def with_default_argument_bis(self, first, default_arg="default"): + pass + + def without_default_argument(self, first, second): + pass + + def with_default_argument_none(self, first, default_arg=None): + pass + + def without_default_argument2(self, first, second): + pass + + def with_default_argument_int(self, first, default_arg=42): + pass + + def with_default_argument_tuple(self, first, default_arg=()): + pass + + def with_default_arg_ter(self, first, default_arg="has_been_changed"): + super(Base, self).with_default_arg_ter(first, default_arg) + + def with_default_arg_quad(self, first, default_arg="has_been_changed"): + super(Base, self).with_default_arg_quad(first, default_arg) + +class NotUselessSuper(Base): + + def multiple_statements(self): + first = 42 * 24 + return super(NotUselessSuper, self).multiple_statements() + first + + def not_a_call(self): + return 1 + 2 + + def not_super_call(self): + return type(self).__class__ + + def not_super_attribute_access(self): + return super(NotUselessSuper, self) + + def invalid_super_call(self): + return super(NotUselessSuper, 1).invalid_super_call() + + def other_invalid_super_call(self): + return super(2, 3, 4, 5).other_invalid_super_call() + + def different_name(self): + return super(NotUselessSuper, self).something() + + def different_super_mro_pointer(self): + return super(Base, self).different_super_mro_pointer() + + def different_super_type(self): + return super(NotUselessSuper, NotUselessSuper).different_super_type() + + def other_different_super_type(self): + return super(NotUselessSuper, 1).other_different_super_type() + + def not_passing_param(self, first): + return super(NotUselessSuper, self).not_passing_param() + + def modifying_param(self, first): + return super(NotUselessSuper, self).modifying_param(first + 1) + + def transforming_param(self, first): + return super(NotUselessSuper, self).transforming_param(type(first)) + + def modifying_variadic(self, *args): + return super(NotUselessSuper, self).modifying_variadic(tuple(args)) + + def not_passing_keyword_variadics(self, *args, **kwargs): + return super(NotUselessSuper, self).not_passing_keyword_variadics(*args) + + def not_passing_default(self, first, second=None): + return super(NotUselessSuper, self).not_passing_default(first) + + def passing_only_a_handful(self, first, second, third, fourth): + return super(NotUselessSuper, self).passing_only_a_handful( + first, second) + + def not_the_same_order(self, first, second, third): + return super(NotUselessSuper, self).not_the_same_order(third, first, second) + + def no_kwargs_in_signature(self, key=None): + values = {'key': 'something'} + return super(NotUselessSuper, self).no_kwargs_in_signature(**values) + + def no_args_in_signature(self, first, second): + values = (first + 1, second + 2) + return super(NotUselessSuper, self).no_args_in_signature(*values) + + def variadics_with_multiple_keyword_arguments(self, **kwargs): + return super(NotUselessSuper, self).variadics_with_multiple_keyword_arguments( + first=None, + second=None, + **kwargs) + + def extraneous_keyword_params(self, none_ok=False): + super(NotUselessSuper, self).extraneous_keyword_params( + none_ok, + valid_values=[23, 42]) + + def extraneous_positional_args(self, **args): + super(NotUselessSuper, self).extraneous_positional_args( + 1, 2, **args) + + def with_default_argument(self, first, default_arg="other"): + # Not useless because the default_arg is different from the one in the base class + super(NotUselessSuper, self).with_default_argument(first, default_arg) + + def without_default_argument(self, first, second=True): + # Not useless because in the base class there is not default value for second argument + super(NotUselessSuper, self).without_default_argument(first, second) + + def with_default_argument_none(self, first, default_arg='NotNone'): + # Not useless because the default_arg is different from the one in the base class + super(NotUselessSuper, self).with_default_argument_none(first, default_arg) + + def without_default_argument2(self, first, second=None): + # Not useless because in the base class there is not default value for second argument + super(NotUselessSuper, self).without_default_argument2(first, second) + + def with_default_argument_int(self, first, default_arg="42"): + # Not useless because the default_arg is a string whereas in the base class it's an int + super(NotUselessSuper, self).with_default_argument_int(first, default_arg) + + def with_default_argument_tuple(self, first, default_arg=("42", "a")): + # Not useless because the default_arg is different from the one in the base class + super(NotUselessSuper, self).with_default_argument_tuple(first, default_arg) + + def with_default_argument_bis(self, first, default_arg="default"): + # Although the default_arg is the same as in the base class, the call signature + # differs. Thus it is not useless. + super(NotUselessSuper, self).with_default_argument_bis(default_arg + "_argument") + + def fake_method(self, param2="other"): + super(NotUselessSuper, self).fake_method(param2) + + def with_default_arg(self, first, default_arg="only_in_super_base"): + # Not useless because the call of this method is different from the function signature + super(NotUselessSuper, self).with_default_arg(first, default_arg + "_and_here") + + def with_default_arg_bis(self, first, default_arg="default_changed"): + # Not useless because the default value is different from the SuperBase one + super(NotUselessSuper, self).with_default_arg_bis(first, default_arg) + + def with_default_arg_ter(self, first, default_arg="has_been_changed_again"): + # Not useless because the default value is different from the Base one + super(NotUselessSuper, self).with_default_arg_ter(first, default_arg) + + def with_default_arg_quad(self, first, default_arg="has_been_changed"): + # Not useless because the default value is the same as in the base but the + # call is different from the signature + super(NotUselessSuper, self).with_default_arg_quad(first, default_arg + "_and_modified") + + +class UselessSuper(Base): + + def equivalent_params(self): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params() + + def equivalent_params_1(self, first): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_1(first) + + def equivalent_params_2(self, *args): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_2(*args) + + def equivalent_params_3(self, *args, **kwargs): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_3(*args, **kwargs) + + def equivalent_params_4(self, first): # [useless-super-delegation] + super(UselessSuper, self).equivalent_params_4(first) + + def equivalent_params_5(self, first, *args): # [useless-super-delegation] + super(UselessSuper, self).equivalent_params_5(first, *args) + + def equivalent_params_6(self, first, *args, **kwargs): # [useless-super-delegation] + return super(UselessSuper, self).equivalent_params_6(first, *args, **kwargs) + + def with_default_argument(self, first, default_arg="default"): # [useless-super-delegation] + # useless because the default value here is the same as in the base class + return super(UselessSuper, self).with_default_argument(first, default_arg) + + def without_default_argument(self, first, second): # [useless-super-delegation] + return super(UselessSuper, self).without_default_argument(first, second) + + def with_default_argument_none(self, first, default_arg=None): # [useless-super-delegation] + # useless because the default value here is the same as in the base class + super(UselessSuper, self).with_default_argument_none(first, default_arg) + + def with_default_argument_int(self, first, default_arg=42): # [useless-super-delegation] + super(UselessSuper, self).with_default_argument_int(first, default_arg) + + def with_default_argument_tuple(self, first, default_arg=()): # [useless-super-delegation] + super(UselessSuper, self).with_default_argument_tuple(first, default_arg) + + def __init__(self): # [useless-super-delegation] + super(UselessSuper, self).__init__() + + def with_default_arg(self, first, default_arg="only_in_super_base"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg(first, default_arg) + + def with_default_arg_bis(self, first, default_arg="only_in_super_base"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg_bis(first, default_arg) + + def with_default_arg_ter(self, first, default_arg="has_been_changed"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg_ter(first, default_arg) + + def with_default_arg_quad(self, first, default_arg="has_been_changed"): # [useless-super-delegation] + super(UselessSuper, self).with_default_arg_quad(first, default_arg) + + +def trigger_something(value_to_trigger): + pass + + +class NotUselessSuperDecorators(Base): + @trigger_something('value1') + def method_decorated(self): + super(NotUselessSuperDecorators, self).method_decorated() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation.txt new file mode 100644 index 0000000..4426fd1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation.txt @@ -0,0 +1,17 @@ +useless-super-delegation:191:UselessSuper.equivalent_params:Useless super delegation in method 'equivalent_params' +useless-super-delegation:194:UselessSuper.equivalent_params_1:Useless super delegation in method 'equivalent_params_1' +useless-super-delegation:197:UselessSuper.equivalent_params_2:Useless super delegation in method 'equivalent_params_2' +useless-super-delegation:200:UselessSuper.equivalent_params_3:Useless super delegation in method 'equivalent_params_3' +useless-super-delegation:203:UselessSuper.equivalent_params_4:Useless super delegation in method 'equivalent_params_4' +useless-super-delegation:206:UselessSuper.equivalent_params_5:Useless super delegation in method 'equivalent_params_5' +useless-super-delegation:209:UselessSuper.equivalent_params_6:Useless super delegation in method 'equivalent_params_6' +useless-super-delegation:212:UselessSuper.with_default_argument:Useless super delegation in method 'with_default_argument' +useless-super-delegation:216:UselessSuper.without_default_argument:Useless super delegation in method 'without_default_argument' +useless-super-delegation:219:UselessSuper.with_default_argument_none:Useless super delegation in method 'with_default_argument_none' +useless-super-delegation:223:UselessSuper.with_default_argument_int:Useless super delegation in method 'with_default_argument_int' +useless-super-delegation:226:UselessSuper.with_default_argument_tuple:Useless super delegation in method 'with_default_argument_tuple' +useless-super-delegation:229:UselessSuper.__init__:Useless super delegation in method '__init__' +useless-super-delegation:232:UselessSuper.with_default_arg:Useless super delegation in method 'with_default_arg' +useless-super-delegation:235:UselessSuper.with_default_arg_bis:Useless super delegation in method 'with_default_arg_bis' +useless-super-delegation:238:UselessSuper.with_default_arg_ter:Useless super delegation in method 'with_default_arg_ter' +useless-super-delegation:241:UselessSuper.with_default_arg_quad:Useless super delegation in method 'with_default_arg_quad' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.py new file mode 100644 index 0000000..09bc25b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.py @@ -0,0 +1,43 @@ +# pylint: disable=missing-docstring, no-member, unused-argument, invalid-name,unused-variable +# pylint: disable=too-few-public-methods,wrong-import-position, useless-object-inheritance + +class NotUselessSuper(object): + + def not_passing_keyword_only(self, first, *, second): + return super(NotUselessSuper, self).not_passing_keyword_only(first) + + def passing_keyword_only_with_modifications(self, first, *, second): + return super(NotUselessSuper, self).passing_keyword_only_with_modifications( + first, second + 1) + + +class AlsoNotUselessSuper(NotUselessSuper): + def not_passing_keyword_only(self, first, *, second="second"): + return super().not_passing_keyword_only(first, second=second) + + +class UselessSuper(object): + + def useless(self, *, first): # [useless-super-delegation] + super(UselessSuper, self).useless(first=first) + + +class Egg(): + def __init__(self, thing: object) -> None: + pass + +class Spam(Egg): + def __init__(self, thing: int) -> None: + super().__init__(thing) + +class Ham(Egg): + def __init__(self, thing: object) -> None: # [useless-super-delegation] + super().__init__(thing) + + +from typing import List + + +class Test: + def __init__(self, _arg: List[int]) -> None: + super().__init__() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.rc new file mode 100644 index 0000000..c093be2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.txt new file mode 100644 index 0000000..433c7a9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py3.txt @@ -0,0 +1,2 @@ +useless-super-delegation:21:UselessSuper.useless:Useless super delegation in method 'useless' +useless-super-delegation:34:Ham.__init__:Useless super delegation in method '__init__' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.py new file mode 100644 index 0000000..ffc3c6c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.py @@ -0,0 +1,12 @@ +# pylint: disable=missing-docstring,too-few-public-methods,no-member,unused-argument, useless-object-inheritance + +class NotUselessSuper(object): + + def not_passing_all_params(self, first, *args, second=None, **kwargs): + return super(NotUselessSuper, self).not_passing_all_params(*args, second, **kwargs) + + +class UselessSuper(object): + + def useless(self, first, *, second=None, **kwargs): # [useless-super-delegation] + return super(UselessSuper, self).useless(first, second=second, **kwargs) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.rc new file mode 100644 index 0000000..71de8b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.5 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.txt new file mode 100644 index 0000000..8d9cdaa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/useless_super_delegation_py35.txt @@ -0,0 +1 @@ +useless-super-delegation:11:UselessSuper.useless:Useless super delegation in method 'useless' \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/using_constant_test.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/using_constant_test.py new file mode 100644 index 0000000..8d3c2da --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/using_constant_test.py @@ -0,0 +1,141 @@ +"""Verify if constant tests are used inside if statements.""" +# pylint: disable=invalid-name, missing-docstring,too-few-public-methods +# pylint: disable=no-init,expression-not-assigned, useless-object-inheritance + + +import collections + + +def function(): + yield + + +class Class(object): + + def method(self): + pass + + +instance = Class() + +if collections: # [using-constant-test] + pass + +# GenExpr +if (node for node in range(10)): # [using-constant-test] + pass + +if lambda: None: # [using-constant-test] + pass + +if function: # [using-constant-test] + pass + +if Class: # [using-constant-test] + pass + +if 2: # [using-constant-test] + pass + +if True: # [using-constant-test] + pass + +if '': # [using-constant-test] + pass + +if b'': # [using-constant-test] + pass + +if 2.0: # [using-constant-test] + pass + +if {}: # [using-constant-test] + pass + +if {1, 2, 3}: # [using-constant-test] + pass + +if (1, 2, 3): # [using-constant-test] + pass + +if (): # [using-constant-test] + pass + +# Generator +generator = function() +if generator: # [using-constant-test] + pass + +if 1 if 2 else 3: # [using-constant-test] + pass + +def test_comprehensions(): + [data for data in range(100) if abs] # [using-constant-test] + [data for data in range(100) if 1] # [using-constant-test] + (data for data in range(100) if abs) # [using-constant-test] + (data for data in range(100) if 1) # [using-constant-test] + {data for data in range(100) if abs} # [using-constant-test] + {data: 1 for data in range(100) if abs} # [using-constant-test] + + + +# For these, we require to do inference, even though the result can be a +# constant value. For some of them, we could determine that the test +# is constant, such as 2 + 3, but the components of the BinOp +# can be anything else (2 + somefunccall). + +name = 42 +if name: + pass + +# UnboundMethod / Function +if Class.method: + pass + +# BoundMethod +if instance.method: + pass + +if 3 + 4: + pass + +if 3 and 4: + pass + +if not 3: + pass + +if instance.method(): + pass + +# pylint: disable=misplaced-comparison-constant +if 2 < 3: + pass + +if tuple((1, 2, 3)): + pass + +if dict(): + pass + +if tuple(): + pass + +if [1, 2, 3][:1]: + pass + +def test(*args): + if args: + return 42 + return None + +def test_good_comprehension_checks(): + [data for data in range(100)] + [data for data in range(100) if data] + [data for data in range(100) if abs(data)] + (data for data in range(100) if data) + (data for data in range(100) if abs(data)) + {data for data in range(100) if data} + {data for data in range(100) if abs(data)} + {data: 1 for data in range(100) if data} + {data: 1 for data in range(100)} diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/using_constant_test.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/using_constant_test.txt new file mode 100644 index 0000000..b1c5484 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/using_constant_test.txt @@ -0,0 +1,22 @@ +using-constant-test:21::Using a conditional statement with a constant value +using-constant-test:25::Using a conditional statement with a constant value +using-constant-test:28::Using a conditional statement with a constant value +using-constant-test:31::Using a conditional statement with a constant value +using-constant-test:34::Using a conditional statement with a constant value +using-constant-test:37::Using a conditional statement with a constant value +using-constant-test:40::Using a conditional statement with a constant value +using-constant-test:43::Using a conditional statement with a constant value +using-constant-test:46::Using a conditional statement with a constant value +using-constant-test:49::Using a conditional statement with a constant value +using-constant-test:52::Using a conditional statement with a constant value +using-constant-test:55::Using a conditional statement with a constant value +using-constant-test:58::Using a conditional statement with a constant value +using-constant-test:61::Using a conditional statement with a constant value +using-constant-test:66::Using a conditional statement with a constant value +using-constant-test:69::Using a conditional statement with a constant value +using-constant-test:73:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:74:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:75:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:76:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:77:test_comprehensions:Using a conditional statement with a constant value +using-constant-test:78:test_comprehensions:Using a conditional statement with a constant value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import.py new file mode 100644 index 0000000..66ae63d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import.py @@ -0,0 +1,5 @@ +# pylint: disable=no-absolute-import,missing-docstring,import-error,unused-wildcard-import +from indirect1 import * # [wildcard-import] +# This is an unresolved import which still generates the wildcard-import +# warning. +from unknown.package import * # [wildcard-import] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import.txt new file mode 100644 index 0000000..643d818 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import.txt @@ -0,0 +1,2 @@ +wildcard-import:2::Wildcard import indirect1 +wildcard-import:5::Wildcard import unknown.package diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.py new file mode 100644 index 0000000..21fea47 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.py @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring,unused-wildcard-import,redefined-builtin,import-error +from csv import * +from abc import * # [wildcard-import] +from UNINFERABLE import * # [wildcard-import] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.rc new file mode 100644 index 0000000..c46d828 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.rc @@ -0,0 +1,2 @@ +[IMPORTS] +allow-wildcard-with-all=yes diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.txt new file mode 100644 index 0000000..ef223fa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wildcard_import_allowed.txt @@ -0,0 +1,2 @@ +wildcard-import:3::Wildcard import abc:HIGH +wildcard-import:4::Wildcard import UNINFERABLE:HIGH diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_used_before_assign.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_used_before_assign.py new file mode 100644 index 0000000..64a475a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_used_before_assign.py @@ -0,0 +1,11 @@ +''' +Regression test for +https://bitbucket.org/logilab/pylint/issue/128/attributeerror-when-parsing +''' +from __future__ import with_statement + +def do_nothing(): + """ empty """ + with open("") as ctx.obj: # [undefined-variable] + context.do() # [used-before-assignment] + context = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_used_before_assign.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_used_before_assign.txt new file mode 100644 index 0000000..783ae73 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_used_before_assign.txt @@ -0,0 +1,2 @@ +undefined-variable:9:do_nothing:Undefined variable 'ctx' +used-before-assignment:10:do_nothing:Using variable 'context' before assignment diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_using_generator.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_using_generator.py new file mode 100644 index 0000000..187bdcf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_using_generator.py @@ -0,0 +1,15 @@ +""" Testing with statements that use generators. This should not crash. """ +# pylint: disable=useless-object-inheritance + +class Base(object): + """ Base class. """ + val = 0 + + def gen(self): + """ A generator. """ + yield self.val + + def fun(self): + """ With statement using a generator. """ + with self.gen(): # [not-context-manager] + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_using_generator.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_using_generator.txt new file mode 100644 index 0000000..2b81034 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/with_using_generator.txt @@ -0,0 +1 @@ +not-context-manager:14:Base.fun:Context manager 'generator' doesn't implement __enter__ and __exit__. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order.py new file mode 100644 index 0000000..c2791d1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order.py @@ -0,0 +1,43 @@ +"""Checks import order rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level +from __future__ import absolute_import +try: + from six.moves import configparser +except ImportError: + import configparser + +import logging + +import six +import os.path # [wrong-import-order] +from astroid import are_exclusive +import sys # [wrong-import-order] +import datetime # [wrong-import-order] +import unused_import +from .package import Class +import totally_missing # [wrong-import-order] +from . import package +import astroid # [wrong-import-order] +from . import package2 +from .package2 import Class2 +from ..package3 import Class3 +from six.moves.urllib.parse import quote # [wrong-import-order] + + +LOGGER = logging.getLogger(__name__) + + +if LOGGER: + # imports nested skipped + from . import package4 + import pprint + from pprint import PrettyPrinter + + +try: + # imports nested skipped + from . import package4 + import random + from random import division +except ImportError: + LOGGER.info('A useful message here') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order.txt new file mode 100644 index 0000000..13b601e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order.txt @@ -0,0 +1,6 @@ +wrong-import-order:12::standard import "import os.path" should be placed before "import six" +wrong-import-order:14::standard import "import sys" should be placed before "import six" +wrong-import-order:15::standard import "import datetime" should be placed before "import six" +wrong-import-order:18::first party import "import totally_missing" should be placed before "from .package import Class" +wrong-import-order:20::third party import "import astroid" should be placed before "import unused_import" +wrong-import-order:24::third party import "from six.moves.urllib.parse import quote" should be placed before "import unused_import" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order2.py new file mode 100644 index 0000000..4f9a100 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_order2.py @@ -0,0 +1,16 @@ +"""Checks import order rule in a right case""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module + + +# Standard imports +import os +from sys import argv + +# external imports +import isort + +from six import moves + +# local_imports +from . import my_package +from .my_package import myClass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position.py new file mode 100644 index 0000000..88db33b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position.py @@ -0,0 +1,33 @@ +"""Checks import order rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,wrong-import-order +# pylint: disable=import-error, too-few-public-methods, missing-docstring,using-constant-test, useless-object-inheritance +import os.path + +if True: + from astroid import are_exclusive +try: + import sys +except ImportError: + class Myclass(object): + """docstring""" + +if sys.version_info[0] == 3: + from collections import OrderedDict +else: + class OrderedDict(object): + """Nothing to see here.""" + def some_func(self): + pass + +import six # [wrong-import-position] + +CONSTANT = True + +import datetime # [wrong-import-position] + +VAR = 0 +for i in range(10): + VAR += i + +import scipy # [wrong-import-position] +import astroid # [wrong-import-position] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position.txt new file mode 100644 index 0000000..e734ac5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position.txt @@ -0,0 +1,4 @@ +wrong-import-position:22::Import "import six" should be placed at the top of the module +wrong-import-position:26::Import "import datetime" should be placed at the top of the module +wrong-import-position:32::Import "import scipy" should be placed at the top of the module +wrong-import-position:33::Import "import astroid" should be placed at the top of the module diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position10.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position10.py new file mode 100644 index 0000000..f4a8680 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position10.py @@ -0,0 +1,15 @@ +"""Checks import position rule""" +# pylint: disable=unused-import +import os + +try: + import ast +except ImportError: + def method(items): + """docstring""" + value = 0 + for item in items: + value += item + return value + +import sys diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position11.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position11.py new file mode 100644 index 0000000..9af72c0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position11.py @@ -0,0 +1,4 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,pointless-string-statement +A = 1 +import os # [wrong-import-position] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position11.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position11.txt new file mode 100644 index 0000000..01bb584 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position11.txt @@ -0,0 +1 @@ +wrong-import-position:4::Import "import os" should be placed at the top of the module diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position12.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position12.py new file mode 100644 index 0000000..300968c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position12.py @@ -0,0 +1,5 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,pointless-string-statement +"Two string" + +import os # [wrong-import-position] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position12.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position12.txt new file mode 100644 index 0000000..6d56082 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position12.txt @@ -0,0 +1 @@ +wrong-import-position:5::Import "import os" should be placed at the top of the module diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position13.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position13.py new file mode 100644 index 0000000..6b3d034 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position13.py @@ -0,0 +1,4 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,no-name-in-module +A = 1 +from sys import x # [wrong-import-position] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position13.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position13.txt new file mode 100644 index 0000000..f3def19 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position13.txt @@ -0,0 +1 @@ +wrong-import-position:4::Import "from sys import x" should be placed at the top of the module diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position14.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position14.py new file mode 100644 index 0000000..f5c9a03 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position14.py @@ -0,0 +1,5 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,undefined-variable,import-error +if x: + import os +import y # [wrong-import-position] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position14.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position14.txt new file mode 100644 index 0000000..9fcdac5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position14.txt @@ -0,0 +1 @@ +wrong-import-position:5::Import "import y" should be placed at the top of the module diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position15.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position15.py new file mode 100644 index 0000000..58a19b6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position15.py @@ -0,0 +1,9 @@ +"""Checks import position rule with pep-0008""" +# pylint: disable=unused-import + +__author__ = 'some author' +__email__ = 'some.author@some_email' +__copyright__ = 'Some copyright' + + +import sys diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position2.py new file mode 100644 index 0000000..65ad9e6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position2.py @@ -0,0 +1,10 @@ +"""Checks import order rule with nested non_import sentence""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level +try: + from sys import argv +except ImportError: + pass +else: + pass + +import os diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position3.py new file mode 100644 index 0000000..d2cf685 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position3.py @@ -0,0 +1,3 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level +import os diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position4.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position4.py new file mode 100644 index 0000000..3f1174f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position4.py @@ -0,0 +1,5 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level,unused-variable +def method1(): + """Method 1""" + import x diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position5.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position5.py new file mode 100644 index 0000000..b96a8a0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position5.py @@ -0,0 +1,4 @@ +r"""Checks import position rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level + +import os diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position6.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position6.py new file mode 100644 index 0000000..694c109 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position6.py @@ -0,0 +1,7 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level,undefined-variable + +import y + +if x: + import os diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position7.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position7.py new file mode 100644 index 0000000..bb50956 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position7.py @@ -0,0 +1,9 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level +try: + import x +except ImportError: + pass +finally: + pass +import y diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position8.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position8.py new file mode 100644 index 0000000..cd1028a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position8.py @@ -0,0 +1,4 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level,undefined-variable +if x: + import os diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position9.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position9.py new file mode 100644 index 0000000..a08880b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position9.py @@ -0,0 +1,9 @@ +"""Checks import position rule""" +# pylint: disable=unused-import,relative-import,ungrouped-imports,import-error,no-name-in-module,relative-beyond-top-level +import y +try: + import x +except ImportError: + pass +else: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position_exclude_dunder_main.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position_exclude_dunder_main.py new file mode 100644 index 0000000..05f6803 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position_exclude_dunder_main.py @@ -0,0 +1,12 @@ +# pylint: disable=import-error, unused-import, missing-docstring +CONS = 42 + +if __name__ == '__main__': + CONSTANT = True + VAR = 0 + for i in range(10): + VAR += i + + import six + import datetime + import astroid diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position_exclude_dunder_main.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/wrong_import_position_exclude_dunder_main.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.py new file mode 100644 index 0000000..7803936 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.py @@ -0,0 +1,7 @@ +""" +Check that `yield from`-statement takes an iterable. +""" +# pylint: disable=missing-docstring + +def to_ten(): + yield from 10 # [not-an-iterable] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.rc new file mode 100644 index 0000000..3330edd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.3 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.txt new file mode 100644 index 0000000..8dec6d2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_iterable_py33.txt @@ -0,0 +1 @@ +not-an-iterable:7:to_ten:Non-iterable value 10 is used in an iterating context diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.py new file mode 100644 index 0000000..e2db90c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.py @@ -0,0 +1,4 @@ +"""This is gramatically correct, but it's still a SyntaxError""" +yield from [1, 2] # [yield-outside-function] + +LAMBDA_WITH_YIELD = lambda: (yield from [1, 2]) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.rc new file mode 100644 index 0000000..28c99bc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.txt new file mode 100644 index 0000000..fa3a7fc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_from_outside_func.txt @@ -0,0 +1 @@ +yield-outside-function:2::Yield outside function diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.py new file mode 100644 index 0000000..a0d67f8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.py @@ -0,0 +1,12 @@ +"""Test that `yield` or `yield from` can't be used inside an async function.""" +# pylint: disable=missing-docstring, unused-variable + +async def good_coro(): + def _inner(): + yield 42 + yield from [1, 2, 3] + + +async def bad_coro(): + yield 42 # [yield-inside-async-function] + yield from [1, 2, 3] # [yield-inside-async-function] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.rc new file mode 100644 index 0000000..0a040cb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.rc @@ -0,0 +1,3 @@ +[testoptions] +min_pyver=3.5 +max_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.txt new file mode 100644 index 0000000..ae97cae --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function.txt @@ -0,0 +1,2 @@ +yield-inside-async-function:11:bad_coro:Yield inside async function +yield-inside-async-function:12:bad_coro:Yield inside async function \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.py new file mode 100644 index 0000000..db78011 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.py @@ -0,0 +1,12 @@ +"""Test that `yield` or `yield from` can't be used inside an async function.""" +# pylint: disable=missing-docstring, unused-variable + +async def good_coro(): + def _inner(): + yield 42 + yield from [1, 2, 3] + + +async def bad_coro(): + yield 42 + yield from [1, 2, 3] # [yield-inside-async-function] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.rc new file mode 100644 index 0000000..0ba2b63 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.6 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.txt new file mode 100644 index 0000000..d6e68d0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_inside_async_function_py36.txt @@ -0,0 +1 @@ +yield-inside-async-function:12:bad_coro:Yield inside async function diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_outside_func.py b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_outside_func.py new file mode 100644 index 0000000..5824bc0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_outside_func.py @@ -0,0 +1,4 @@ +"""This is gramatically correct, but it's still a SyntaxError""" +yield 1 # [yield-outside-function] + +LAMBDA_WITH_YIELD = lambda: (yield) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_outside_func.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_outside_func.txt new file mode 100644 index 0000000..fa3a7fc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/functional/yield_outside_func.txt @@ -0,0 +1 @@ +yield-outside-function:2::Yield outside function diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__init__.py new file mode 100644 index 0000000..60e92b7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__init__.py @@ -0,0 +1 @@ +"""test""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..7ab6fba Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_3k_removed_stuff_py_30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_3k_removed_stuff_py_30.cpython-37.pyc new file mode 100644 index 0000000..c493159 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_3k_removed_stuff_py_30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_bad_cont_dictcomp_py27.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_bad_cont_dictcomp_py27.cpython-37.pyc new file mode 100644 index 0000000..0dd5ead Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_bad_cont_dictcomp_py27.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_bug113231.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_bug113231.cpython-37.pyc new file mode 100644 index 0000000..fe4a9c3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_bug113231.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_disable_linebased.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_disable_linebased.cpython-37.pyc new file mode 100644 index 0000000..f0d982d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_disable_linebased.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_dotted_ancestor.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_dotted_ancestor.cpython-37.pyc new file mode 100644 index 0000000..045f9cf Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_dotted_ancestor.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e0012.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e0012.cpython-37.pyc new file mode 100644 index 0000000..4e06cb8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e0012.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e0204.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e0204.cpython-37.pyc new file mode 100644 index 0000000..a24e864 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e0204.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e12xx.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e12xx.cpython-37.pyc new file mode 100644 index 0000000..be9b097 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e12xx.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e13xx.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e13xx.cpython-37.pyc new file mode 100644 index 0000000..3278000 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_e13xx.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_excess_escapes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_excess_escapes.cpython-37.pyc new file mode 100644 index 0000000..17f93d2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_excess_escapes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_first_arg.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_first_arg.cpython-37.pyc new file mode 100644 index 0000000..196bd67 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_first_arg.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0011.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0011.cpython-37.pyc new file mode 100644 index 0000000..4b93620 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0011.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0012.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0012.cpython-37.pyc new file mode 100644 index 0000000..f2deff3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0012.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0013.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0013.cpython-37.pyc new file mode 100644 index 0000000..cb9c595 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0013.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0014.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0014.cpython-37.pyc new file mode 100644 index 0000000..6400907 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0014.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0020.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0020.cpython-37.pyc new file mode 100644 index 0000000..a61ffd5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0020.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0022.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0022.cpython-37.pyc new file mode 100644 index 0000000..5d6918a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_i0022.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_logging_not_lazy_with_logger.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_logging_not_lazy_with_logger.cpython-37.pyc new file mode 100644 index 0000000..f3b6dea Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_logging_not_lazy_with_logger.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_loopvar_in_dict_comp_py27.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_loopvar_in_dict_comp_py27.cpython-37.pyc new file mode 100644 index 0000000..977419e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_loopvar_in_dict_comp_py27.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_module___dict__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_module___dict__.cpython-37.pyc new file mode 100644 index 0000000..5ffcaf0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_module___dict__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_nameerror_on_string_substitution.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_nameerror_on_string_substitution.cpython-37.pyc new file mode 100644 index 0000000..a3ac9e1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_nameerror_on_string_substitution.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_no_dummy_redefined.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_no_dummy_redefined.cpython-37.pyc new file mode 100644 index 0000000..80f5293 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_no_dummy_redefined.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror___init___return_from_inner_function.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror___init___return_from_inner_function.cpython-37.pyc new file mode 100644 index 0000000..2caa678 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror___init___return_from_inner_function.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_access_attr_before_def_false_positive.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_access_attr_before_def_false_positive.cpython-37.pyc new file mode 100644 index 0000000..168c64d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_access_attr_before_def_false_positive.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_base_init_vars.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_base_init_vars.cpython-37.pyc new file mode 100644 index 0000000..d8cb1cb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_base_init_vars.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_builtin_module_test.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_builtin_module_test.cpython-37.pyc new file mode 100644 index 0000000..9dba918 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_builtin_module_test.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_class_attributes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_class_attributes.cpython-37.pyc new file mode 100644 index 0000000..c94d25b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_class_attributes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_classes_meth_could_be_a_function.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_classes_meth_could_be_a_function.cpython-37.pyc new file mode 100644 index 0000000..3bfc6cc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_classes_meth_could_be_a_function.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_classes_protected_member_access.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_classes_protected_member_access.cpython-37.pyc new file mode 100644 index 0000000..37c8464 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_classes_protected_member_access.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_decorator_scope.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_decorator_scope.cpython-37.pyc new file mode 100644 index 0000000..39f59ce Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_decorator_scope.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_e1101_9588_base_attr_aug_assign.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_e1101_9588_base_attr_aug_assign.cpython-37.pyc new file mode 100644 index 0000000..ebd7d10 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_e1101_9588_base_attr_aug_assign.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_external_classmethod_crash.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_external_classmethod_crash.cpython-37.pyc new file mode 100644 index 0000000..0cf69fa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_external_classmethod_crash.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_inner_classes.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_inner_classes.cpython-37.pyc new file mode 100644 index 0000000..908dadc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_inner_classes.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_lambda_use_before_assign.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_lambda_use_before_assign.cpython-37.pyc new file mode 100644 index 0000000..2540d07 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_lambda_use_before_assign.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_mcs_attr_access.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_mcs_attr_access.cpython-37.pyc new file mode 100644 index 0000000..5ef1421 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_mcs_attr_access.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_new_style_class_py_30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_new_style_class_py_30.cpython-37.pyc new file mode 100644 index 0000000..95d2117 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_new_style_class_py_30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_no_warning_docstring.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_no_warning_docstring.cpython-37.pyc new file mode 100644 index 0000000..f68b5d0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_no_warning_docstring.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_object_as_class_attribute.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_object_as_class_attribute.cpython-37.pyc new file mode 100644 index 0000000..18d86fc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_object_as_class_attribute.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_overloaded_operator.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_overloaded_operator.cpython-37.pyc new file mode 100644 index 0000000..bed7fc8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_overloaded_operator.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_property_affectation_py26.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_property_affectation_py26.cpython-37.pyc new file mode 100644 index 0000000..7315777 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_property_affectation_py26.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_yield_assign_py25.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_yield_assign_py25.cpython-37.pyc new file mode 100644 index 0000000..a9a50f7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_yield_assign_py25.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_yield_return_mix.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_yield_return_mix.cpython-37.pyc new file mode 100644 index 0000000..4201db5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_noerror_yield_return_mix.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_nonregr___file___global.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_nonregr___file___global.cpython-37.pyc new file mode 100644 index 0000000..3b8715b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_nonregr___file___global.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_return_yield_mix_py_33.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_return_yield_mix_py_33.cpython-37.pyc new file mode 100644 index 0000000..a18c6c6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_return_yield_mix_py_33.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_typecheck_callfunc_assigment.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_typecheck_callfunc_assigment.cpython-37.pyc new file mode 100644 index 0000000..9184f3f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_typecheck_callfunc_assigment.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_unused_import_py30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_unused_import_py30.cpython-37.pyc new file mode 100644 index 0000000..66eb9ff Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_unused_import_py30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_variables_unused_name_from_wilcard_import.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_variables_unused_name_from_wilcard_import.cpython-37.pyc new file mode 100644 index 0000000..bada0cb Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_variables_unused_name_from_wilcard_import.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0233.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0233.cpython-37.pyc new file mode 100644 index 0000000..d330dcc Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0233.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401.cpython-37.pyc new file mode 100644 index 0000000..ac84d12 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401_disabled.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401_disabled.cpython-37.pyc new file mode 100644 index 0000000..df82521 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401_disabled.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401_disabled_in_func.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401_disabled_in_func.cpython-37.pyc new file mode 100644 index 0000000..0c53ce5 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0401_disabled_in_func.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0404.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0404.cpython-37.pyc new file mode 100644 index 0000000..318aaec Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0404.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0405.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0405.cpython-37.pyc new file mode 100644 index 0000000..6d71289 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0405.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0406.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0406.cpython-37.pyc new file mode 100644 index 0000000..f44e297 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0406.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0611.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0611.cpython-37.pyc new file mode 100644 index 0000000..6e325af Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0611.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0612.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0612.cpython-37.pyc new file mode 100644 index 0000000..a9712d1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0612.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0613.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0613.cpython-37.pyc new file mode 100644 index 0000000..ab52952 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0613.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0623_py30.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0623_py30.cpython-37.pyc new file mode 100644 index 0000000..96aad9a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0623_py30.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0801.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0801.cpython-37.pyc new file mode 100644 index 0000000..1e7f5fa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/func_w0801.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/hide_code_with_imports.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/hide_code_with_imports.cpython-37.pyc new file mode 100644 index 0000000..dd6152d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/hide_code_with_imports.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/ignore_except_pass_by_default.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/ignore_except_pass_by_default.cpython-37.pyc new file mode 100644 index 0000000..220ad22 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/ignore_except_pass_by_default.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/not__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/not__init__.cpython-37.pyc new file mode 100644 index 0000000..44b1b2e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/not__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/w0401_cycle.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/w0401_cycle.cpython-37.pyc new file mode 100644 index 0000000..aae8d01 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/w0401_cycle.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/w0801_same.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/w0801_same.cpython-37.pyc new file mode 100644 index 0000000..eadb42b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/__pycache__/w0801_same.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_3k_removed_stuff_py_30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_3k_removed_stuff_py_30.py new file mode 100644 index 0000000..54ad935 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_3k_removed_stuff_py_30.py @@ -0,0 +1,13 @@ +"""test relative import""" +# pylint: disable=no-absolute-import +from __future__ import print_function +import func_w0401 +__revision__ = filter(None, map(str, (1, 2, 3))) + + +def function(): + """something""" + print(func_w0401) + unic = u"unicode" + low = unic.looower + return low diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_bad_cont_dictcomp_py27.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_bad_cont_dictcomp_py27.py new file mode 100644 index 0000000..a552710 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_bad_cont_dictcomp_py27.py @@ -0,0 +1,38 @@ +"""Bad continuations in dictionary comprehensions.""" + +__revision__ = 0 + +# Dictionary comprehensions should not require extra indentation when breaking +# before the 'for', which is not part of the value +C1 = {'key{}'.format(x): 'value{}'.format(x) + for x in range(3)} + +C2 = {'key{}'.format(x): 'value{}'.format(x) for x in + range(3)} + +# Dictionary comprehensions with multiple loops broken in different places +C3 = {x*y: (x, y) for x in range(3) for y in range(3)} + +C4 = {x*y: (x, y) + for x in range(3) for y in range(3)} + +C5 = {x*y: (x, y) for x + in range(3) for y in range(3)} + +C6 = {x*y: (x, y) for x in range(3) + for y in range(3)} + +C7 = {key: + key ** 2 + for key in range(10)} + +C8 = { + key: key ** 2 + for key in range(10)} + +# Misaligned cases for dict comprehensions +C9 = {'key{}'.format(x): 'value{}'.format(x) + for x in range(3)} # [bad-continuation] + +C9 = {'key{}'.format(x): 'value{}'.format(x) + for x in range(3)} # [bad-continuation] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_bug113231.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_bug113231.py new file mode 100644 index 0000000..6334ff9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_bug113231.py @@ -0,0 +1,24 @@ +# pylint: disable=E1101 +# pylint: disable=C0103 +# pylint: disable=R0903, useless-object-inheritance, unnecessary-pass +"""test bugfix for #113231 in logging checker +""" +from __future__ import absolute_import +# Muck up the names in an effort to confuse... +import logging as renamed_logging + +__revision__ = '' + +class Logger(object): + """Fake logger""" + pass + +logger = renamed_logging.getLogger(__name__) +fake_logger = Logger() + +# Statements that should be flagged: +renamed_logging.warning('%s, %s' % (4, 5)) +logger.warning('%s' % 5) + +# Statements that should not be flagged: +fake_logger.warn('%s' % 5) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_disable_linebased.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_disable_linebased.py new file mode 100644 index 0000000..b94c2e3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_disable_linebased.py @@ -0,0 +1,14 @@ +# This is a very very very very very very very very very very very very very very very very very very very very very long line. +# pylint: disable=line-too-long +"""Make sure enable/disable pragmas work for messages that are applied to lines and not syntax nodes. + +A disable pragma for a message that applies to nodes is applied to the whole +block if it comes before the first statement (excluding the docstring). For +line-based messages, this behavior needs to be altered to really only apply to +the enclosed lines. +""" +# pylint: enable=line-too-long + +from __future__ import print_function + +print('This is a very long line which the linter will warn about, now that line-too-long has been enabled again.') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_dotted_ancestor.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_dotted_ancestor.py new file mode 100644 index 0000000..ff32858 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_dotted_ancestor.py @@ -0,0 +1,11 @@ +"""bla""" +# pylint: disable=no-absolute-import + +from input import func_w0233 + +__revision__ = 'yo' + +class Aaaa(func_w0233.AAAA): + """test dotted name in ancestors""" + def __init__(self): + func_w0233.AAAA.__init__(self) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e0012.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e0012.py new file mode 100644 index 0000000..f4810ee --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e0012.py @@ -0,0 +1,4 @@ +# pylint:enable=W04044 +"""check unknown option +""" +__revision__ = 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e0204.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e0204.py new file mode 100644 index 0000000..9a0f708 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e0204.py @@ -0,0 +1,20 @@ +"""check for method without self as first argument +""" +# pylint: disable=useless-object-inheritance +from __future__ import print_function +__revision__ = 0 + + +class Abcd(object): + """dummy class""" + + def __init__(truc): + """method without self""" + print(1) + + def abdc(yoo): + """another test""" + print(yoo) + def edf(self): + """just another method""" + print('yapudju in', self) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e12xx.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e12xx.py new file mode 100644 index 0000000..74984d9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e12xx.py @@ -0,0 +1,28 @@ +# pylint: disable=E1101, no-absolute-import +"""Test checking of log format strings +""" + +import logging + +__revision__ = '' + + +def pprint(): + """Test string format in logging statements. + """ + # These should all emit lint errors: + logging.info(0, '') # 1205 + logging.info('', '') # 1205 + logging.info('%s%', '') # 1201 + logging.info('%s%s', '') # 1206 + logging.info('%s%y', '', '') # 1200 + logging.info('%s%s', '', '', '') # 1205 + + # These should be okay: + logging.info(1) + logging.info(True) + logging.info('') + logging.info('%s%') + logging.info('%s', '') + logging.info('%s%%', '') + logging.info('%s%s', '', '') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e13xx.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e13xx.py new file mode 100644 index 0000000..227311c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_e13xx.py @@ -0,0 +1,21 @@ +"""test string format error +""" +# pylint: disable=print-statement,unsupported-binary-operation +from __future__ import print_function + +PARG_1 = PARG_2 = PARG_3 = 1 + +def pprint(): + """Test string format + """ + print("%s %s" % {'PARG_1': 1, 'PARG_2': 2}) # E1306 + print("%s" % (PARG_1, PARG_2)) # E1305 + print("%(PARG_1)d %d" % {'PARG_1': 1, 'PARG_2': 2}) # E1302 + print("%(PARG_1)d %(PARG_2)d" % {'PARG_1': 1}) # E1304 + print("%(PARG_1)d %(PARG_2)d" % {'PARG_1': 1, 'PARG_2':2, 'PARG_3':3}) #W1301 + print("%(PARG_1)d %(PARG_2)d" % {'PARG_1': 1, 2:3}) # W1300 E1304 + print("%(PARG_1)d %(PARG_2)d" % (2, 3)) # 1303 + print("%(PARG_1)d %(PARG_2)d" % [2, 3]) # 1303 + print("%2z" % PARG_1) + print("strange format %2" % PARG_2) + print("works in 3 %a" % 1) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_excess_escapes.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_excess_escapes.py new file mode 100644 index 0000000..9542021 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_excess_escapes.py @@ -0,0 +1,30 @@ +# pylint:disable=W0105, W0511, misplaced-comparison-constant, comparison-with-itself +"""Stray backslash escapes may be missing a raw-string prefix.""" + +__revision__ = '$Id$' + +# Bad escape sequences, which probably don't do what you expect. +A = "\[\]\\" +assert '\/' == '\\/' +ESCAPE_BACKSLASH = '\`' + +# Valid escape sequences. +NEWLINE = "\n" +OLD_ESCAPES = '\a\b\f\n\t\r\v' +HEX = '\xad\x0a\x0d' +FALSE_OCTAL = '\o123\o000' # Not octal in Python +OCTAL = '\123\000' +NOT_OCTAL = '\888\999' +NUL = '\0' +UNICODE = u'\u1234' +HIGH_UNICODE = u'\U0000abcd' +QUOTES = '\'\"' +LITERAL_NEWLINE = '\ +' +ESCAPE_UNICODE = "\\\\n" + +# Bad docstring +"""Even in a docstring + +You shouldn't have ambiguous text like: C:\Program Files\alpha +""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_first_arg.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_first_arg.py new file mode 100644 index 0000000..7df2fd2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_first_arg.py @@ -0,0 +1,42 @@ +# pylint: disable=C0111, W0232, useless-object-inheritance +"""check for methods first arguments +""" + +__revision__ = 0 + + +class Obj(object): + # C0202, classmethod + def __new__(something): + pass + + # C0202, classmethod + def class1(cls): + pass + class1 = classmethod(class1) + + def class2(other): + pass + class2 = classmethod(class2) + + +class Meta(type): + # C0204, metaclass __new__ + def __new__(other, name, bases, dct): + pass + + # C0203, metaclass method + def method1(cls): + pass + + def method2(other): + pass + + # C0205, metaclass classmethod + def class1(cls): + pass + class1 = classmethod(class1) + + def class2(other): + pass + class2 = classmethod(class2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0011.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0011.py new file mode 100644 index 0000000..a4ef215 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0011.py @@ -0,0 +1,4 @@ +# pylint:disable=W0404 +"""check warning on local disabling +""" +__revision__ = 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0012.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0012.py new file mode 100644 index 0000000..9b6fbe7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0012.py @@ -0,0 +1,4 @@ +# pylint:enable=W0404 +"""check warning on local enabling +""" +__revision__ = 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0013.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0013.py new file mode 100644 index 0000000..0a3f833 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0013.py @@ -0,0 +1,8 @@ +# pylint: skip-file +"""disable-all is usable as an inline option""" + +# no warning should be issued +try: + import this +except: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0014.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0014.py new file mode 100644 index 0000000..63ff37c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0014.py @@ -0,0 +1,8 @@ +# pylint: disable-all +"""disable-all is usable as an inline option""" + +# no warning should be issued +try: + import this +except: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0020.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0020.py new file mode 100644 index 0000000..8c0fe9f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0020.py @@ -0,0 +1,8 @@ +"""Test for reporting of suppressed messages.""" + +__revision__ = 0 + +def suppressed(): + """A function with an unused variable.""" + # pylint: disable=W0612 + var = 0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0022.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0022.py new file mode 100644 index 0000000..f5b308f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_i0022.py @@ -0,0 +1,22 @@ +"""Deprecated suppression style.""" + +__revision__ = None + +a = 1 # pylint: disable=invalid-name +b = 1 # pylint: disable-msg=invalid-name + +# pylint: disable=invalid-name +c = 1 +# pylint: enable=invalid-name + +# pylint: disable-msg=invalid-name +d = 1 +# pylint: enable-msg=invalid-name + +# pylint: disable-msg=C0103 +e = 1 +# pylint: enable-msg=C0103 + +# pylint: disable=C0103 +f = 1 +# pylint: enable=C0103 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_logging_not_lazy_with_logger.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_logging_not_lazy_with_logger.py new file mode 100644 index 0000000..973a5c7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_logging_not_lazy_with_logger.py @@ -0,0 +1,13 @@ +"""Logging warnings using a logger class.""" +from __future__ import absolute_import +import logging + +__revision__ = '' + +LOG = logging.getLogger("domain") +LOG.debug("%s" % "junk") +LOG.log(logging.DEBUG, "%s" % "junk") +LOG2 = LOG.debug +LOG2("%s" % "junk") + +logging.getLogger("domain").debug("%s" % "junk") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_loopvar_in_dict_comp_py27.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_loopvar_in_dict_comp_py27.py new file mode 100644 index 0000000..312eee7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_loopvar_in_dict_comp_py27.py @@ -0,0 +1,8 @@ +"""Tests for loopvar-in-closure.""" + +__revision__ = 0 + + +def bad_case(): + """Loop variable from dict comprehension.""" + return {x: lambda: x for x in range(10)} diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_module___dict__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_module___dict__.py new file mode 100644 index 0000000..5451422 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_module___dict__.py @@ -0,0 +1,9 @@ +"""http://www.logilab.org/ticket/6949.""" +from __future__ import print_function +__revision__ = None + +print(__dict__ is not None) + +__dict__ = {} + +print(__dict__ is not None) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_nameerror_on_string_substitution.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_nameerror_on_string_substitution.py new file mode 100644 index 0000000..be7b5c8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_nameerror_on_string_substitution.py @@ -0,0 +1,8 @@ +"""pylint doesn't see the NameError in this module""" + +__revision__ = None + +MSG = "hello %s" % MSG + +MSG2 = ("hello %s" % + MSG2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_no_dummy_redefined.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_no_dummy_redefined.py new file mode 100644 index 0000000..a5c0aea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_no_dummy_redefined.py @@ -0,0 +1,14 @@ +"""Make sure warnings about redefinitions do not trigger for dummy variables.""" +from __future__ import print_function + + +_, INTERESTING = 'a=b'.split('=') + +value = 10 + + +def clobbering(): + """Clobbers a dummy name from the outer scope.""" + value = 9 + for _ in range(7): + print(value) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror___init___return_from_inner_function.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror___init___return_from_inner_function.py new file mode 100644 index 0000000..769d5ac --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror___init___return_from_inner_function.py @@ -0,0 +1,12 @@ +# pylint: disable=R0903, useless-object-inheritance +"""#10075""" + +__revision__ = 1 + +class Aaa(object): + """docstring""" + def __init__(self): + def inner_function(arg): + """inner docstring""" + return arg + 4 + self.func = inner_function diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_access_attr_before_def_false_positive.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_access_attr_before_def_false_positive.py new file mode 100644 index 0000000..3884c99 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_access_attr_before_def_false_positive.py @@ -0,0 +1,98 @@ +#pylint: disable=C0103,R0904,R0903,W0201,no-absolute-import, useless-object-inheritance +""" +This module demonstrates a possible problem of pyLint with calling __init__ s +from inherited classes. +Initializations done there are not considered, which results in Error E0203 for +self.cookedq. +""" + +from __future__ import print_function + +import telnetlib + +class SeeTelnet(telnetlib.Telnet): + """ + Extension of telnetlib. + """ + + def __init__(self, host=None, port=0): + """ + Constructor. + When called without arguments, create an unconnected instance. + With a hostname argument, it connects the instance; a port + number is optional. + Parameter: + - host: IP address of the host + - port: Port number + """ + telnetlib.Telnet.__init__(self, host, port) + + def readUntilArray(self, matches, _=None): + """ + Read until a given string is encountered or until timeout. + ... + """ + self.process_rawq() + maxLength = 0 + for match in matches: + if len(match) > maxLength: + maxLength = len(match) + +class Base(object): + """bla bla""" + dougloup_papa = None + + def __init__(self): + self._var = False + +class Derived(Base): + """derived blabla""" + dougloup_moi = None + def Work(self): + """do something""" + # E0203 - Access to member '_var' before its definition + if self._var: + print("True") + else: + print("False") + self._var = True + + # E0203 - Access to member 'dougloup_papa' before its definition + if self.dougloup_papa: + print('dougloup !') + self.dougloup_papa = True + # E0203 - Access to member 'dougloup_moi' before its definition + if self.dougloup_moi: + print('dougloup !') + self.dougloup_moi = True + + +class QoSALConnection(object): + """blabla""" + + _the_instance = None + + def __new__(cls): + if cls._the_instance is None: + cls._the_instance = object.__new__(cls) + return cls._the_instance + + def __init__(self): + pass + +class DefinedOutsideInit(object): + """use_attr is seen as the method defining attr because its in + first position + """ + def __init__(self): + self.reset() + + def use_attr(self): + """use and set members""" + if self.attr: + print('hop') + self.attr = 10 + + def reset(self): + """reset members""" + self.attr = 4 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_base_init_vars.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_base_init_vars.py new file mode 100644 index 0000000..152cbfd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_base_init_vars.py @@ -0,0 +1,35 @@ +# pylint:disable=R0201, print-statement, too-few-public-methods, useless-object-inheritance +"""Checks that class variables are seen as inherited ! +""" +__revision__ = '' + +class BaseClass(object): + """A simple base class + """ + + def __init__(self): + self.base_var = {} + + def met(self): + """yo""" + def meeting(self, with_): + """ye""" + return with_ +class MyClass(BaseClass): + """Inherits from BaseClass + """ + + def __init__(self): + BaseClass.__init__(self) + self.var = {} + + def met(self): + """Checks that base_var is not seen as defined outsite '__init__' + """ + self.var[1] = 'one' + self.base_var[1] = 'one' + return self.base_var, self.var + +if __name__ == '__main__': + OBJ = MyClass() + OBJ.met() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_builtin_module_test.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_builtin_module_test.py new file mode 100644 index 0000000..9b1e7ce --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_builtin_module_test.py @@ -0,0 +1,11 @@ +"""test import from a builtin module""" + +from __future__ import absolute_import +from math import log10 + +__revision__ = None + + +def log10_2(): + """bla bla bla""" + return log10(2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_class_attributes.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_class_attributes.py new file mode 100644 index 0000000..b6fd460 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_class_attributes.py @@ -0,0 +1,18 @@ +"""Test that valid class attribute doesn't trigger errors""" +__revision__ = 'sponge bob' +# pylint: disable=useless-object-inheritance + +class Clazz(object): + "dummy class" + + def __init__(self): + self.topic = 5 + self._data = 45 + + def change_type(self, new_class): + """Change type""" + self.__class__ = new_class + + def do_nothing(self): + "I do nothing useful" + return self.topic + 56 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_classes_meth_could_be_a_function.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_classes_meth_could_be_a_function.py new file mode 100644 index 0000000..05a6c40 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_classes_meth_could_be_a_function.py @@ -0,0 +1,33 @@ +# pylint: disable=C0111,R0903,W0232, useless-object-inheritance +""" +#2479 + +R0201 (formely W0212), Method could be a function shouldn't be emitted in case +like factory method pattern +""" +__revision__ = 1 + +class XAsub(object): + pass +class XBsub(XAsub): + pass +class XCsub(XAsub): + pass + +class Aimpl(object): + # disable "method could be a function" on classes which are not overriding + # the factory method because in that case the usage of polymorphism is not + # detected + # pylint: disable=R0201 + def makex(self): + return XAsub() + +class Bimpl(Aimpl): + + def makex(self): + return XBsub() + +class Cimpl(Aimpl): + + def makex(self): + return XCsub() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_classes_protected_member_access.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_classes_protected_member_access.py new file mode 100644 index 0000000..516efd7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_classes_protected_member_access.py @@ -0,0 +1,26 @@ +""" +#3123: W0212 false positive on static method +""" +__revision__ = 1 + +# pylint: disable=no-classmethod-decorator, no-staticmethod-decorator, useless-object-inheritance +class A3123(object): + """oypuee""" + _protected = 1 + def __init__(self): + pass + + + def cmeth(cls, val): + """set protected member""" + cls._protected = +val + + cmeth = classmethod(cmeth) + + def smeth(val): + """set protected member""" + A3123._protected += val + + smeth = staticmethod(smeth) + + prop = property(lambda self: self._protected) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_decorator_scope.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_decorator_scope.py new file mode 100644 index 0000000..8d35159 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_decorator_scope.py @@ -0,0 +1,19 @@ +# -*- pylint: disable=W0232,R0903, useless-object-inheritance +"""Test that decorators sees the class namespace - just like +function default values does but function body doesn't. + +https://www.logilab.net/elo/ticket/3711 - bug finding decorator arguments +https://www.logilab.net/elo/ticket/5626 - name resolution bug inside classes +""" + +from __future__ import print_function + +class Test(object): + """test class""" + ident = lambda x: x + + @ident(ident) + def method(self, val=ident(7), func=ident): + """hop""" + print(self) + return func(val) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_e1101_9588_base_attr_aug_assign.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_e1101_9588_base_attr_aug_assign.py new file mode 100644 index 0000000..14be398 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_e1101_9588_base_attr_aug_assign.py @@ -0,0 +1,38 @@ +# pylint: disable=R0903, useless-object-inheritance +""" +False positive case of E1101: + +The error is triggered when the attribute set in the base class is +modified with augmented assignment in a derived class. + +http://www.logilab.org/ticket/9588 +""" +__revision__ = 0 + +class BaseClass(object): + "The base class" + def __init__(self): + "Set an attribute." + self.e1101 = 1 + +class FalsePositiveClass(BaseClass): + "The first derived class which triggers the false positive" + def __init__(self): + "Augmented assignment triggers E1101." + BaseClass.__init__(self) + self.e1101 += 1 + + def countup(self): + "Consequently this also triggers E1101." + self.e1101 += 1 + +class NegativeClass(BaseClass): + "The second derived class, which does not trigger the error E1101" + def __init__(self): + "Ordinary assignment is OK." + BaseClass.__init__(self) + self.e1101 = self.e1101 + 1 + + def countup(self): + "No problem." + self.e1101 += 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_external_classmethod_crash.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_external_classmethod_crash.py new file mode 100644 index 0000000..e9842a5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_external_classmethod_crash.py @@ -0,0 +1,21 @@ +# pylint: disable=W0232,R0903,W0613, useless-object-inheritance +"""tagging a function as a class method cause a crash when checking for +signature overriding +""" + +def fetch_config(mainattr=None): + """return a class method""" + + def fetch_order(cls, attr, var): + """a class method""" + if attr == mainattr: + return var + return None + fetch_order = classmethod(fetch_order) + return fetch_order + +class Aaa(object): + """hop""" + fetch_order = fetch_config('A') + +__revision__ = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_inner_classes.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_inner_classes.py new file mode 100644 index 0000000..24a2edb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_inner_classes.py @@ -0,0 +1,33 @@ +# pylint: disable=R0903, useless-object-inheritance, unnecessary-pass +"""Backend Base Classes for the schwelm user DB""" + +__revision__ = "alpha" + +class Aaa(object): + """docstring""" + def __init__(self): + self.__setattr__('a', 'b') + + + def one_public(self): + """docstring""" + pass + + def another_public(self): + """docstring""" + pass + +class Bbb(Aaa): + """docstring""" + pass + +class Ccc(Aaa): + """docstring""" + + class Ddd(Aaa): + """docstring""" + pass + + class Eee(Ddd): + """docstring""" + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_lambda_use_before_assign.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_lambda_use_before_assign.py new file mode 100644 index 0000000..af2775c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_lambda_use_before_assign.py @@ -0,0 +1,8 @@ +"""https://www.logilab.net/elo/ticket/18862""" +from __future__ import print_function +__revision__ = 1 +def function(): + """hop""" + ggg = lambda: xxx + xxx = 1 + print(ggg()) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_mcs_attr_access.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_mcs_attr_access.py new file mode 100644 index 0000000..149e078 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_mcs_attr_access.py @@ -0,0 +1,20 @@ +# pylint: disable=R0903, metaclass-assignment, useless-object-inheritance +"""test attribute access on metaclass""" + + +from __future__ import print_function + +class Meta(type): + """the meta class""" + def __init__(cls, name, bases, dictionary): + super(Meta, cls).__init__(name, bases, dictionary) + print(cls, cls._meta_args) + delattr(cls, '_meta_args') + +class Test(object): + """metaclassed class""" + __metaclass__ = Meta + _meta_args = ('foo', 'bar') + + def __init__(self): + print('__init__', self) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_new_style_class_py_30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_new_style_class_py_30.py new file mode 100644 index 0000000..a33ae19 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_new_style_class_py_30.py @@ -0,0 +1,45 @@ +"""check builtin data descriptors such as mode and name attributes +on a file are correctly handled + +bug notified by Pierre Rouleau on 2005-04-24 +""" +from __future__ import print_function +__revision__ = None + +class File(file): # pylint: disable=file-builtin + """ Testing new-style class inheritance from file""" + + # + def __init__(self, name, mode="r", buffering=-1, verbose=False): + """Constructor""" + + self.was_modified = False + self.verbose = verbose + super(File, self).__init__(name, mode, buffering) + if self.verbose: + print("File %s is opened. The mode is: %s" % (self.name, + self.mode)) + + # + def write(self, a_string): + """ Write a string to the file.""" + + super(File, self).write(a_string) + self.was_modified = True + + # + def writelines(self, sequence): + """ Write a sequence of strings to the file. """ + + super(File, self).writelines(sequence) + self.was_modified = True + + # + def close(self): + """Close the file.""" + + if self.verbose: + print("Closing file %s" % self.name) + + super(File, self).close() + self.was_modified = False diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_no_warning_docstring.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_no_warning_docstring.py new file mode 100644 index 0000000..315eeea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_no_warning_docstring.py @@ -0,0 +1,42 @@ +''' Test for inheritance ''' +from __future__ import print_function +__revision__ = 1 +# pylint: disable=too-few-public-methods, using-constant-test, useless-object-inheritance +class AAAA(object): + ''' class AAAA ''' + + def __init__(self): + pass + + def method1(self): + ''' method 1 ''' + print(self) + + def method2(self): + ''' method 2 ''' + print(self) + +class BBBB(AAAA): + ''' class BBBB ''' + + def __init__(self): + AAAA.__init__(self) + + # should ignore docstring calling from class AAAA + def method1(self): + AAAA.method1(self) + +class CCCC(BBBB): + ''' class CCCC ''' + + def __init__(self): + BBBB.__init__(self) + + # should ignore docstring since CCCC is inherited from BBBB which is + # inherited from AAAA containing method2 + if __revision__: + def method2(self): + AAAA.method2(self) + else: + def method2(self): + AAAA.method1(self) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_object_as_class_attribute.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_object_as_class_attribute.py new file mode 100644 index 0000000..71cd027 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_object_as_class_attribute.py @@ -0,0 +1,18 @@ +# pylint: disable=R0903, useless-object-inheritance +"""Test case for the problem described below : + - A class extends 'object' + - This class defines its own __init__() + * pylint will therefore check that baseclasses' init() + are called + - If this class defines an 'object' attribute, then pylint + will use this new definition when trying to retrieve + object.__init__() +""" + +__revision__ = None + +class Statement(object): + """ ... """ + def __init__(self): + pass + object = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_overloaded_operator.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_overloaded_operator.py new file mode 100644 index 0000000..3a158b0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_overloaded_operator.py @@ -0,0 +1,21 @@ +# pylint: disable=C0111,R0903, useless-object-inheritance +"""#3291""" +from __future__ import print_function + +class Myarray(object): + def __init__(self, array): + self.array = array + + def __mul__(self, val): + return Myarray(val) + + def astype(self): + return "ASTYPE", self + +def randint(maximum): + if maximum is not None: + return Myarray([1, 2, 3]) * 2 + + return int(5) + +print(randint(1).astype()) # we don't wan't an error for astype access diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_property_affectation_py26.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_property_affectation_py26.py new file mode 100644 index 0000000..60118bb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_property_affectation_py26.py @@ -0,0 +1,24 @@ +# pylint: disable=R0903, useless-object-inheritance +""" +Simple test case for an annoying behavior in pylint. +""" + +__revision__ = 'pouet' + +class Test(object): + """Smallest test case for reported issue.""" + + def __init__(self): + self._thing = None + + @property + def myattr(self): + """Getter for myattr""" + return self._thing + + @myattr.setter + def myattr(self, value): + """Setter for myattr.""" + self._thing = value + +Test().myattr = 'grou' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_yield_assign_py25.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_yield_assign_py25.py new file mode 100644 index 0000000..f40d8d9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_yield_assign_py25.py @@ -0,0 +1,21 @@ +"""http://www.logilab.org/ticket/8771""" + +from __future__ import print_function + +def generator(): + """yield as assignment""" + yield 45 + xxxx = yield 123 + print(xxxx) + +def generator_fp1(seq): + """W0631 false positive""" + for val in seq: + pass + for val in seq: + yield val + +def generator_fp2(): + """E0601 false positive""" + xxxx = 12 + yield xxxx diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_yield_return_mix.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_yield_return_mix.py new file mode 100644 index 0000000..8e050f0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_noerror_yield_return_mix.py @@ -0,0 +1,8 @@ +""" module doc """ +# pylint: disable=useless-return +__revision__ = None + +def somegen(): + """this kind of mix is OK""" + yield 1 + return diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_nonregr___file___global.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_nonregr___file___global.py new file mode 100644 index 0000000..910033c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_nonregr___file___global.py @@ -0,0 +1,8 @@ +"""test no crash on __file__ global""" + +def func(): + """override __file__""" + global __file__ + __file__ = 'hop' + +__revision__ = 'pouet' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_return_yield_mix_py_33.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_return_yield_mix_py_33.py new file mode 100644 index 0000000..b120b80 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_return_yield_mix_py_33.py @@ -0,0 +1,15 @@ +"""pylint should detect yield and return mix inside generators""" +# pylint: disable=using-constant-test, inconsistent-return-statements +def somegen(): + """this is a bad generator""" + if True: + return 1 + else: + yield 2 + +def moregen(): + """this is another bad generator""" + if True: + yield 1 + else: + return 2 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_typecheck_callfunc_assigment.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_typecheck_callfunc_assigment.py new file mode 100644 index 0000000..36d476e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_typecheck_callfunc_assigment.py @@ -0,0 +1,61 @@ +# pylint: disable=useless-return, useless-object-inheritance +"""check assignment to function call where the function doesn't return + + 'E1111': ('Assigning to function call which doesn\'t return', + 'Used when an assignment is done on a function call but the \ + infered function doesn\'t return anything.'), + 'W1111': ('Assigning to function call which only returns None', + 'Used when an assignment is done on a function call but the \ + infered function returns nothing but None.'), + +""" +from __future__ import generators, print_function + +def func_no_return(): + """function without return""" + print('dougloup') + +A = func_no_return() + + +def func_return_none(): + """function returning none""" + print('dougloup') + return None + +A = func_return_none() + + +def func_implicit_return_none(): + """Function returning None from bare return statement.""" + return + +A = func_implicit_return_none() + + +def func_return_none_and_smth(): + """function returning none and something else""" + print('dougloup') + if 2 or 3: + return None + return 3 + +A = func_return_none_and_smth() + +def generator(): + """no problemo""" + yield 2 + +A = generator() + +class Abstract(object): + """bla bla""" + + def abstract_method(self): + """use to return something in concrete implementation""" + raise NotImplementedError + + def use_abstract(self): + """should not issue E1111""" + var = self.abstract_method() + print(var) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_unused_import_py30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_unused_import_py30.py new file mode 100644 index 0000000..91a9e9a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_unused_import_py30.py @@ -0,0 +1,20 @@ +"""check unused import for metaclasses +""" +# pylint: disable=too-few-public-methods,wrong-import-position,ungrouped-imports +__revision__ = 1 +import abc +import sys +from abc import ABCMeta +from abc import ABCMeta as SomethingElse + +class Meta(metaclass=abc.ABCMeta): + """ Test """ + def __init__(self): + self.data = sys.executable + self.test = abc + +class Meta2(metaclass=ABCMeta): + """ Test """ + +class Meta3(metaclass=SomethingElse): + """ test """ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_variables_unused_name_from_wilcard_import.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_variables_unused_name_from_wilcard_import.py new file mode 100644 index 0000000..bb92155 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_variables_unused_name_from_wilcard_import.py @@ -0,0 +1,3 @@ +"""check unused import from a wildcard import""" +# pylint: disable=no-absolute-import +from input.func_w0611 import * diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0122_py_30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0122_py_30.py new file mode 100644 index 0000000..6b86691 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0122_py_30.py @@ -0,0 +1,12 @@ +"""test global statement""" + +__revision__ = 0 + +exec 'a = __revision__' +exec 'a = 1' in {} + +exec 'a = 1' in globals() + +def func(): + """exec in local scope""" + exec 'b = 1' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0233.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0233.py new file mode 100644 index 0000000..eb5d972 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0233.py @@ -0,0 +1,51 @@ +# pylint: disable=R0903,W0212,W0403,W0406,no-absolute-import,wrong-import-order, useless-object-inheritance + +"""test for call to __init__ from a non ancestor class +""" +from __future__ import print_function +from . import func_w0233 +import nonexistant +__revision__ = '$Id: func_w0233.py,v 1.2 2004-09-29 08:35:13 syt Exp $' + +class AAAA(object): + """ancestor 1""" + + def __init__(self): + print('init', self) + BBBBMixin.__init__(self) + +class BBBBMixin(object): + """ancestor 2""" + + def __init__(self): + print('init', self) + +class CCC(BBBBMixin, func_w0233.AAAA, func_w0233.BBBB, nonexistant.AClass): + """mix different things, some inferable some not""" + def __init__(self): + BBBBMixin.__init__(self) + func_w0233.AAAA.__init__(self) + func_w0233.BBBB.__init__(self) + nonexistant.AClass.__init__(self) + +class DDDD(AAAA): + """call superclass constructor in disjunct branches""" + def __init__(self, value): + if value: + AAAA.__init__(self) + else: + AAAA.__init__(self) + +class Super(dict): + """ test late binding super() call """ + def __init__(self): + base = super() + base.__init__() + +class Super2(dict): + """ Using the same idiom as Super, but without calling + the __init__ method. + """ + def __init__(self): + base = super() + base.__woohoo__() diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0332_py_30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0332_py_30.py new file mode 100644 index 0000000..6a38e8c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0332_py_30.py @@ -0,0 +1,4 @@ +"""check use of l as long int marker +""" +# pylint: disable=long-suffix +__revision__ = 1l diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401.py new file mode 100644 index 0000000..12227bc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401.py @@ -0,0 +1,9 @@ +"""test cyclic import +""" +# pylint: disable=no-absolute-import +from __future__ import print_function + +from . import w0401_cycle + +if w0401_cycle: + print(w0401_cycle) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_disabled.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_disabled.py new file mode 100644 index 0000000..966706c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_disabled.py @@ -0,0 +1,9 @@ +"""test cyclic import +""" +# pylint: disable=no-absolute-import +from __future__ import print_function + +from . import w0401_cycle # pylint: disable=cyclic-import + +if w0401_cycle: + print(w0401_cycle) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_disabled_in_func.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_disabled_in_func.py new file mode 100644 index 0000000..b9b0ced --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_disabled_in_func.py @@ -0,0 +1,11 @@ +"""Test disabling of cyclic import check inside a function +""" +# pylint: disable=no-absolute-import +from __future__ import print_function + + +def func(): + """Test disabling of cyclic import check inside a function""" + from . import w0401_cycle # pylint: disable=cyclic-import + if w0401_cycle: + print(w0401_cycle) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__init__.py new file mode 100644 index 0000000..dedef66 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__init__.py @@ -0,0 +1,2 @@ +"""Our big package.""" +__revision__ = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..049172a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/all_the_things.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/all_the_things.cpython-37.pyc new file mode 100644 index 0000000..3c31e96 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/all_the_things.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing1.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing1.cpython-37.pyc new file mode 100644 index 0000000..2efc857 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing1.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing2.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing2.cpython-37.pyc new file mode 100644 index 0000000..5e3bcb3 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/__pycache__/thing2.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/all_the_things.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/all_the_things.py new file mode 100644 index 0000000..b8bd47b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/all_the_things.py @@ -0,0 +1,9 @@ +"""All the things!""" +# pylint: disable=no-absolute-import +from .thing1 import THING1 +from .thing2 import THING2 +from .thing2 import THING1_PLUS_THING2 +__revision__ = None + +_ = (THING1, THING2, THING1_PLUS_THING2) +del _ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/thing1.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/thing1.py new file mode 100644 index 0000000..34972a7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/thing1.py @@ -0,0 +1,3 @@ +"""The first thing.""" +__revision__ = None +THING1 = "I am thing1" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/thing2.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/thing2.py new file mode 100644 index 0000000..66d3316 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0401_package/thing2.py @@ -0,0 +1,7 @@ +"""The second thing.""" +# pylint: disable=no-absolute-import +from .all_the_things import THING1 +__revision__ = None + +THING2 = "I am thing2" +THING1_PLUS_THING2 = "%s, plus %s" % (THING1, THING2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0404.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0404.py new file mode 100644 index 0000000..2ce7d65 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0404.py @@ -0,0 +1,27 @@ +"""Unittests for W0404 (reimport)""" +from __future__ import absolute_import, print_function + +import sys + +import xml.etree.ElementTree +from xml.etree import ElementTree + +from email import encoders +import email.encoders + +import sys #pylint: disable=ungrouped-imports,wrong-import-order +__revision__ = 0 + +def no_reimport(): + """docstring""" + import os + print(os) + + +def reimport(): + """This function contains a reimport.""" + import sys + del sys + + +del sys, ElementTree, xml.etree.ElementTree, encoders, email.encoders diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0405.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0405.py new file mode 100644 index 0000000..50a069d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0405.py @@ -0,0 +1,31 @@ +"""check reimport +""" +from __future__ import absolute_import, print_function + +# pylint: disable=using-constant-test,ungrouped-imports,wrong-import-position +import os +from os.path import join, exists +import os +import re as _re + +__revision__ = 0 +_re.match('yo', '.*') + +if __revision__: + print(os) + from os.path import exists + print(join, exists) + +def func(yooo): + """reimport in different scope""" + import os as ass + ass.remove(yooo) + import re + re.compile('.*') + +if 1: # pylint: disable=using-constant-test + import sys + print(sys.modules) +else: + print('bla') + import sys diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0406.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0406.py new file mode 100644 index 0000000..ceb12b5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0406.py @@ -0,0 +1,10 @@ +"""test module importing itself""" +# pylint: disable=no-absolute-import,using-constant-test +from __future__ import print_function +from . import func_w0406 + +__revision__ = 0 + + +if __revision__: + print(func_w0406) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0611.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0611.py new file mode 100644 index 0000000..8877872 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0611.py @@ -0,0 +1,25 @@ +"""check unused import +""" +# pylint: disable=no-absolute-import, useless-object-inheritance + +from __future__ import print_function + +import os +import sys + +class NonRegr(object): + """???""" + def __init__(self): + print('initialized') + + def sys(self): + """should not get sys from there...""" + print(self, sys) + + def dummy(self, truc): + """yo""" + return self, truc + + def blop(self): + """yo""" + print(self, 'blip') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0612.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0612.py new file mode 100644 index 0000000..3d873bb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0612.py @@ -0,0 +1,37 @@ +"""test unused variable +""" +# pylint: disable=invalid-name, redefined-outer-name, no-absolute-import +from __future__ import print_function +PATH = OS = collections = deque = None + +def function(matches): + """"yo""" + aaaa = 1 + index = -1 + for match in matches: + index += 1 + print(match) + +def visit_if(self, node): + """increments the branches counter""" + branches = 1 + # don't double count If nodes coming from some 'elif' + if node.orelse and len(node.orelse) > 1: + branches += 1 + self.inc_branch(branches) + self.stmts += branches + +def test_global(): + """ Test various assignments of global + variables through imports. + """ + global PATH, OS, collections, deque + from os import path as PATH + import os as OS + import collections + from collections import deque + # make sure that these triggers unused-variable + from sys import platform + from sys import version as VERSION + import this + import re as RE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0613.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0613.py new file mode 100644 index 0000000..02213c8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0613.py @@ -0,0 +1,42 @@ +# pylint: disable=R0903, print-statement, useless-object-inheritance +"""test unused argument +""" +from __future__ import print_function + + +def function(arg=1): + """ignore arg""" + + +class AAAA(object): + """dummy class""" + + def method(self, arg): + """dummy method""" + print(self) + def __init__(self, *unused_args, **unused_kwargs): + pass + + @classmethod + def selected(cls, *args, **kwargs): + """called by the registry when the vobject has been selected. + """ + return cls + + def using_inner_function(self, etype, size=1): + """return a fake result set for a particular entity type""" + rset = AAAA([('A',)]*size, '%s X' % etype, + description=[(etype,)]*size) + def inner(row, col=0, etype=etype, req=self, rset=rset): + """inner using all its argument""" + # pylint: disable = E1103 + return req.vreg.etype_class(etype)(req, rset, row, col) + # pylint: disable = W0201 + rset.get_entity = inner + +class BBBB(object): + """dummy class""" + + def __init__(self, arg): + """Constructor with an extra parameter. Should raise a warning""" + self.spam = 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0623_py30.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0623_py30.py new file mode 100644 index 0000000..7eb27a9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0623_py30.py @@ -0,0 +1,17 @@ +"""Test for W0623, overwriting names in exception handlers.""" +# pylint: disable=unnecessary-pass + +__revision__ = '' + +class MyError(Exception): + """Special exception class.""" + pass + + +def some_function(): + """A function.""" + + try: + {}["a"] + except KeyError as some_function: # W0623 + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0801.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0801.py new file mode 100644 index 0000000..cd386ff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/func_w0801.py @@ -0,0 +1,11 @@ +"""test code similarities +by defaut docstring are not considered +""" +__revision__ = 'id' +A = 2 +B = 3 +C = A + B +# need more than X lines to trigger the message +C *= 2 +A -= B +# all this should be detected diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/hide_code_with_imports.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/hide_code_with_imports.py new file mode 100644 index 0000000..a8449c9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/hide_code_with_imports.py @@ -0,0 +1,16 @@ +quicksort = lambda a: qs1(a,0,len(a)-1) ; import a +qs1 = lambda a,lo,hi: qs2(a,lo,hi) if lo<hi else a ; import b +qs2 = lambda a,lo,hi: qs3(lo,hi,*qsp(a,lo,hi)) ; import c +qs3 = lambda lo,hi,a,p: qs1(qs1(a,p+1,hi),lo,p-1) ; import d +qsp = lambda a,lo,hi: qsp1(a,lo,hi,a[hi],lo,lo) ; import e +qsp1 = lambda a,lo,hi,p,i,j: qsp2(a,lo,hi,p,i,j,j<hi) ; import f +qsp2 = lambda a,lo,hi,p,i,j,c: qspt(a,lo,hi,p,i,j,qsp3 if c else qsp7); import g +qspt = lambda a,lo,hi,p,i,j,n: n(a,lo,hi,p,i,j) ; import h +qsp3 = lambda a,lo,hi,p,i,j: qsp4(a,lo,hi,p,i,j,a[j]<p) ; import i +qsp4 = lambda a,lo,hi,p,i,j,c: qspt(a,lo,hi,p,i,j,qsp5 if c else qsp6); import j +qsp5 = lambda a,lo,hi,p,i,j: qsp1(sw(a,i,j),lo,hi,p,i+1,j+1) ; import k +qsp6 = lambda a,lo,hi,p,i,j: qsp1(a,lo,hi,p,i,j+1) ; import l +qsp7 = lambda a,lo,hi,p,i,j: (sw(a,i,hi), i) ; import m +sw = lambda a,i,j: sw1(enumerate(a),i,j,a[i],(-1,a[j])) ; import n +sw1 = lambda a,i,j,ai,aj: sw2([aj if x[0]==i else x for x in a],j,ai) ; import o +sw2 = lambda a,j,ai: [ai if x[0]==j else x[1] for x in a] ; import p diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/ignore_except_pass_by_default.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/ignore_except_pass_by_default.py new file mode 100644 index 0000000..444e540 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/ignore_except_pass_by_default.py @@ -0,0 +1,6 @@ +"""#5575: by default no W0704 warning on bare pass in except""" + +try: + __exception__ = 0 +except ValueError: + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/multiline-import b/basic python programmes/venv/Lib/site-packages/pylint/test/input/multiline-import new file mode 100644 index 0000000..b9507ef --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/multiline-import @@ -0,0 +1,8 @@ +from foo import ( + bar, + baz, + quux, + quuux, + quuuux, + quuuuux, +) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/noext b/basic python programmes/venv/Lib/site-packages/pylint/test/input/noext new file mode 100644 index 0000000..8aeda06 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/noext @@ -0,0 +1,4 @@ +#!/usr/bin/env python +"""a python file without .py extension""" + +__revision__ = None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/not__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/not__init__.py new file mode 100644 index 0000000..60e92b7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/not__init__.py @@ -0,0 +1 @@ +"""test""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/similar1 b/basic python programmes/venv/Lib/site-packages/pylint/test/input/similar1 new file mode 100644 index 0000000..2b04ee2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/similar1 @@ -0,0 +1,22 @@ +import one +from two import two +three +four +five +six # comments optionally ignored +seven +eight +nine +''' ten +eleven +twelve ''' +thirteen +fourteen +fifteen + + + + +sixteen +seventeen +eighteen diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/similar2 b/basic python programmes/venv/Lib/site-packages/pylint/test/input/similar2 new file mode 100644 index 0000000..77f5f1e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/similar2 @@ -0,0 +1,22 @@ +import one +from two import two +three +four +five +six +seven +eight +nine +''' ten +ELEVEN +twelve ''' +thirteen +fourteen +FIFTEEN + + + + +sixteen +seventeen +eighteen diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/w0401_cycle.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/w0401_cycle.py new file mode 100644 index 0000000..ddb4255 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/w0401_cycle.py @@ -0,0 +1,9 @@ +"""w0401 dependency +""" +# pylint: disable=print-statement, no-absolute-import +from __future__ import print_function + +from . import func_w0401 + +if func_w0401: + print(input) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/input/w0801_same.py b/basic python programmes/venv/Lib/site-packages/pylint/test/input/w0801_same.py new file mode 100644 index 0000000..cd386ff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/input/w0801_same.py @@ -0,0 +1,11 @@ +"""test code similarities +by defaut docstring are not considered +""" +__revision__ = 'id' +A = 2 +B = 3 +C = A + B +# need more than X lines to trigger the message +C *= 2 +A -= B +# all this should be detected diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/builtin_module.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/builtin_module.txt new file mode 100644 index 0000000..2616c0e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/builtin_module.txt @@ -0,0 +1 @@ +F: 1: ignored builtin module sys diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_3k_removed_stuff_py_30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_3k_removed_stuff_py_30.txt new file mode 100644 index 0000000..9920f1b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_3k_removed_stuff_py_30.txt @@ -0,0 +1,2 @@ +E: 12:function: Instance of 'unicode' has no 'looower' member +W: 4: Relative import 'func_w0401', should be 'input.func_w0401' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_bad_cont_dictcomp_py27.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_bad_cont_dictcomp_py27.txt new file mode 100644 index 0000000..51bde77 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_bad_cont_dictcomp_py27.txt @@ -0,0 +1,6 @@ +C: 35: Wrong continued indentation (add 2 spaces). + for x in range(3)} # [bad-continuation] + ^ | +C: 38: Wrong continued indentation (remove 4 spaces). + for x in range(3)} # [bad-continuation] + | ^ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_bug113231.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_bug113231.txt new file mode 100644 index 0000000..a9d3f7e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_bug113231.txt @@ -0,0 +1,2 @@ +W: 20: Specify string format arguments as logging function parameters +W: 21: Specify string format arguments as logging function parameters diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_disable_linebased.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_disable_linebased.txt new file mode 100644 index 0000000..06e391d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_disable_linebased.txt @@ -0,0 +1,2 @@ +C: 1: Line too long (127/100) +C: 14: Line too long (114/100) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_disable_linebased_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_disable_linebased_py30.txt new file mode 100644 index 0000000..06e391d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_disable_linebased_py30.txt @@ -0,0 +1,2 @@ +C: 1: Line too long (127/100) +C: 14: Line too long (114/100) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_dotted_ancestor.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_dotted_ancestor.txt new file mode 100644 index 0000000..6e2c6fa --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_dotted_ancestor.txt @@ -0,0 +1 @@ +R: 8:Aaaa: Too few public methods (0/2) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e0012.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e0012.txt new file mode 100644 index 0000000..a6d1b69 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e0012.txt @@ -0,0 +1 @@ +E: 1: Bad option value 'W04044' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e0204.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e0204.txt new file mode 100644 index 0000000..40a5928 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e0204.txt @@ -0,0 +1,3 @@ +E: 11:Abcd.__init__: Method should have "self" as first argument +E: 15:Abcd.abdc: Method should have "self" as first argument + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e12xx.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e12xx.txt new file mode 100644 index 0000000..92640d2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e12xx.txt @@ -0,0 +1,6 @@ +E: 14:pprint: Too many arguments for logging format string +E: 15:pprint: Too many arguments for logging format string +E: 16:pprint: Logging format string ends in middle of conversion specifier +E: 17:pprint: Not enough arguments for logging format string +E: 18:pprint: Unsupported logging format character 'y' (0x79) at index 3 +E: 19:pprint: Too many arguments for logging format string diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e13xx.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e13xx.txt new file mode 100644 index 0000000..f2d0d36 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e13xx.txt @@ -0,0 +1,13 @@ +E: 11:pprint: Not enough arguments for format string +E: 12:pprint: Too many arguments for format string +E: 13:pprint: Mixing named and unnamed conversion specifiers in format string +E: 14:pprint: Missing key 'PARG_2' in format string dictionary +E: 16:pprint: Missing key 'PARG_2' in format string dictionary +E: 17:pprint: Expected mapping for format string, not Tuple +E: 18:pprint: Expected mapping for format string, not List +E: 19:pprint: Unsupported format character 'z' (0x7a) at index 2 +E: 20:pprint: Format string ends in middle of conversion specifier +E: 21:pprint: Unsupported format character 'a' (0x61) at index 12 +W: 15:pprint: Unused key 'PARG_3' in format string dictionary +W: 16:pprint: Format string dictionary key should be a string, not 2 + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e13xx_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e13xx_py30.txt new file mode 100644 index 0000000..7ac9fb1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_e13xx_py30.txt @@ -0,0 +1,11 @@ +E: 11:pprint: Not enough arguments for format string +E: 12:pprint: Too many arguments for format string +E: 13:pprint: Mixing named and unnamed conversion specifiers in format string +E: 14:pprint: Missing key 'PARG_2' in format string dictionary +E: 16:pprint: Missing key 'PARG_2' in format string dictionary +E: 17:pprint: Expected mapping for format string, not Tuple +E: 18:pprint: Expected mapping for format string, not List +E: 19:pprint: Unsupported format character 'z' (0x7a) at index 2 +E: 20:pprint: Format string ends in middle of conversion specifier +W: 15:pprint: Unused key 'PARG_3' in format string dictionary +W: 16:pprint: Format string dictionary key should be a string, not 2 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_excess_escapes.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_excess_escapes.txt new file mode 100644 index 0000000..2f07722 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_excess_escapes.txt @@ -0,0 +1,9 @@ +W: 7: Anomalous backslash in string: '\['. String constant might be missing an r prefix. +W: 7: Anomalous backslash in string: '\]'. String constant might be missing an r prefix. +W: 8: Anomalous backslash in string: '\/'. String constant might be missing an r prefix. +W: 9: Anomalous backslash in string: '\`'. String constant might be missing an r prefix. +W: 15: Anomalous backslash in string: '\o'. String constant might be missing an r prefix. +W: 15: Anomalous backslash in string: '\o'. String constant might be missing an r prefix. +W: 17: Anomalous backslash in string: '\8'. String constant might be missing an r prefix. +W: 17: Anomalous backslash in string: '\9'. String constant might be missing an r prefix. +W: 27: Anomalous backslash in string: '\P'. String constant might be missing an r prefix. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_first_arg.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_first_arg.txt new file mode 100644 index 0000000..8d93204 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_first_arg.txt @@ -0,0 +1,9 @@ +C: 10:Obj.__new__: Class method __new__ should have 'cls' as first argument +C: 18:Obj.class2: Class method class2 should have 'cls' as first argument +C: 25:Meta.__new__: Metaclass class method __new__ should have 'cls' as first argument +C: 32:Meta.method2: Metaclass method method2 should have 'cls' as first argument +C: 40:Meta.class2: Metaclass class method class2 should have 'cls' as first argument +R: 16:Obj: Consider using a decorator instead of calling classmethod +R: 20:Obj: Consider using a decorator instead of calling classmethod +R: 38:Meta: Consider using a decorator instead of calling classmethod +R: 42:Meta: Consider using a decorator instead of calling classmethod diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0011.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0011.txt new file mode 100644 index 0000000..66d4bfc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0011.txt @@ -0,0 +1,3 @@ +I: 1: Id 'W0404' is used to disable 'reimported' message emission +I: 1: Locally disabling reimported (W0404) +I: 1: Useless suppression of 'reimported' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0012.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0012.txt new file mode 100644 index 0000000..5ad4cd6 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0012.txt @@ -0,0 +1 @@ +I: 1: Id 'W0404' is used to enable 'reimported' message emission diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0013.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0013.txt new file mode 100644 index 0000000..75d7afd --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0013.txt @@ -0,0 +1 @@ +I: 1: Ignoring entire file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0014.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0014.txt new file mode 100644 index 0000000..c3b521d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0014.txt @@ -0,0 +1,2 @@ +I: 1: Ignoring entire file +I: 1: Pragma "disable-all" is deprecated, use "skip-file" instead diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0020.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0020.txt new file mode 100644 index 0000000..ddd1cb4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0020.txt @@ -0,0 +1,3 @@ +I: 7: Id 'W0612' is used to disable 'unused-variable' message emission +I: 7: Locally disabling unused-variable (W0612) +I: 8: Suppressed 'unused-variable' (from line 7) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0022.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0022.txt new file mode 100644 index 0000000..28b7d71 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_i0022.txt @@ -0,0 +1,21 @@ +I: 5: Locally disabling invalid-name (C0103) +I: 5: Suppressed 'invalid-name' (from line 5) +I: 6: Locally disabling invalid-name (C0103) +I: 6: Pragma "disable-msg" is deprecated, use "disable" instead +I: 6: Suppressed 'invalid-name' (from line 6) +I: 8: Locally disabling invalid-name (C0103) +I: 9: Suppressed 'invalid-name' (from line 8) +I: 12: Locally disabling invalid-name (C0103) +I: 12: Pragma "disable-msg" is deprecated, use "disable" instead +I: 13: Suppressed 'invalid-name' (from line 12) +I: 14: Pragma "enable-msg" is deprecated, use "enable" instead +I: 16: Id 'C0103' is used to disable 'invalid-name' message emission +I: 16: Locally disabling invalid-name (C0103) +I: 16: Pragma "disable-msg" is deprecated, use "disable" instead +I: 17: Suppressed 'invalid-name' (from line 16) +I: 18: Id 'C0103' is used to enable 'invalid-name' message emission +I: 18: Pragma "enable-msg" is deprecated, use "enable" instead +I: 20: Id 'C0103' is used to disable 'invalid-name' message emission +I: 20: Locally disabling invalid-name (C0103) +I: 21: Suppressed 'invalid-name' (from line 20) +I: 22: Id 'C0103' is used to enable 'invalid-name' message emission diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_logging_not_lazy_with_logger.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_logging_not_lazy_with_logger.txt new file mode 100644 index 0000000..04823cf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_logging_not_lazy_with_logger.txt @@ -0,0 +1,4 @@ +W: 8: Specify string format arguments as logging function parameters +W: 9: Specify string format arguments as logging function parameters +W: 11: Specify string format arguments as logging function parameters +W: 13: Specify string format arguments as logging function parameters diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_loopvar_in_dict_comp_py27.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_loopvar_in_dict_comp_py27.txt new file mode 100644 index 0000000..bc11121 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_loopvar_in_dict_comp_py27.txt @@ -0,0 +1 @@ +W: 8:bad_case.<lambda>: Cell variable x defined in loop diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_module___dict__.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_module___dict__.txt new file mode 100644 index 0000000..4169824 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_module___dict__.txt @@ -0,0 +1 @@ +E: 5: Using variable '__dict__' before assignment diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_nameerror_on_string_substitution.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_nameerror_on_string_substitution.txt new file mode 100644 index 0000000..aab2102 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_nameerror_on_string_substitution.txt @@ -0,0 +1,2 @@ +E: 5: Using variable 'MSG' before assignment +E: 8: Using variable 'MSG2' before assignment diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_no_dummy_redefined.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_no_dummy_redefined.txt new file mode 100644 index 0000000..a7db92f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_no_dummy_redefined.txt @@ -0,0 +1,2 @@ +C: 7: Constant name "value" doesn't conform to UPPER_CASE naming style +W: 12:clobbering: Redefining name 'value' from outer scope (line 7) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_nonregr___file___global.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_nonregr___file___global.txt new file mode 100644 index 0000000..c0d7340 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_nonregr___file___global.txt @@ -0,0 +1,2 @@ +W: 5:func: Redefining built-in '__file__' +W: 5:func: Using the global statement diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_raw_escapes.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_raw_escapes.txt new file mode 100644 index 0000000..991fba7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_raw_escapes.txt @@ -0,0 +1,3 @@ +W: 5: Anomalous Unicode escape in byte string: '\u'. String constant might be missing an r or u prefix. +W: 6: Anomalous Unicode escape in byte string: '\U'. String constant might be missing an r or u prefix. +W: 7: Anomalous Unicode escape in byte string: '\N'. String constant might be missing an r or u prefix. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_return_yield_mix_py_33.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_return_yield_mix_py_33.txt new file mode 100644 index 0000000..d81ce5c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_return_yield_mix_py_33.txt @@ -0,0 +1,2 @@ +E: 6:somegen: Return with argument inside generator +E: 15:moregen: Return with argument inside generator diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_toolonglines_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_toolonglines_py30.txt new file mode 100644 index 0000000..cd594f5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_toolonglines_py30.txt @@ -0,0 +1,4 @@ +C: 1: Line too long (101/100) +C: 2: Line too long (104/100) +C: 17: Line too long (102/100) +C: 25: Line too long (105/100) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_callfunc_assigment.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_callfunc_assigment.txt new file mode 100644 index 0000000..d1257ca --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_callfunc_assigment.txt @@ -0,0 +1,3 @@ +E: 18: Assigning result of a function call, where the function has no return +E: 26: Assigning result of a function call, where the function returns None +E: 33: Assigning result of a function call, where the function returns None diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_getattr_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_getattr_py30.txt new file mode 100644 index 0000000..b6bf150 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_getattr_py30.txt @@ -0,0 +1,9 @@ +E: 25:Client.__init__: Class 'Provider' has no 'cattribute' member +E: 35:Client.use_method: Instance of 'Provider' has no 'hophophop' member +E: 40:Client.use_attr: Instance of 'Provider' has no 'attribute' member +E: 52:Client.test_bt_types: Instance of 'list' has no 'apppend' member +E: 54:Client.test_bt_types: Instance of 'dict' has no 'set' member +E: 56:Client.test_bt_types: Instance of 'tuple' has no 'append' member +E: 58:Client.test_bt_types: Instance of 'str' has no 'loower' member +E: 62:Client.test_bt_types: Instance of 'int' has no 'whatever' member +E: 66: Instance of 'int' has no 'lower' member (but some types could not be inferred) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_non_callable_call.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_non_callable_call.txt new file mode 100644 index 0000000..8baa237 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_typecheck_non_callable_call.txt @@ -0,0 +1,8 @@ +E: 10: __revision__ is not callable +E: 29: INSTANCE is not callable +E: 31: LIST is not callable +E: 33: DICT is not callable +E: 35: TUPLE is not callable +E: 37: INT is not callable +E: 72: PROP.test is not callable +E: 73: PROP.custom is not callable \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unicode_literal_py26.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unicode_literal_py26.txt new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unicode_literal_py274.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unicode_literal_py274.txt new file mode 100644 index 0000000..25efa99 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unicode_literal_py274.txt @@ -0,0 +1 @@ +W: 6: Anomalous Unicode escape in byte string: '\u'. String constant might be missing an r or u prefix. diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unused_import_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unused_import_py30.txt new file mode 100644 index 0000000..aa79b28 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_unused_import_py30.txt @@ -0,0 +1 @@ +W: 8: Reimport 'ABCMeta' (imported line 7) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py29.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py29.txt new file mode 100644 index 0000000..14d61ad --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py29.txt @@ -0,0 +1,3 @@ +W: 6: Using possibly undefined loop variable 'C' +W: 15: Using possibly undefined loop variable 'var1' + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py30.txt new file mode 100644 index 0000000..46d3430 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_use_for_or_listcomp_var_py30.txt @@ -0,0 +1,3 @@ +E: 6: Using variable 'C' before assignment +W: 15: Using possibly undefined loop variable 'var1' + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_variables_unused_name_from_wilcard_import.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_variables_unused_name_from_wilcard_import.txt new file mode 100644 index 0000000..01c57af --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_variables_unused_name_from_wilcard_import.txt @@ -0,0 +1,4 @@ +W: 3: Unused import NonRegr from wildcard import +W: 3: Unused import os from wildcard import +W: 3: Unused import sys from wildcard import +W: 3: Wildcard import input.func_w0611 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0122_py_30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0122_py_30.txt new file mode 100644 index 0000000..d833076 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0122_py_30.txt @@ -0,0 +1,5 @@ +W: 5: Use of exec +W: 6: Use of exec +W: 8: Use of exec +W: 12:func: Use of exec + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0233.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0233.txt new file mode 100644 index 0000000..de4f0fb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0233.txt @@ -0,0 +1,6 @@ +E: 7: Unable to import 'nonexistant' +E: 23:CCC: Module 'input.func_w0233' has no 'BBBB' member +E: 28:CCC.__init__: Module 'input.func_w0233' has no 'BBBB' member +E: 51:Super2.__init__: Super of 'Super2' has no '__woohoo__' member +W: 15:AAAA.__init__: __init__ method from a non direct base class 'BBBBMixin' is called +W: 49:Super2.__init__: __init__ method from base class 'dict' is not called diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0312.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0312.txt new file mode 100644 index 0000000..917e8d0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0312.txt @@ -0,0 +1,2 @@ +W: 10: Found indentation with tabs instead of spaces +W: 11: Found indentation with tabs instead of spaces diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0332_py_30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0332_py_30.txt new file mode 100644 index 0000000..16f1d80 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0332_py_30.txt @@ -0,0 +1 @@ +W: 4: Use of "l" as long integer identifier diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401.txt new file mode 100644 index 0000000..f6648f4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401.txt @@ -0,0 +1,3 @@ +R: 1: Cyclic import (input.func_w0401 -> input.w0401_cycle) +W: 8: Using a conditional statement with a constant value +W: 8: Using a conditional statement with a constant value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_disabled.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_disabled.txt new file mode 100644 index 0000000..b5a8db3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_disabled.txt @@ -0,0 +1,2 @@ +W: 8: Using a conditional statement with a constant value +W: 8: Using a conditional statement with a constant value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_disabled_in_func.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_disabled_in_func.txt new file mode 100644 index 0000000..b5ce452 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_disabled_in_func.txt @@ -0,0 +1,2 @@ +W: 8: Using a conditional statement with a constant value +W: 10:func: Using a conditional statement with a constant value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_package.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_package.txt new file mode 100644 index 0000000..ca05124 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0401_package.txt @@ -0,0 +1,2 @@ +R: 1: Cyclic import (input.func_w0401_package.all_the_things -> input.func_w0401_package.thing2) +W: 8: Using a conditional statement with a constant value diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0404.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0404.txt new file mode 100644 index 0000000..2cfc137 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0404.txt @@ -0,0 +1,5 @@ +W: 7: Reimport 'ElementTree' (imported line 6) +W: 10: Reimport 'email.encoders' (imported line 9) +W: 12: Reimport 'sys' (imported line 4) +W: 23:reimport: Redefining name 'sys' from outer scope (line 4) +W: 23:reimport: Reimport 'sys' (imported line 4) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0405.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0405.txt new file mode 100644 index 0000000..072b155 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0405.txt @@ -0,0 +1,4 @@ +W: 8: Reimport 'os' (imported line 6) +W: 16: Reimport 'exists' (imported line 7) +W: 21:func: Reimport 'os' (imported line 6) +W: 23:func: Reimport 're' (imported line 9) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0406.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0406.txt new file mode 100644 index 0000000..f6bc14d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0406.txt @@ -0,0 +1 @@ +W: 4: Module import itself diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0611.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0611.txt new file mode 100644 index 0000000..2be0d0a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0611.txt @@ -0,0 +1 @@ +W: 7: Unused import os diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0612.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0612.txt new file mode 100644 index 0000000..a6d8bdc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0612.txt @@ -0,0 +1,6 @@ +W: 9:function: Unused variable 'aaaa' +W: 28:test_global: Using the global statement +W: 34:test_global: Unused platform imported from sys +W: 35:test_global: Unused version imported from sys as VERSION +W: 36:test_global: Unused import this +W: 37:test_global: Unused re imported as RE diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0613.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0613.txt new file mode 100644 index 0000000..36cb380 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0613.txt @@ -0,0 +1,5 @@ +W: 7:function: Unused argument 'arg' +W: 14:AAAA.method: Unused argument 'arg' +W: 21:AAAA.selected: Unused argument 'args' +W: 21:AAAA.selected: Unused argument 'kwargs' +W: 40:BBBB.__init__: Unused argument 'arg' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0622.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0622.txt new file mode 100644 index 0000000..7191347 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0622.txt @@ -0,0 +1,2 @@ +W: 8:function: Redefining built-in 'type' +W: 11: Redefining built-in 'map' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623.txt new file mode 100644 index 0000000..08fe8b5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623.txt @@ -0,0 +1,11 @@ +C: 28:some_function: Variable name "FOO" doesn't conform to 'variable-name-hint' template +C: 41: Constant name "exc3" doesn't conform to 'constant-name-hint' template +C: 55: Variable name "OOPS" doesn't conform to 'variable-name-hint' template +W: 18:some_function: Redefining name 'RuntimeError' from object 'exceptions' in exception handler +W: 20:some_function: Redefining name 'OSError' from builtins in exception handler +W: 20:some_function: Unused variable 'OSError' +W: 22:some_function: Redefining name 'MyError' from outer scope (line 7) in exception handler +W: 22:some_function: Unused variable 'MyError' +W: 45: Redefining name 'RuntimeError' from object 'exceptions' in exception handler +W: 47: Redefining name 'OSError' from builtins in exception handler +W: 49: Redefining name 'MyOtherError' from outer scope (line 36) in exception handler diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623_py30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623_py30.txt new file mode 100644 index 0000000..e5cc0f5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623_py30.txt @@ -0,0 +1,2 @@ +W: 16:some_function: Redefining name 'some_function' from outer scope (line 11) in exception handler +W: 16:some_function: Unused variable 'some_function' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623_py_30.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623_py_30.txt new file mode 100644 index 0000000..77329bb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0623_py_30.txt @@ -0,0 +1,12 @@ +C: 28:some_function: Variable name "FOO" doesn't conform to 'variable-name-hint' template +C: 41: Constant name "exc3" doesn't conform to 'constant-name-hint' template +C: 57: Variable name "OOPS" doesn't conform to 'variable-name-hint' template +W: 18:some_function: Redefining name 'RuntimeError' from object 'exceptions' in exception handler +W: 20:some_function: Redefining name 'OSError' from builtins in exception handler +W: 20:some_function: Unused variable 'OSError' +W: 22:some_function: Redefining name 'MyError' from outer scope (line 7) in exception handler +W: 22:some_function: Unused variable 'MyError' +W: 45: Redefining name 'RuntimeError' from object 'exceptions' in exception handler +W: 47: Redefining name 'args' from object 'exceptions.RuntimeError' in exception handler +W: 49: Redefining name 'OSError' from builtins in exception handler +W: 51: Redefining name 'MyOtherError' from outer scope (line 36) in exception handler diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0801.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0801.txt new file mode 100644 index 0000000..203ce92 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_w0801.txt @@ -0,0 +1,11 @@ +R: 1: Similar lines in 2 files +==input.func_w0801:3 +==input.w0801_same:3 +__revision__ = 'id' +A = 2 +B = 3 +C = A + B +# need more than X lines to trigger the message +C *= 2 +A -= B +# all this should be detected diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_with_without_as_py25.txt b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_with_without_as_py25.txt new file mode 100644 index 0000000..18ca371 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/messages/func_with_without_as_py25.txt @@ -0,0 +1,3 @@ +E: 11:do_nothing: Using variable 'base' before assignment +W: 11:do_nothing: Statement seems to have no effect + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/.pylintrc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/.pylintrc new file mode 100644 index 0000000..9a5bb5a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/.pylintrc @@ -0,0 +1,4 @@ +[MASTER] + +optimize-ast=no + diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/application_crash.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/application_crash.cpython-37.pyc new file mode 100644 index 0000000..bcc87e0 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/application_crash.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/classdoc_usage.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/classdoc_usage.cpython-37.pyc new file mode 100644 index 0000000..38e5b13 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/classdoc_usage.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/decimal_inference.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/decimal_inference.cpython-37.pyc new file mode 100644 index 0000000..6001a6e Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/decimal_inference.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/empty.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/empty.cpython-37.pyc new file mode 100644 index 0000000..aae0c19 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/empty.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/func_block_disable_msg.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/func_block_disable_msg.cpython-37.pyc new file mode 100644 index 0000000..180657b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/func_block_disable_msg.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_assign.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_assign.cpython-37.pyc new file mode 100644 index 0000000..be0feef Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_assign.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_package_subpackage_module.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_package_subpackage_module.cpython-37.pyc new file mode 100644 index 0000000..b1c61f6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_package_subpackage_module.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_something.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_something.cpython-37.pyc new file mode 100644 index 0000000..ed6faa4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/import_something.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/meta.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/meta.cpython-37.pyc new file mode 100644 index 0000000..c0b290a Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/meta.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/module_global.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/module_global.cpython-37.pyc new file mode 100644 index 0000000..ea6fd85 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/module_global.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/no_stdout_encoding.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/no_stdout_encoding.cpython-37.pyc new file mode 100644 index 0000000..2b68afa Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/no_stdout_encoding.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/numarray_import.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/numarray_import.cpython-37.pyc new file mode 100644 index 0000000..2de3593 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/numarray_import.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/numarray_inf.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/numarray_inf.cpython-37.pyc new file mode 100644 index 0000000..5b0be5c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/numarray_inf.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/precedence_test.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/precedence_test.cpython-37.pyc new file mode 100644 index 0000000..b48c9c8 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/precedence_test.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/special_attr_scope_lookup_crash.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/special_attr_scope_lookup_crash.cpython-37.pyc new file mode 100644 index 0000000..66a53d2 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/special_attr_scope_lookup_crash.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/test_pylintrc_comments.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/test_pylintrc_comments.cpython-37.pyc new file mode 100644 index 0000000..0258920 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/test_pylintrc_comments.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/try_finally_disable_msg_crash.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/try_finally_disable_msg_crash.cpython-37.pyc new file mode 100644 index 0000000..9415f03 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/try_finally_disable_msg_crash.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/wildcard.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/wildcard.cpython-37.pyc new file mode 100644 index 0000000..141a402 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/wildcard.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/wrong_import_position.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/wrong_import_position.cpython-37.pyc new file mode 100644 index 0000000..881708d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/__pycache__/wrong_import_position.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__init__.py new file mode 100644 index 0000000..fdabe9f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__init__.py @@ -0,0 +1,4 @@ +"""a package with absolute import activated +""" + +from __future__ import absolute_import diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..274fb1f Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__pycache__/string.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__pycache__/string.cpython-37.pyc new file mode 100644 index 0000000..81ca945 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/__pycache__/string.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/string.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/string.py new file mode 100644 index 0000000..f47e9a5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/absimp/string.py @@ -0,0 +1,7 @@ +""" +http://www.logilab.org/ticket/70495 +http://www.logilab.org/ticket/70565 +""" +from __future__ import absolute_import, print_function +import string +print(string) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/application_crash.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/application_crash.py new file mode 100644 index 0000000..8d3eb17 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/application_crash.py @@ -0,0 +1 @@ +ABC = something_undefined diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/__init__.py new file mode 100644 index 0000000..76f75d3 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/__init__.py @@ -0,0 +1,2 @@ +import missing +raise missing.Missing.. \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/__pycache__/wrong.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/__pycache__/wrong.cpython-37.pyc new file mode 100644 index 0000000..88a7890 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/__pycache__/wrong.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/wrong.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/wrong.py new file mode 100644 index 0000000..4feea7e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/bad_package/wrong.py @@ -0,0 +1,5 @@ +""" +Test that pylint doesn't crash when a relative import +depends on the local __init__, which contains an expected syntax error. +""" +from . import missing diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__init__.py new file mode 100644 index 0000000..be998a9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__init__.py @@ -0,0 +1,6 @@ +from ... import Something +from . import data +try: + from ... import Lala +except ImportError: + pass \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..3a4fe8c Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/data.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/data.cpython-37.pyc new file mode 100644 index 0000000..6731583 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/__pycache__/data.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/data.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/data.py new file mode 100644 index 0000000..9ec64d2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/beyond_top/data.py @@ -0,0 +1 @@ +Anything = 42 \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/classdoc_usage.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/classdoc_usage.py new file mode 100644 index 0000000..2d9df51 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/classdoc_usage.py @@ -0,0 +1,17 @@ +"""ds""" + +__revision__ = None +# pylint: disable=useless-object-inheritance + +class SomeClass(object): + """cds""" + doc = __doc__ + + def __init__(self): + """only to make pylint happier""" + + def please(self): + """public method 1/2""" + + def besilent(self): + """public method 2/2""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/comments_pylintrc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/comments_pylintrc new file mode 100644 index 0000000..93a3310 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/comments_pylintrc @@ -0,0 +1,7 @@ +[MESSAGES CONTROL] +disable=all +enable= + trailing-whitespace, # Caring about it + bad-indentation, # And about this + # And about this + missing-docstring \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/decimal_inference.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/decimal_inference.py new file mode 100644 index 0000000..00c9130 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/decimal_inference.py @@ -0,0 +1,10 @@ +"""hum E1011 on .prec member is justifiable since Context instance are built +using setattr/locals :( + +2007/02/17 update: .prec attribute is now detected by astroid :o) +""" +from __future__ import print_function +import decimal + +decimal.getcontext().prec = 200 +print(decimal.getcontext().prec) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/descriptor_crash.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/descriptor_crash.py new file mode 100644 index 0000000..4b3adcc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/descriptor_crash.py @@ -0,0 +1,20 @@ +# -*- coding: iso-8859-1 -*- + +import urllib + +class Page(object): + _urlOpen = staticmethod(urllib.urlopen) + + def getPage(self, url): + handle = self._urlOpen(url) + data = handle.read() + handle.close() + return data + #_getPage + +#Page + +if __name__ == "__main__": + import sys + p = Page() + print p.getPage(sys.argv[1]) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__init__.py new file mode 100644 index 0000000..0b43a70 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__init__.py @@ -0,0 +1,3 @@ +# pylint: disable=missing-docstring +from .dummy import DUMMY +from .another import ANOTHER diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..84c1284 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/another.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/another.cpython-37.pyc new file mode 100644 index 0000000..641fd25 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/another.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/dummy.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/dummy.cpython-37.pyc new file mode 100644 index 0000000..69101b1 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/__pycache__/dummy.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/another.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/another.py new file mode 100644 index 0000000..56a8712 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/another.py @@ -0,0 +1,3 @@ +# pylint: disable=missing-docstring + +ANOTHER = 42 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/dummy.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/dummy.py new file mode 100644 index 0000000..60345dc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy/dummy.py @@ -0,0 +1,2 @@ +# pylint: disable=missing-docstring +DUMMY = 42 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin.rc new file mode 100644 index 0000000..162dedc --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin.rc @@ -0,0 +1,6 @@ +[MASTER] +load-plugins=dummy_plugin + +[DUMMY_PLUGIN] +dummy_option_1="dummy value 1" +dummy_option_2="dummy value 2" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin/__pycache__/dummy_plugin.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin/__pycache__/dummy_plugin.cpython-37.pyc new file mode 100644 index 0000000..45a9a38 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin/__pycache__/dummy_plugin.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin/dummy_plugin.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin/dummy_plugin.py new file mode 100644 index 0000000..95b0b93 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/dummy_plugin/dummy_plugin.py @@ -0,0 +1,30 @@ +from pylint.checkers import BaseChecker + + +class DummyPlugin1(BaseChecker): + name = 'dummy_plugin' + msgs = {'I9061': ('Dummy short desc 01', 'dummy-message-01', 'Dummy long desc')} + options = ( + ('dummy_option_1', { + 'type': 'string', + 'metavar': '<string>', + 'help': 'Dummy option 1', + }), + ) + + +class DummyPlugin2(BaseChecker): + name = 'dummy_plugin' + msgs = {'I9060': ('Dummy short desc 02', 'dummy-message-02', 'Dummy long desc')} + options = ( + ('dummy_option_2', { + 'type': 'string', + 'metavar': '<string>', + 'help': 'Dummy option 2', + }), + ) + + +def register(linter): + linter.register_checker(DummyPlugin1(linter)) + linter.register_checker(DummyPlugin2(linter)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/empty.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/empty.py new file mode 100644 index 0000000..e69de29 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/func_block_disable_msg.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/func_block_disable_msg.py new file mode 100644 index 0000000..36198db --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/func_block_disable_msg.py @@ -0,0 +1,1026 @@ +# pylint: disable=C0302,bare-except,print-statement, useless-object-inheritance +"""pylint option block-disable""" +from __future__ import print_function + +class Foo(object): + """block-disable test""" + + def __init__(self): + self._test = "42" + + def meth1(self, arg): + """this issues a message""" + print(self) + + def meth2(self, arg): + """and this one not""" + # pylint: disable=W0613 + print(self._test\ + + "foo") + + def meth3(self): + """test one line disabling""" + # no error + print(self.bla) # pylint: disable=E1101 + # error + print(self.blop) + + def meth4(self): + """test re-enabling""" + # pylint: disable=E1101 + # no error + print(self.bla) + print(self.blop) + # pylint: enable=E1101 + # error + print(self.blip) + + def meth5(self): + """test IF sub-block re-enabling""" + # pylint: disable=E1101 + # no error + print(self.bla) + if self.blop: + # pylint: enable=E1101 + # error + print(self.blip) + else: + # no error + print(self.blip) + # no error + print(self.blip) + + def meth6(self): + """test TRY/EXCEPT sub-block re-enabling""" + # pylint: disable=E1101 + # no error + print(self.bla) + try: + # pylint: enable=E1101 + # error + print(self.blip) + except UndefinedName: # pylint: disable=E0602 + # no error + print(self.blip) + # no error + print(self.blip) + + def meth7(self): + """test one line block opening disabling""" + if self.blop: # pylint: disable=E1101 + # error + print(self.blip) + else: + # error + print(self.blip) + # error + print(self.blip) + + + def meth8(self): + """test late disabling""" + # error + print(self.blip) + # pylint: disable=E1101 + # no error + print(self.bla) + print(self.blop) + + def meth9(self): + """test re-enabling right after a block with whitespace""" + eris = 5 + + if eris: # pylint: disable=using-constant-test + print("In block") + + # pylint: disable=E1101 + # no error + print(self.bla) + print(self.blu) + # pylint: enable=E1101 + # error + print(self.blip) + + def meth10(self): + """Test double disable""" + # pylint: disable=E1101 + # no error + print(self.bla) + # pylint: disable=E1101 + print(self.blu) + + +class ClassLevelMessage(object): + """shouldn't display to much attributes/not enough methods messages + """ + # pylint: disable=R0902,R0903 + + def __init__(self): + self.attr1 = 1 + self.attr2 = 1 + self.attr3 = 1 + self.attr4 = 1 + self.attr5 = 1 + self.attr6 = 1 + self.attr7 = 1 + self.attr8 = 1 + self.attr9 = 1 + self.attr0 = 1 + + def too_complex_but_thats_ok(self, attr1, attr2): + """THIS Method has too much branches and returns but i don't care + """ + # pylint: disable=R0912,R0911 + try: + attr3 = attr1+attr2 + except ValueError: + attr3 = None + except: + return 'duh', self + if attr1: + for i in attr1: + if attr2: + return i + else: + return 'duh' + elif attr2: + for i in attr2: + if attr2: + return i + else: + return 'duh' + else: + for i in range(15): + if attr3: + return i + else: + return 'doh' + return None + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +print('hop, too many lines but i don\'t care') diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_assign.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_assign.py new file mode 100644 index 0000000..c01cd52 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_assign.py @@ -0,0 +1,5 @@ +import shmixml.dom.minidom +import xml.dom.minidom + +if 'dom' not in xml.__dict__: + xml.dom = shmixml.dom diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_package_subpackage_module.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_package_subpackage_module.py new file mode 100644 index 0000000..2864e3c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_package_subpackage_module.py @@ -0,0 +1,49 @@ +# pylint: disable=I0011,C0301,W0611 +"""I found some of my scripts trigger off an AttributeError in pylint +0.8.1 (with common 0.12.0 and astroid 0.13.1). + +Traceback (most recent call last): + File "/usr/bin/pylint", line 4, in ? + lint.Run(sys.argv[1:]) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 729, in __init__ + linter.check(args) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 412, in check + self.check_file(filepath, modname, checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 426, in check_file + astroid = self._check_file(filepath, modname, checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 450, in _check_file + self.check_astroid_module(astroid, checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 494, in check_astroid_module + self.astroid_events(astroid, [checker for checker in checkers + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 511, in astroid_events + self.astroid_events(child, checkers, _reversed_checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 511, in astroid_events + self.astroid_events(child, checkers, _reversed_checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 508, in astroid_events + checker.visit(astroid) + File "/usr/lib/python2.4/site-packages/logilab/astroid/utils.py", line 84, in visit + method(node) + File "/usr/lib/python2.4/site-packages/pylint/checkers/variables.py", line 295, in visit_import + self._check_module_attrs(node, module, name_parts[1:]) + File "/usr/lib/python2.4/site-packages/pylint/checkers/variables.py", line 357, in _check_module_attrs + self.add_message('E0611', args=(name, module.name), +AttributeError: Import instance has no attribute 'name' + + +You can reproduce it by: +(1) create package structure like the following: + +package/ + __init__.py + subpackage/ + __init__.py + module.py + +(2) in package/__init__.py write: + +import subpackage + +(3) run pylint with a script importing package.subpackage.module. +""" +import package.subpackage.module +__revision__ = '$Id: import_package_subpackage_module.py,v 1.1 2005-11-10 16:08:54 syt Exp $' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_something.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_something.py new file mode 100644 index 0000000..61bc51f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/import_something.py @@ -0,0 +1,4 @@ +# pylint: disable=missing-docstring,unused-import + +import os +import sys diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/init_wildcard/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/init_wildcard/__init__.py new file mode 100644 index 0000000..8a4b31c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/init_wildcard/__init__.py @@ -0,0 +1 @@ +from empty import * diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/init_wildcard/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/init_wildcard/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..36845b7 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/init_wildcard/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/meta.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/meta.py new file mode 100644 index 0000000..7001207 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/meta.py @@ -0,0 +1,3 @@ +# pylint: disable=invalid-name, missing-docstring +# pylint: disable=unbalanced-tuple-unpacking +n = 42 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/module_global.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/module_global.py new file mode 100644 index 0000000..107d652 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/module_global.py @@ -0,0 +1,7 @@ +# pylint: disable=W0603,W0601,W0604,E0602,W0104 +"""was causing infinite recursion +""" +__revision__ = 1 + +global GLOBAL_VAR +GLOBAL_VAR.foo diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/no_stdout_encoding.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/no_stdout_encoding.py new file mode 100644 index 0000000..d72aa65 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/no_stdout_encoding.py @@ -0,0 +1,4 @@ +#-*- coding:iso-8859-1 -*- +class test: + def __init__(self, dir): + testString = u"répertoire :\n%s !"%dir diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/numarray_import.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/numarray_import.py new file mode 100644 index 0000000..e89757f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/numarray_import.py @@ -0,0 +1,7 @@ +"""#10077""" + +__revision__ = 1 + +from numarray import zeros + +zeros(shape=(4, 5)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/numarray_inf.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/numarray_inf.py new file mode 100644 index 0000000..4ea22a9 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/numarray_inf.py @@ -0,0 +1,5 @@ +"""#3216""" + +import numarray as na +import numarray.random_array as nar +IM16 = nar.randint(0, 256, 300).astype(na.UInt8) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/AudioTime.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/AudioTime.py new file mode 100644 index 0000000..ef65143 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/AudioTime.py @@ -0,0 +1,3 @@ +"""test preceded by the AudioTime class in __init__.py""" + +__revision__ = 0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__init__.py new file mode 100644 index 0000000..bf6b73c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__init__.py @@ -0,0 +1,15 @@ +# pylint: disable=R0903,W0403 + +"""package's __init__ file""" + +from . import subpackage + +__revision__ = 0 + +# E0602 - Undefined variable '__path__' +__path__ += "folder" + +class AudioTime: + """test precedence over the AudioTime submodule""" + + DECIMAL = 3 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__pycache__/AudioTime.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__pycache__/AudioTime.cpython-37.pyc new file mode 100644 index 0000000..8ac39a4 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__pycache__/AudioTime.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..ea07be6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__init__.py new file mode 100644 index 0000000..dc4782e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__init__.py @@ -0,0 +1 @@ +"""package.subpackage""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..358ea59 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/module.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/module.cpython-37.pyc new file mode 100644 index 0000000..c3a9b74 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/__pycache__/module.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/module.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/module.py new file mode 100644 index 0000000..4b7244b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package/subpackage/module.py @@ -0,0 +1 @@ +"""package.subpackage.module""" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__init__.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__init__.py new file mode 100644 index 0000000..3107fff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__init__.py @@ -0,0 +1,3 @@ +""" Check for E0603 for missing submodule found in __all__ """ +__revision__ = 1 +__all__ = ['notmissing', 'missing'] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..229ec1d Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__pycache__/notmissing.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__pycache__/notmissing.cpython-37.pyc new file mode 100644 index 0000000..75ed3a6 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/__pycache__/notmissing.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/notmissing.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/notmissing.py new file mode 100644 index 0000000..4ca0c32 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/package_all/notmissing.py @@ -0,0 +1,2 @@ +""" empty """ +__revision__ = 1 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/precedence_test.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/precedence_test.py new file mode 100644 index 0000000..ff5871d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/precedence_test.py @@ -0,0 +1,21 @@ +""" + # package/__init__.py + class AudioTime(object): + DECIMAL = 3 + + # package/AudioTime.py + class AudioTime(object): + pass + + # test.py + from package import AudioTime + # E0611 - No name 'DECIMAL' in module 'AudioTime.AudioTime' + print AudioTime.DECIMAL + +""" +from __future__ import print_function +from package import AudioTime +__revision__ = 0 + + +print(AudioTime.DECIMAL) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k-disabled.rc b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k-disabled.rc new file mode 100644 index 0000000..41d7757 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k-disabled.rc @@ -0,0 +1,2 @@ +[MESSAGES CONTROL] +disable=no-absolute-import diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k_error_flag.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k_error_flag.py new file mode 100644 index 0000000..12f5c4d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k_error_flag.py @@ -0,0 +1,11 @@ +"""Contains both normal error messages and Python3 porting error messages.""" +# pylint: disable=too-few-public-methods + +raise Exception, 1 # Error emitted here with the Python 3 checker. + + +class Test(object): + """dummy""" + + def __init__(self): + return 42 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k_errors_and_warnings.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k_errors_and_warnings.py new file mode 100644 index 0000000..3d033e8 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/py3k_errors_and_warnings.py @@ -0,0 +1,19 @@ +"""Contains both normal error messages and Python3 porting error messages.""" +# pylint: disable=too-few-public-methods + +# error: import missing `from __future__ import absolute_import` +import sys + +# error: Use raise ErrorClass(args) instead of raise ErrorClass, args. +raise Exception, 1 + +class Test(object): + """dummy""" + + def __init__(self): + # warning: Calling a dict.iter*() method + {1: 2}.iteritems() + return 42 + +# error: print statement used +print 'not in python3' diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/special_attr_scope_lookup_crash.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/special_attr_scope_lookup_crash.py new file mode 100644 index 0000000..b693a9f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/special_attr_scope_lookup_crash.py @@ -0,0 +1,3 @@ +class Klass(object): + """A""" + __doc__ += "B" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/syntax_error.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/syntax_error.py new file mode 100644 index 0000000..bf86aff --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/syntax_error.py @@ -0,0 +1 @@ +class A extends B {} \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/test_pylintrc_comments.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/test_pylintrc_comments.py new file mode 100644 index 0000000..6bcff58 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/test_pylintrc_comments.py @@ -0,0 +1,2 @@ +def f(x): + return x # 1 space \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/try_finally_disable_msg_crash.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/try_finally_disable_msg_crash.py new file mode 100644 index 0000000..1719308 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/try_finally_disable_msg_crash.py @@ -0,0 +1,5 @@ +try: + pass +finally: + # pylint: disable=W0201 + pass diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/wildcard.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/wildcard.py new file mode 100644 index 0000000..8a4b31c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/wildcard.py @@ -0,0 +1 @@ +from empty import * diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/wrong_import_position.py b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/wrong_import_position.py new file mode 100644 index 0000000..30fa923 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/regrtest_data/wrong_import_position.py @@ -0,0 +1,11 @@ +"""Test that wrong-import-position is properly reset when +other errors are disabled. +""" +# pylint: disable=unused-import, too-few-public-methods + + +class Something(object): + """A class before an import.""" + + +import os diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/test_func.py b/basic python programmes/venv/Lib/site-packages/pylint/test/test_func.py new file mode 100644 index 0000000..091a6d7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/test_func.py @@ -0,0 +1,158 @@ +# Copyright (c) 2006-2010, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Michka Popoff <michkapopoff@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""functional/non regression tests for pylint""" + +import sys +import re + +import pytest +from os.path import abspath, dirname, join + +from pylint.testutils import _get_tests_info, linter + +PY3K = sys.version_info >= (3, 0) +SYS_VERS_STR = "%d%d%d" % sys.version_info[:3] + +# Configure paths +INPUT_DIR = join(dirname(abspath(__file__)), "input") +MSG_DIR = join(dirname(abspath(__file__)), "messages") + +FILTER_RGX = None +UPDATE = False +INFO_TEST_RGX = re.compile(r"^func_i\d\d\d\d$") + +# Classes + +quote = "'" if sys.version_info >= (3, 3) else "" + + +def exception_str(self, ex): # pylint: disable=unused-argument + """function used to replace default __str__ method of exception instances""" + return "in %s\n:: %s" % (ex.file, ", ".join(ex.args)) + + +class LintTestUsingModule(object): + INPUT_DIR = None + DEFAULT_PACKAGE = "input" + package = DEFAULT_PACKAGE + linter = linter + module = None + depends = None + output = None + _TEST_TYPE = "module" + + # def runTest(self): + # # This is a hack to make ./test/test_func.py work under pytest. + # pass + + def _test_functionality(self): + tocheck = [self.package + "." + self.module] + # pylint: disable=not-an-iterable; can't handle boolean checks for now + if self.depends: + tocheck += [ + self.package + ".%s" % name.replace(".py", "") + for name, _ in self.depends + ] + self._test(tocheck) + + def _check_result(self, got): + assert self._get_expected().strip() + "\n" == got.strip() + "\n" + + def _test(self, tocheck): + if INFO_TEST_RGX.match(self.module): + self.linter.enable("I") + else: + self.linter.disable("I") + try: + self.linter.check(tocheck) + except Exception as ex: + # need finalization to restore a correct state + self.linter.reporter.finalize() + ex.file = tocheck + print(ex) + ex.__str__ = exception_str + raise + self._check_result(self.linter.reporter.finalize()) + + def _has_output(self): + return not self.module.startswith("func_noerror_") + + def _get_expected(self): + if self._has_output() and self.output: + with open(self.output, "U") as fobj: + return fobj.read().strip() + "\n" + else: + return "" + + +class LintTestUpdate(LintTestUsingModule): + + _TEST_TYPE = "update" + + def _check_result(self, got): + if self._has_output(): + try: + expected = self._get_expected() + except IOError: + expected = "" + if got != expected: + with open(self.output, "w") as fobj: + fobj.write(got) + + +def gen_tests(filter_rgx): + if filter_rgx: + is_to_run = re.compile(filter_rgx).search + else: + is_to_run = lambda x: 1 + tests = [] + for module_file, messages_file in _get_tests_info(INPUT_DIR, MSG_DIR, "func_", ""): + if not is_to_run(module_file) or module_file.endswith((".pyc", "$py.class")): + continue + base = module_file.replace(".py", "").split("_")[1] + dependencies = _get_tests_info(INPUT_DIR, MSG_DIR, base, ".py") + tests.append((module_file, messages_file, dependencies)) + + if UPDATE: + return tests + + assert len(tests) < 196, "Please do not add new test cases here." + return tests + + +@pytest.mark.parametrize( + "module_file,messages_file,dependencies", + gen_tests(FILTER_RGX), + ids=[o[0] for o in gen_tests(FILTER_RGX)], +) +def test_functionality(module_file, messages_file, dependencies): + + LT = LintTestUpdate() if UPDATE else LintTestUsingModule() + + LT.module = module_file.replace(".py", "") + LT.output = messages_file + LT.depends = dependencies or None + LT.INPUT_DIR = INPUT_DIR + LT._test_functionality() + + +if __name__ == "__main__": + if "-u" in sys.argv: + UPDATE = True + sys.argv.remove("-u") + + if len(sys.argv) > 1: + FILTER_RGX = sys.argv[1] + del sys.argv[1] + pytest.main(sys.argv) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/test_functional.py b/basic python programmes/venv/Lib/site-packages/pylint/test/test_functional.py new file mode 100644 index 0000000..576cd0d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/test_functional.py @@ -0,0 +1,386 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Functional full-module tests for PyLint.""" +import csv +import collections +import io +import operator +import os +import re +import sys +import platform + +import six +from six.moves import configparser + +import pytest + +from pylint import checkers +from pylint import interfaces +from pylint import lint +from pylint import reporters + +class test_dialect(csv.excel): + if sys.version_info[0] < 3: + delimiter = b':' + lineterminator = b'\n' + else: + delimiter = ':' + lineterminator = '\n' + + +csv.register_dialect('test', test_dialect) + + +class NoFileError(Exception): + pass + +# Notes: +# - for the purpose of this test, the confidence levels HIGH and UNDEFINED +# are treated as the same. + +# TODOs +# - implement exhaustivity tests + +# If message files should be updated instead of checked. +UPDATE = False + +class OutputLine(collections.namedtuple('OutputLine', + ['symbol', 'lineno', 'object', 'msg', 'confidence'])): + @classmethod + def from_msg(cls, msg): + return cls( + msg.symbol, msg.line, msg.obj or '', msg.msg.replace("\r\n", "\n"), + msg.confidence.name + if msg.confidence != interfaces.UNDEFINED else interfaces.HIGH.name) + + @classmethod + def from_csv(cls, row): + confidence = row[4] if len(row) == 5 else interfaces.HIGH.name + return cls(row[0], int(row[1]), row[2], row[3], confidence) + + def to_csv(self): + if self.confidence == interfaces.HIGH.name: + return self[:-1] + else: + return self + + +# Common sub-expressions. +_MESSAGE = {'msg': r'[a-z][a-z\-]+'} +# Matches a #, +# - followed by a comparison operator and a Python version (optional), +# - followed by a line number with a +/- (optional), +# - followed by a list of bracketed message symbols. +# Used to extract expected messages from testdata files. +_EXPECTED_RE = re.compile( + r'\s*#\s*(?:(?P<line>[+-]?[0-9]+):)?' + r'(?:(?P<op>[><=]+) *(?P<version>[0-9.]+):)?' + r'\s*\[(?P<msgs>%(msg)s(?:,\s*%(msg)s)*)\]' % _MESSAGE) + + +def parse_python_version(str): + return tuple(int(digit) for digit in str.split('.')) + + +class FunctionalTestReporter(reporters.BaseReporter): + def handle_message(self, msg): + self.messages.append(msg) + + def on_set_current_module(self, module, filepath): + self.messages = [] + + def display_reports(self, layout): + """Ignore layouts.""" + + +class FunctionalTestFile(object): + """A single functional test case file with options.""" + + _CONVERTERS = { + 'min_pyver': parse_python_version, + 'max_pyver': parse_python_version, + 'requires': lambda s: s.split(',') + } + + + def __init__(self, directory, filename): + self._directory = directory + self.base = filename.replace('.py', '') + self.options = { + 'min_pyver': (2, 5), + 'max_pyver': (4, 0), + 'requires': [], + 'except_implementations': [], + } + self._parse_options() + + def _parse_options(self): + cp = configparser.ConfigParser() + cp.add_section('testoptions') + try: + cp.read(self.option_file) + except NoFileError: + pass + + for name, value in cp.items('testoptions'): + conv = self._CONVERTERS.get(name, lambda v: v) + self.options[name] = conv(value) + + @property + def option_file(self): + return self._file_type('.rc') + + @property + def module(self): + package = os.path.basename(self._directory) + return '.'.join([package, self.base]) + + @property + def expected_output(self): + return self._file_type('.txt', check_exists=False) + + @property + def source(self): + return self._file_type('.py') + + def _file_type(self, ext, check_exists=True): + name = os.path.join(self._directory, self.base + ext) + if not check_exists or os.path.exists(name): + return name + else: + raise NoFileError + + +_OPERATORS = { + '>': operator.gt, + '<': operator.lt, + '>=': operator.ge, + '<=': operator.le, +} + +def parse_expected_output(stream): + return [OutputLine.from_csv(row) for row in csv.reader(stream, 'test')] + + +def get_expected_messages(stream): + """Parses a file and get expected messages. + + :param stream: File-like input stream. + :returns: A dict mapping line,msg-symbol tuples to the count on this line. + """ + messages = collections.Counter() + for i, line in enumerate(stream): + match = _EXPECTED_RE.search(line) + if match is None: + continue + line = match.group('line') + if line is None: + line = i + 1 + elif line.startswith('+') or line.startswith('-'): + line = i + 1 + int(line) + else: + line = int(line) + + version = match.group('version') + op = match.group('op') + if version: + required = parse_python_version(version) + if not _OPERATORS[op](sys.version_info, required): + continue + + for msg_id in match.group('msgs').split(','): + messages[line, msg_id.strip()] += 1 + return messages + + +def multiset_difference(left_op, right_op): + """Takes two multisets and compares them. + + A multiset is a dict with the cardinality of the key as the value. + + :param left_op: The expected entries. + :param right_op: Actual entries. + + :returns: The two multisets of missing and unexpected messages. + """ + missing = left_op.copy() + missing.subtract(right_op) + unexpected = {} + for key, value in list(six.iteritems(missing)): + if value <= 0: + missing.pop(key) + if value < 0: + unexpected[key] = -value + return missing, unexpected + + +class LintModuleTest(object): + maxDiff = None + + def __init__(self, test_file): + test_reporter = FunctionalTestReporter() + self._linter = lint.PyLinter() + self._linter.set_reporter(test_reporter) + self._linter.config.persistent = 0 + checkers.initialize(self._linter) + self._linter.disable('I') + try: + self._linter.read_config_file(test_file.option_file) + self._linter.load_config_file() + except NoFileError: + pass + self._test_file = test_file + + def setUp(self): + if self._should_be_skipped_due_to_version(): + pytest.skip( 'Test cannot run with Python %s.' % (sys.version.split(' ')[0],)) + missing = [] + for req in self._test_file.options['requires']: + try: + __import__(req) + except ImportError: + missing.append(req) + if missing: + pytest.skip('Requires %s to be present.' % (','.join(missing),)) + if self._test_file.options['except_implementations']: + implementations = [ + item.strip() for item in + self._test_file.options['except_implementations'].split(",") + ] + implementation = platform.python_implementation() + if implementation in implementations: + pytest.skip( + 'Test cannot run with Python implementation %r' + % (implementation, )) + + def _should_be_skipped_due_to_version(self): + return (sys.version_info < self._test_file.options['min_pyver'] or + sys.version_info > self._test_file.options['max_pyver']) + + def __str__(self): + return "%s (%s.%s)" % (self._test_file.base, self.__class__.__module__, + self.__class__.__name__) + + def _open_expected_file(self): + return open(self._test_file.expected_output) + + def _open_source_file(self): + if self._test_file.base == "invalid_encoded_data": + return open(self._test_file.source) + if "latin1" in self._test_file.base: + return io.open(self._test_file.source, encoding="latin1") + return io.open(self._test_file.source, encoding="utf8") + + def _get_expected(self): + with self._open_source_file() as fobj: + expected_msgs = get_expected_messages(fobj) + + if expected_msgs: + with self._open_expected_file() as fobj: + expected_output_lines = parse_expected_output(fobj) + else: + expected_output_lines = [] + return expected_msgs, expected_output_lines + + def _get_received(self): + messages = self._linter.reporter.messages + messages.sort(key=lambda m: (m.line, m.symbol, m.msg)) + received_msgs = collections.Counter() + received_output_lines = [] + for msg in messages: + received_msgs[msg.line, msg.symbol] += 1 + received_output_lines.append(OutputLine.from_msg(msg)) + return received_msgs, received_output_lines + + def _runTest(self): + self._linter.check([self._test_file.module]) + + expected_messages, expected_text = self._get_expected() + received_messages, received_text = self._get_received() + + if expected_messages != received_messages: + msg = ['Wrong results for file "%s":' % (self._test_file.base)] + missing, unexpected = multiset_difference(expected_messages, + received_messages) + if missing: + msg.append('\nExpected in testdata:') + msg.extend(' %3d: %s' % msg for msg in sorted(missing)) + if unexpected: + msg.append('\nUnexpected in testdata:') + msg.extend(' %3d: %s' % msg for msg in sorted(unexpected)) + pytest.fail('\n'.join(msg)) + self._check_output_text(expected_messages, expected_text, received_text) + + def _split_lines(self, expected_messages, lines): + emitted, omitted = [], [] + for msg in lines: + if (msg[1], msg[0]) in expected_messages: + emitted.append(msg) + else: + omitted.append(msg) + return emitted, omitted + + def _check_output_text(self, expected_messages, expected_lines, + received_lines): + assert self._split_lines(expected_messages, expected_lines)[0] == \ + received_lines, self._test_file.base + + +class LintModuleOutputUpdate(LintModuleTest): + def _open_expected_file(self): + try: + return super(LintModuleOutputUpdate, self)._open_expected_file() + except IOError: + return io.StringIO() + + def _check_output_text(self, expected_messages, expected_lines, + received_lines): + if not expected_messages: + return + emitted, remaining = self._split_lines(expected_messages, expected_lines) + if emitted != received_lines: + remaining.extend(received_lines) + remaining.sort(key=lambda m: (m[1], m[0], m[3])) + with open(self._test_file.expected_output, 'w') as fobj: + writer = csv.writer(fobj, dialect='test') + for line in remaining: + writer.writerow(line.to_csv()) + +def get_tests(): + input_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), + 'functional') + suite = [] + for fname in os.listdir(input_dir): + if fname != '__init__.py' and fname.endswith('.py'): + suite.append(FunctionalTestFile(input_dir, fname)) + return suite + + +TESTS = get_tests() +TESTS_NAMES = [t.base for t in TESTS] + + +@pytest.mark.parametrize("test_file", TESTS, ids=TESTS_NAMES) +def test_functional(test_file): + LintTest = LintModuleOutputUpdate(test_file) if UPDATE else LintModuleTest(test_file) + LintTest.setUp() + LintTest._runTest() + + +if __name__ == '__main__': + if '-u' in sys.argv: + UPDATE = True + sys.argv.remove('-u') + pytest.main(sys.argv) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/test_import_graph.py b/basic python programmes/venv/Lib/site-packages/pylint/test/test_import_graph.py new file mode 100644 index 0000000..2181645 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/test_import_graph.py @@ -0,0 +1,84 @@ +# Copyright (c) 2006-2008, 2010, 2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Reverb C <reverbc@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import os +from os.path import exists + +import pytest + +from pylint.checkers import initialize, imports +from pylint.lint import PyLinter + +import pylint.testutils as testutils + + +@pytest.fixture +def dest(): + dest = "dependencies_graph.dot" + yield dest + os.remove(dest) + + +def test_dependencies_graph(dest): + imports._dependencies_graph(dest, {"labas": ["hoho", "yep"], "hoho": ["yep"]}) + with open(dest) as stream: + assert ( + stream.read().strip() + == """ +digraph "dependencies_graph" { +rankdir=LR +charset="utf-8" +URL="." node[shape="box"] +"hoho" []; +"yep" []; +"labas" []; +"yep" -> "hoho" []; +"hoho" -> "labas" []; +"yep" -> "labas" []; +} +""".strip() + ) + + +@pytest.fixture +def linter(): + l = PyLinter(reporter=testutils.TestReporter()) + initialize(l) + return l + + +@pytest.fixture +def remove_files(): + yield + for fname in ("import.dot", "ext_import.dot", "int_import.dot"): + try: + os.remove(fname) + except: + pass + + +@pytest.mark.usefixtures("remove_files") +def test_checker_dep_graphs(linter): + l = linter + l.global_set_option("persistent", False) + l.global_set_option("reports", True) + l.global_set_option("enable", "imports") + l.global_set_option("import-graph", "import.dot") + l.global_set_option("ext-import-graph", "ext_import.dot") + l.global_set_option("int-import-graph", "int_import.dot") + l.global_set_option("int-import-graph", "int_import.dot") + # ignore this file causing spurious MemoryError w/ some python version (>=2.3?) + l.global_set_option("ignore", ("func_unknown_encoding.py",)) + l.check("input") + l.generate_reports() + assert exists("import.dot") + assert exists("ext_import.dot") + assert exists("int_import.dot") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/test_regr.py b/basic python programmes/venv/Lib/site-packages/pylint/test/test_regr.py new file mode 100644 index 0000000..c3e0260 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/test_regr.py @@ -0,0 +1,139 @@ +# Copyright (c) 2006-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Reverb C <reverbc@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""non regression tests for pylint, which requires a too specific configuration +to be incorporated in the automatic functional test framework +""" + +import sys +import os +from os.path import abspath, dirname, join + +import pytest + +import astroid +import pylint.testutils as testutils +from pylint import epylint + + +REGR_DATA = join(dirname(abspath(__file__)), "regrtest_data") +sys.path.insert(1, REGR_DATA) + +try: + PYPY_VERSION_INFO = sys.pypy_version_info +except AttributeError: + PYPY_VERSION_INFO = None + + +@pytest.fixture(scope="module") +def reporter(reporter): + return testutils.TestReporter + + +@pytest.fixture(scope="module") +def disable(disable): + return ["I"] + + +@pytest.fixture +def finalize_linter(linter): + """call reporter.finalize() to cleanup + pending messages if a test finished badly + """ + yield linter + linter.reporter.finalize() + + +def Equals(expected): + return lambda got: got == expected + + +@pytest.mark.parametrize( + "file_name, check", + [ + ("package.__init__", Equals("")), + ("precedence_test", Equals("")), + ("import_package_subpackage_module", Equals("")), + ("pylint.checkers.__init__", lambda x: "__path__" not in x), + (join(REGR_DATA, "classdoc_usage.py"), Equals("")), + (join(REGR_DATA, "module_global.py"), Equals("")), + (join(REGR_DATA, "decimal_inference.py"), Equals("")), + (join(REGR_DATA, "absimp", "string.py"), Equals("")), + (join(REGR_DATA, "bad_package"), lambda x: "Unused import missing" in x), + ], +) +def test_package(finalize_linter, file_name, check): + finalize_linter.check(file_name) + got = finalize_linter.reporter.finalize().strip() + assert check(got) + + +@pytest.mark.parametrize( + "file_name", + [ + join(REGR_DATA, "import_assign.py"), + join(REGR_DATA, "special_attr_scope_lookup_crash.py"), + join(REGR_DATA, "try_finally_disable_msg_crash"), + ], +) +def test_crash(finalize_linter, file_name): + finalize_linter.check(file_name) + + +@pytest.mark.parametrize( + "fname", [x for x in os.listdir(REGR_DATA) if x.endswith("_crash.py")] +) +def test_descriptor_crash(fname, finalize_linter): + finalize_linter.check(join(REGR_DATA, fname)) + finalize_linter.reporter.finalize().strip() + + +@pytest.fixture +def modify_path(): + cwd = os.getcwd() + sys.path.insert(0, "") + yield + sys.path.pop(0) + os.chdir(cwd) + + +@pytest.mark.usefixtures("modify_path") +def test_check_package___init__(finalize_linter): + filename = "package.__init__" + finalize_linter.check(filename) + checked = list(finalize_linter.stats["by_module"].keys()) + assert checked == [filename] + + os.chdir(join(REGR_DATA, "package")) + finalize_linter.check("__init__") + checked = list(finalize_linter.stats["by_module"].keys()) + assert checked == ["__init__"] + + +def test_pylint_config_attr(): + mod = astroid.MANAGER.ast_from_module_name("pylint.lint") + pylinter = mod["PyLinter"] + expect = [ + "OptionsManagerMixIn", + "object", + "MessagesHandlerMixIn", + "ReportsHandlerMixIn", + "BaseTokenChecker", + "BaseChecker", + "OptionsProviderMixIn", + ] + assert [c.name for c in pylinter.ancestors()] == expect + assert list(astroid.Instance(pylinter).getattr("config")) + inferred = list(astroid.Instance(pylinter).igetattr("config")) + assert len(inferred) == 1 + assert inferred[0].root().name == "optparse" + assert inferred[0].name == "Values" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/test_self.py b/basic python programmes/venv/Lib/site-packages/pylint/test/test_self.py new file mode 100644 index 0000000..cbc2317 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/test_self.py @@ -0,0 +1,548 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Vlad Temian <vladtemian@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2017 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Daniel Miller <millerdev@gmail.com> +# Copyright (c) 2017 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2017 Thomas Hisch <t.hisch@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Jason Owen <jason.a.owen@gmail.com> +# Copyright (c) 2018 Jace Browning <jacebrowning@gmail.com> +# Copyright (c) 2018 Reverb C <reverbc@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import contextlib +import json +import re +import sys +import os +from os.path import join, dirname, abspath +import tempfile +import textwrap +import configparser +from io import StringIO + +from pylint.lint import Run +from pylint.reporters import BaseReporter +from pylint.reporters.text import * +from pylint.reporters.json import JSONReporter +import pytest +from pylint import utils + +HERE = abspath(dirname(__file__)) + + +@contextlib.contextmanager +def _patch_streams(out): + sys.stderr = sys.stdout = out + try: + yield + finally: + sys.stderr = sys.__stderr__ + sys.stdout = sys.__stdout__ + + +@contextlib.contextmanager +def _configure_lc_ctype(lc_ctype): + lc_ctype_env = "LC_CTYPE" + original_lctype = os.environ.get(lc_ctype_env) + os.environ[lc_ctype_env] = lc_ctype + try: + yield + finally: + os.environ.pop(lc_ctype_env) + if original_lctype: + os.environ[lc_ctype_env] = original_lctype + + +class MultiReporter(BaseReporter): + def __init__(self, reporters): + self._reporters = reporters + self.path_strip_prefix = os.getcwd() + os.sep + + def on_set_current_module(self, *args, **kwargs): + for rep in self._reporters: + rep.on_set_current_module(*args, **kwargs) + + def handle_message(self, msg): + for rep in self._reporters: + rep.handle_message(msg) + + def display_reports(self, layout): + pass + + @property + def out(self): + return self._reporters[0].out + + @property + def linter(self): + return self._linter + + @linter.setter + def linter(self, value): + self._linter = value + for rep in self._reporters: + rep.linter = value + + +class TestRunTC(object): + def _runtest(self, args, reporter=None, out=None, code=None): + if out is None: + out = StringIO() + pylint_code = self._run_pylint(args, reporter=reporter, out=out) + if reporter: + output = reporter.out.getvalue() + elif hasattr(out, "getvalue"): + output = out.getvalue() + else: + output = None + msg = "expected output status %s, got %s" % (code, pylint_code) + if output is not None: + msg = "%s. Below pylint output: \n%s" % (msg, output) + assert pylint_code == code, msg + + def _run_pylint(self, args, out, reporter=None): + args = args + ["--persistent=no"] + with _patch_streams(out): + with pytest.raises(SystemExit) as cm: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + Run(args, reporter=reporter) + return cm.value.code + + def _clean_paths(self, output): + """Remove version-specific tox parent directories from paths.""" + return re.sub( + "^py.+/site-packages/", "", output.replace("\\", "/"), flags=re.MULTILINE + ) + + def _test_output(self, args, expected_output): + out = StringIO() + self._run_pylint(args, out=out) + actual_output = self._clean_paths(out.getvalue()) + assert expected_output.strip() in actual_output.strip() + + def test_pkginfo(self): + """Make pylint check itself.""" + self._runtest(["pylint.__pkginfo__"], reporter=TextReporter(StringIO()), code=0) + + def test_all(self): + """Make pylint check itself.""" + reporters = [ + TextReporter(StringIO()), + ColorizedTextReporter(StringIO()), + JSONReporter(StringIO()), + ] + self._runtest( + [join(HERE, "functional/arguments.py")], + reporter=MultiReporter(reporters), + code=2, + ) + + def test_no_ext_file(self): + self._runtest([join(HERE, "input", "noext")], code=0) + + def test_w0704_ignored(self): + self._runtest([join(HERE, "input", "ignore_except_pass_by_default.py")], code=0) + + def test_exit_zero(self): + self._runtest( + ["--exit-zero", join(HERE, "regrtest_data", "syntax_error.py")], code=0 + ) + + def test_generate_config_option(self): + self._runtest(["--generate-rcfile"], code=0) + + def test_generate_config_option_order(self): + out1 = StringIO() + out2 = StringIO() + self._runtest(["--generate-rcfile"], code=0, out=out1) + self._runtest(["--generate-rcfile"], code=0, out=out2) + output1 = out1.getvalue() + output2 = out2.getvalue() + assert output1 == output2 + + def test_generate_config_disable_symbolic_names(self): + # Test that --generate-rcfile puts symbolic names in the --disable + # option. + + out = StringIO() + self._run_pylint(["--generate-rcfile", "--rcfile="], out=out) + + output = out.getvalue() + # Get rid of the pesky messages that pylint emits if the + # configuration file is not found. + master = re.search(r"\[MASTER", output) + out = StringIO(output[master.start() :]) + parser = configparser.RawConfigParser() + parser.readfp(out) + messages = utils._splitstrip(parser.get("MESSAGES CONTROL", "disable")) + assert "suppressed-message" in messages + + def test_generate_rcfile_no_obsolete_methods(self): + out = StringIO() + self._run_pylint(["--generate-rcfile"], out=out) + output = out.getvalue() + assert "profile" not in output + + def test_inexisting_rcfile(self): + out = StringIO() + with pytest.raises(IOError) as excinfo: + self._run_pylint(["--rcfile=/tmp/norcfile.txt"], out=out) + assert "The config file /tmp/norcfile.txt doesn't exist!" == str(excinfo.value) + + def test_help_message_option(self): + self._runtest(["--help-msg", "W0101"], code=0) + + def test_error_help_message_option(self): + self._runtest(["--help-msg", "WX101"], code=0) + + def test_error_missing_arguments(self): + self._runtest([], code=32) + + def test_no_out_encoding(self): + """test redirection of stdout with non ascii caracters + """ + # This test reproduces bug #48066 ; it happens when stdout is redirected + # through '>' : the sys.stdout.encoding becomes then None, and if the + # output contains non ascii, pylint will crash + if sys.version_info < (3, 0): + strio = tempfile.TemporaryFile() + else: + strio = StringIO() + assert strio.encoding is None + self._runtest( + [join(HERE, "regrtest_data/no_stdout_encoding.py"), "--enable=all"], + out=strio, + code=28, + ) + + def test_parallel_execution(self): + self._runtest( + [ + "-j 2", + join(HERE, "functional/arguments.py"), + join(HERE, "functional/arguments.py"), + ], + code=2, + ) + + def test_parallel_execution_missing_arguments(self): + self._runtest(["-j 2", "not_here", "not_here_too"], code=1) + + def test_py3k_option(self): + # Test that --py3k flag works. + rc_code = 0 + self._runtest( + [join(HERE, "functional", "unpacked_exceptions.py"), "--py3k"], code=rc_code + ) + + def test_py3k_jobs_option(self): + rc_code = 0 + self._runtest( + [join(HERE, "functional", "unpacked_exceptions.py"), "--py3k", "-j 2"], + code=rc_code, + ) + + @pytest.mark.skipif(sys.version_info[0] > 2, reason="Requires the --py3k flag.") + def test_py3k_commutative_with_errors_only(self): + + # Test what gets emitted with -E only + module = join(HERE, "regrtest_data", "py3k_error_flag.py") + expected = textwrap.dedent( + """ + ************* Module py3k_error_flag + Explicit return in __init__ + """ + ) + self._test_output( + [module, "-E", "--msg-template='{msg}'"], expected_output=expected + ) + + # Test what gets emitted with -E --py3k + expected = textwrap.dedent( + """ + ************* Module py3k_error_flag + Use raise ErrorClass(args) instead of raise ErrorClass, args. + """ + ) + self._test_output( + [module, "-E", "--py3k", "--msg-template='{msg}'"], expected_output=expected + ) + + # Test what gets emitted with --py3k -E + self._test_output( + [module, "--py3k", "-E", "--msg-template='{msg}'"], expected_output=expected + ) + + @pytest.mark.skipif(sys.version_info[0] > 2, reason="Requires the --py3k flag.") + def test_py3k_commutative_with_config_disable(self): + module = join(HERE, "regrtest_data", "py3k_errors_and_warnings.py") + rcfile = join(HERE, "regrtest_data", "py3k-disabled.rc") + cmd = [module, "--msg-template='{msg}'", "--reports=n"] + + expected = textwrap.dedent( + """ + ************* Module py3k_errors_and_warnings + import missing `from __future__ import absolute_import` + Use raise ErrorClass(args) instead of raise ErrorClass, args. + Calling a dict.iter*() method + print statement used + """ + ) + self._test_output(cmd + ["--py3k"], expected_output=expected) + + expected = textwrap.dedent( + """ + ************* Module py3k_errors_and_warnings + Use raise ErrorClass(args) instead of raise ErrorClass, args. + Calling a dict.iter*() method + print statement used + """ + ) + self._test_output( + cmd + ["--py3k", "--rcfile", rcfile], expected_output=expected + ) + + expected = textwrap.dedent( + """ + ************* Module py3k_errors_and_warnings + Use raise ErrorClass(args) instead of raise ErrorClass, args. + print statement used + """ + ) + self._test_output( + cmd + ["--py3k", "-E", "--rcfile", rcfile], expected_output=expected + ) + + self._test_output( + cmd + ["-E", "--py3k", "--rcfile", rcfile], expected_output=expected + ) + + def test_abbreviations_are_not_supported(self): + expected = "no such option: --load-plugin" + self._test_output([".", "--load-plugin"], expected_output=expected) + + def test_enable_all_works(self): + module = join(HERE, "data", "clientmodule_test.py") + expected = textwrap.dedent( + """ + ************* Module data.clientmodule_test + pylint/test/data/clientmodule_test.py:10:8: W0612: Unused variable 'local_variable' (unused-variable) + pylint/test/data/clientmodule_test.py:18:4: C0111: Missing method docstring (missing-docstring) + pylint/test/data/clientmodule_test.py:22:0: C0111: Missing class docstring (missing-docstring) + """ + ) + self._test_output( + [module, "--disable=all", "--enable=all", "-rn"], expected_output=expected + ) + + def test_wrong_import_position_when_others_disabled(self): + expected_output = textwrap.dedent( + """ + ************* Module wrong_import_position + pylint/test/regrtest_data/wrong_import_position.py:11:0: C0413: Import "import os" should be placed at the top of the module (wrong-import-position) + """ + ) + module1 = join(HERE, "regrtest_data", "import_something.py") + module2 = join(HERE, "regrtest_data", "wrong_import_position.py") + args = [ + module2, + module1, + "--disable=all", + "--enable=wrong-import-position", + "-rn", + "-sn", + ] + out = StringIO() + self._run_pylint(args, out=out) + actual_output = self._clean_paths(out.getvalue().strip()) + + to_remove = "No config file found, using default configuration" + if to_remove in actual_output: + actual_output = actual_output[len(to_remove) :] + if actual_output.startswith("Using config file "): + # If ~/.pylintrc is present remove the + # Using config file... line + actual_output = actual_output[actual_output.find("\n") :] + assert expected_output.strip() == actual_output.strip() + + def test_import_itself_not_accounted_for_relative_imports(self): + expected = "Your code has been rated at 10.00/10" + package = join(HERE, "regrtest_data", "dummy") + self._test_output( + [package, "--disable=locally-disabled", "-rn"], expected_output=expected + ) + + def test_reject_empty_indent_strings(self): + expected = "indent string can't be empty" + module = join(HERE, "data", "clientmodule_test.py") + self._test_output([module, "--indent-string="], expected_output=expected) + + def test_json_report_when_file_has_syntax_error(self): + out = StringIO() + module = join(HERE, "regrtest_data", "syntax_error.py") + self._runtest([module], code=2, reporter=JSONReporter(out)) + output = json.loads(out.getvalue()) + assert isinstance(output, list) + assert len(output) == 1 + assert isinstance(output[0], dict) + expected = { + "obj": "", + "column": 0, + "line": 1, + "type": "error", + "symbol": "syntax-error", + "module": "syntax_error", + } + message = output[0] + for key, value in expected.items(): + assert key in message + assert message[key] == value + assert "invalid syntax" in message["message"].lower() + + def test_json_report_when_file_is_missing(self): + out = StringIO() + module = join(HERE, "regrtest_data", "totally_missing.py") + self._runtest([module], code=1, reporter=JSONReporter(out)) + output = json.loads(out.getvalue()) + assert isinstance(output, list) + assert len(output) == 1 + assert isinstance(output[0], dict) + expected = { + "obj": "", + "column": 0, + "line": 1, + "type": "fatal", + "symbol": "fatal", + "module": module, + } + message = output[0] + for key, value in expected.items(): + assert key in message + assert message[key] == value + assert message["message"].startswith("No module named") + + def test_information_category_disabled_by_default(self): + expected = "Your code has been rated at 10.00/10" + path = join(HERE, "regrtest_data", "meta.py") + self._test_output([path], expected_output=expected) + + def test_error_mode_shows_no_score(self): + expected_output = textwrap.dedent( + """ + ************* Module application_crash + pylint/test/regrtest_data/application_crash.py:1:6: E0602: Undefined variable 'something_undefined' (undefined-variable) + """ + ) + module = join(HERE, "regrtest_data", "application_crash.py") + self._test_output([module, "-E"], expected_output=expected_output) + + def test_evaluation_score_shown_by_default(self): + expected_output = "Your code has been rated at " + module = join(HERE, "regrtest_data", "application_crash.py") + self._test_output([module], expected_output=expected_output) + + def test_confidence_levels(self): + expected = "Your code has been rated at" + path = join(HERE, "regrtest_data", "meta.py") + self._test_output( + [path, "--confidence=HIGH,INFERENCE"], expected_output=expected + ) + + def test_bom_marker(self): + path = join(HERE, "regrtest_data", "meta.py") + config_path = join(HERE, "regrtest_data", ".pylintrc") + expected = "Your code has been rated at 10.00/10" + self._test_output( + [path, "--rcfile=%s" % config_path, "-rn"], expected_output=expected + ) + + def test_pylintrc_plugin_duplicate_options(self): + dummy_plugin_path = join(HERE, "regrtest_data", "dummy_plugin") + # Enable --load-plugins=dummy_plugin + sys.path.append(dummy_plugin_path) + config_path = join(HERE, "regrtest_data", "dummy_plugin.rc") + expected = ( + ":dummy-message-01 (I9061): *Dummy short desc 01*\n" + " Dummy long desc This message belongs to the dummy_plugin checker.\n\n" + ":dummy-message-02 (I9060): *Dummy short desc 02*\n" + " Dummy long desc This message belongs to the dummy_plugin checker." + ) + self._test_output( + [ + "--rcfile=%s" % config_path, + "--help-msg=dummy-message-01,dummy-message-02", + ], + expected_output=expected, + ) + expected = ( + "[DUMMY_PLUGIN]\n\n# Dummy option 1\ndummy_option_1=dummy value 1\n\n" + "# Dummy option 2\ndummy_option_2=dummy value 2" + ) + self._test_output( + ["--rcfile=%s" % config_path, "--generate-rcfile"], expected_output=expected + ) + sys.path.remove(dummy_plugin_path) + + def test_pylintrc_comments_in_values(self): + path = join(HERE, "regrtest_data", "test_pylintrc_comments.py") + config_path = join(HERE, "regrtest_data", "comments_pylintrc") + expected = textwrap.dedent( + """ + ************* Module test_pylintrc_comments + pylint/test/regrtest_data/test_pylintrc_comments.py:2:0: W0311: Bad indentation. Found 1 spaces, expected 4 (bad-indentation) + pylint/test/regrtest_data/test_pylintrc_comments.py:1:0: C0111: Missing module docstring (missing-docstring) + pylint/test/regrtest_data/test_pylintrc_comments.py:1:0: C0111: Missing function docstring (missing-docstring) + """ + ) + self._test_output( + [path, "--rcfile=%s" % config_path, "-rn"], expected_output=expected + ) + + def test_no_crash_with_formatting_regex_defaults(self): + self._runtest( + ["--ignore-patterns=a"], reporter=TextReporter(StringIO()), code=32 + ) + + def test_getdefaultencoding_crashes_with_lc_ctype_utf8(self): + expected_output = textwrap.dedent( + """ + ************* Module application_crash + pylint/test/regrtest_data/application_crash.py:1:6: E0602: Undefined variable 'something_undefined' (undefined-variable) + """ + ) + module = join(HERE, "regrtest_data", "application_crash.py") + with _configure_lc_ctype("UTF-8"): + self._test_output([module, "-E"], expected_output=expected_output) + + @pytest.mark.skipif(sys.platform == "win32", reason="only occurs on *nix") + def test_parseable_file_path(self): + file_name = "test_target.py" + fake_path = HERE + os.getcwd() + module = join(fake_path, file_name) + + try: + # create module under directories which have the same name as reporter.path_strip_prefix + # e.g. /src/some/path/src/test_target.py when reporter.path_strip_prefix = /src/ + os.makedirs(fake_path) + with open(module, "w") as test_target: + test_target.write("a,b = object()") + + self._test_output( + [module, "--output-format=parseable"], + expected_output=join(os.getcwd(), file_name), + ) + finally: + os.remove(module) + os.removedirs(fake_path) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_base.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_base.py new file mode 100644 index 0000000..a1607cf --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_base.py @@ -0,0 +1,527 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2013-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Yannack <yannack@users.noreply.github.com> +# Copyright (c) 2017 ttenhoeve-aa <ttenhoeve@appannie.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2018 Fureigh <fureigh@users.noreply.github.com> +# Copyright (c) 2018 glmdgrielson <32415403+glmdgrielson@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unittest for the base checker.""" + +import re +import sys +import unittest + +import astroid +from pylint.checkers import base +from pylint.testutils import CheckerTestCase, Message, set_config + + +class TestDocstring(CheckerTestCase): + CHECKER_CLASS = base.DocStringChecker + + def test_missing_docstring_module(self): + module = astroid.parse("something") + message = Message("missing-docstring", node=module, args=("module",)) + with self.assertAddsMessages(message): + self.checker.visit_module(module) + + def test_missing_docstring_empty_module(self): + module = astroid.parse("") + with self.assertNoMessages(): + self.checker.visit_module(module) + + def test_empty_docstring_module(self): + module = astroid.parse("''''''") + message = Message("empty-docstring", node=module, args=("module",)) + with self.assertAddsMessages(message): + self.checker.visit_module(module) + + def test_empty_docstring_function(self): + func = astroid.extract_node( + """ + def func(tion): + pass""" + ) + message = Message("missing-docstring", node=func, args=("function",)) + with self.assertAddsMessages(message): + self.checker.visit_functiondef(func) + + @set_config(docstring_min_length=2) + def test_short_function_no_docstring(self): + func = astroid.extract_node( + """ + def func(tion): + pass""" + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(func) + + @set_config(docstring_min_length=2) + def test_long_function_no_docstring(self): + func = astroid.extract_node( + """ + def func(tion): + pass + pass + """ + ) + message = Message("missing-docstring", node=func, args=("function",)) + with self.assertAddsMessages(message): + self.checker.visit_functiondef(func) + + @set_config(docstring_min_length=2) + def test_long_function_nested_statements_no_docstring(self): + func = astroid.extract_node( + """ + def func(tion): + try: + pass + except: + pass + """ + ) + message = Message("missing-docstring", node=func, args=("function",)) + with self.assertAddsMessages(message): + self.checker.visit_functiondef(func) + + @set_config(docstring_min_length=2) + def test_function_no_docstring_by_name(self): + func = astroid.extract_node( + """ + def __fun__(tion): + pass""" + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(func) + + def test_class_no_docstring(self): + klass = astroid.extract_node( + """ + class Klass(object): + pass""" + ) + message = Message("missing-docstring", node=klass, args=("class",)) + with self.assertAddsMessages(message): + self.checker.visit_classdef(klass) + + def test_inner_function_no_docstring(self): + func = astroid.extract_node( + """ + def func(tion): + \"""Documented\""" + def inner(fun): + # Not documented + pass + """ + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(func) + + +class TestNameChecker(CheckerTestCase): + CHECKER_CLASS = base.NameChecker + CONFIG = {"bad_names": set()} + + @set_config( + attr_rgx=re.compile("[A-Z]+"), + property_classes=("abc.abstractproperty", ".custom_prop"), + ) + def test_property_names(self): + # If a method is annotated with @property, its name should + # match the attr regex. Since by default the attribute regex is the same + # as the method regex, we override it here. + methods = astroid.extract_node( + """ + import abc + + def custom_prop(f): + return property(f) + + class FooClass(object): + @property + def FOO(self): #@ + pass + + @property + def bar(self): #@ + pass + + @abc.abstractproperty + def BAZ(self): #@ + pass + + @custom_prop + def QUX(self): #@ + pass + """ + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(methods[0]) + self.checker.visit_functiondef(methods[2]) + self.checker.visit_functiondef(methods[3]) + with self.assertAddsMessages( + Message( + "invalid-name", + node=methods[1], + args=("Attribute", "bar", "'[A-Z]+' pattern"), + ) + ): + self.checker.visit_functiondef(methods[1]) + + @set_config(attr_rgx=re.compile("[A-Z]+")) + def test_property_setters(self): + method = astroid.extract_node( + """ + class FooClass(object): + @property + def foo(self): pass + + @foo.setter + def FOOSETTER(self): #@ + pass + """ + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(method) + + def test_module_level_names(self): + assign = astroid.extract_node( + """ + import collections + Class = collections.namedtuple("a", ("b", "c")) #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_assignname(assign.targets[0]) + + assign = astroid.extract_node( + """ + class ClassA(object): + pass + ClassB = ClassA + """ + ) + with self.assertNoMessages(): + self.checker.visit_assignname(assign.targets[0]) + + module = astroid.parse( + """ + def A(): + return 1, 2, 3 + CONSTA, CONSTB, CONSTC = A() + CONSTD = A()""" + ) + with self.assertNoMessages(): + self.checker.visit_assignname(module.body[1].targets[0].elts[0]) + self.checker.visit_assignname(module.body[2].targets[0]) + + assign = astroid.extract_node( + """ + CONST = "12 34 ".rstrip().split()""" + ) + with self.assertNoMessages(): + self.checker.visit_assignname(assign.targets[0]) + + @unittest.skipIf(sys.version_info >= (3, 7), reason="Needs Python 3.6 or earlier") + @set_config(const_rgx=re.compile(".+")) + @set_config(function_rgx=re.compile(".+")) + @set_config(class_rgx=re.compile(".+")) + def test_assign_to_new_keyword_py3(self): + ast = astroid.extract_node( + """ + async = "foo" #@ + await = "bar" #@ + def async(): #@ + pass + class async: #@ + pass + """ + ) + with self.assertAddsMessages( + Message( + msg_id="assign-to-new-keyword", + node=ast[0].targets[0], + args=("async", "3.7"), + ) + ): + self.checker.visit_assignname(ast[0].targets[0]) + with self.assertAddsMessages( + Message( + msg_id="assign-to-new-keyword", + node=ast[1].targets[0], + args=("await", "3.7"), + ) + ): + self.checker.visit_assignname(ast[1].targets[0]) + with self.assertAddsMessages( + Message(msg_id="assign-to-new-keyword", node=ast[2], args=("async", "3.7")) + ): + self.checker.visit_functiondef(ast[2]) + with self.assertAddsMessages( + Message(msg_id="assign-to-new-keyword", node=ast[3], args=("async", "3.7")) + ): + self.checker.visit_classdef(ast[3]) + + +class TestMultiNamingStyle(CheckerTestCase): + CHECKER_CLASS = base.NameChecker + + MULTI_STYLE_RE = re.compile("(?:(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$") + + @set_config(class_rgx=MULTI_STYLE_RE) + def test_multi_name_detection_majority(self): + classes = astroid.extract_node( + """ + class classb(object): #@ + pass + class CLASSA(object): #@ + pass + class CLASSC(object): #@ + pass + """ + ) + message = Message( + "invalid-name", + node=classes[0], + args=("Class", "classb", "'(?:(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$' pattern"), + ) + with self.assertAddsMessages(message): + for cls in classes: + self.checker.visit_classdef(cls) + self.checker.leave_module(cls.root) + + @set_config(class_rgx=MULTI_STYLE_RE) + def test_multi_name_detection_first_invalid(self): + classes = astroid.extract_node( + """ + class class_a(object): #@ + pass + class classb(object): #@ + pass + class CLASSC(object): #@ + pass + """ + ) + messages = [ + Message( + "invalid-name", + node=classes[0], + args=( + "Class", + "class_a", + "'(?:(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$' pattern", + ), + ), + Message( + "invalid-name", + node=classes[2], + args=( + "Class", + "CLASSC", + "'(?:(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$' pattern", + ), + ), + ] + with self.assertAddsMessages(*messages): + for cls in classes: + self.checker.visit_classdef(cls) + self.checker.leave_module(cls.root) + + @set_config( + method_rgx=MULTI_STYLE_RE, + function_rgx=MULTI_STYLE_RE, + name_group=("function:method",), + ) + def test_multi_name_detection_group(self): + function_defs = astroid.extract_node( + """ + class First(object): + def func(self): #@ + pass + + def FUNC(): #@ + pass + """, + module_name="test", + ) + message = Message( + "invalid-name", + node=function_defs[1], + args=("Function", "FUNC", "'(?:(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$' pattern"), + ) + with self.assertAddsMessages(message): + for func in function_defs: + self.checker.visit_functiondef(func) + self.checker.leave_module(func.root) + + @set_config( + function_rgx=re.compile("(?:(?P<ignore>FOO)|(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$") + ) + def test_multi_name_detection_exempt(self): + function_defs = astroid.extract_node( + """ + def FOO(): #@ + pass + def lower(): #@ + pass + def FOO(): #@ + pass + def UPPER(): #@ + pass + """ + ) + message = Message( + "invalid-name", + node=function_defs[3], + args=( + "Function", + "UPPER", + "'(?:(?P<ignore>FOO)|(?P<UP>[A-Z]+)|(?P<down>[a-z]+))$' pattern", + ), + ) + with self.assertAddsMessages(message): + for func in function_defs: + self.checker.visit_functiondef(func) + self.checker.leave_module(func.root) + + +class TestComparison(CheckerTestCase): + CHECKER_CLASS = base.ComparisonChecker + + def test_comparison(self): + node = astroid.extract_node("foo == True") + message = Message("singleton-comparison", node=node, args=(True, "just 'expr'")) + with self.assertAddsMessages(message): + self.checker.visit_compare(node) + + node = astroid.extract_node("foo == False") + message = Message("singleton-comparison", node=node, args=(False, "'not expr'")) + with self.assertAddsMessages(message): + self.checker.visit_compare(node) + + node = astroid.extract_node("foo == None") + message = Message( + "singleton-comparison", node=node, args=(None, "'expr is None'") + ) + with self.assertAddsMessages(message): + self.checker.visit_compare(node) + + node = astroid.extract_node("True == foo") + messages = ( + Message("misplaced-comparison-constant", node=node, args=("foo == True",)), + Message("singleton-comparison", node=node, args=(True, "just 'expr'")), + ) + with self.assertAddsMessages(*messages): + self.checker.visit_compare(node) + + node = astroid.extract_node("False == foo") + messages = ( + Message("misplaced-comparison-constant", node=node, args=("foo == False",)), + Message("singleton-comparison", node=node, args=(False, "'not expr'")), + ) + with self.assertAddsMessages(*messages): + self.checker.visit_compare(node) + + node = astroid.extract_node("None == foo") + messages = ( + Message("misplaced-comparison-constant", node=node, args=("foo == None",)), + Message("singleton-comparison", node=node, args=(None, "'expr is None'")), + ) + with self.assertAddsMessages(*messages): + self.checker.visit_compare(node) + + +class TestNamePresets(unittest.TestCase): + SNAKE_CASE_NAMES = {"test_snake_case", "test_snake_case11", "test_https_200"} + CAMEL_CASE_NAMES = {"testCamelCase", "testCamelCase11", "testHTTP200"} + UPPER_CASE_NAMES = {"TEST_UPPER_CASE", "TEST_UPPER_CASE11", "TEST_HTTP_200"} + PASCAL_CASE_NAMES = {"TestPascalCase", "TestPascalCase11", "TestHTTP200"} + ALL_NAMES = ( + SNAKE_CASE_NAMES | CAMEL_CASE_NAMES | UPPER_CASE_NAMES | PASCAL_CASE_NAMES + ) + + def _test_name_is_correct_for_all_name_types(self, naming_style, name): + for name_type in base.KNOWN_NAME_TYPES: + self._test_is_correct(naming_style, name, name_type) + + def _test_name_is_incorrect_for_all_name_types(self, naming_style, name): + for name_type in base.KNOWN_NAME_TYPES: + self._test_is_incorrect(naming_style, name, name_type) + + def _test_should_always_pass(self, naming_style): + always_pass_data = [ + ("__add__", "method"), + ("__set_name__", "method"), + ("__version__", "const"), + ("__author__", "const"), + ] + for name, name_type in always_pass_data: + self._test_is_correct(naming_style, name, name_type) + + def _test_is_correct(self, naming_style, name, name_type): + rgx = naming_style.get_regex(name_type) + self.assertTrue( + rgx.match(name), + "{!r} does not match pattern {!r} (style: {}, type: {})".format( + name, rgx, naming_style, name_type + ), + ) + + def _test_is_incorrect(self, naming_style, name, name_type): + rgx = naming_style.get_regex(name_type) + self.assertFalse( + rgx.match(name), + "{!r} match pattern {!r} but shouldn't (style: {}, type: {})".format( + name, rgx, naming_style, name_type + ), + ) + + def test_snake_case(self): + naming_style = base.SnakeCaseStyle + + for name in self.SNAKE_CASE_NAMES: + self._test_name_is_correct_for_all_name_types(naming_style, name) + for name in self.ALL_NAMES - self.SNAKE_CASE_NAMES: + self._test_name_is_incorrect_for_all_name_types(naming_style, name) + + self._test_should_always_pass(naming_style) + + def test_camel_case(self): + naming_style = base.CamelCaseStyle + + for name in self.CAMEL_CASE_NAMES: + self._test_name_is_correct_for_all_name_types(naming_style, name) + for name in self.ALL_NAMES - self.CAMEL_CASE_NAMES: + self._test_name_is_incorrect_for_all_name_types(naming_style, name) + + self._test_should_always_pass(naming_style) + + def test_upper_case(self): + naming_style = base.UpperCaseStyle + + for name in self.UPPER_CASE_NAMES: + self._test_name_is_correct_for_all_name_types(naming_style, name) + for name in self.ALL_NAMES - self.UPPER_CASE_NAMES: + self._test_name_is_incorrect_for_all_name_types(naming_style, name) + + self._test_should_always_pass(naming_style) + + def test_pascal_case(self): + naming_style = base.PascalCaseStyle + + for name in self.PASCAL_CASE_NAMES: + self._test_name_is_correct_for_all_name_types(naming_style, name) + for name in self.ALL_NAMES - self.PASCAL_CASE_NAMES: + self._test_name_is_incorrect_for_all_name_types(naming_style, name) + + self._test_should_always_pass(naming_style) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_classes.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_classes.py new file mode 100644 index 0000000..1bf929b --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_classes.py @@ -0,0 +1,114 @@ +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the variables checker.""" +import astroid +from pylint.checkers import classes +from pylint.testutils import CheckerTestCase, Message, set_config + + +class TestVariablesChecker(CheckerTestCase): + + CHECKER_CLASS = classes.ClassChecker + + def test_bitbucket_issue_164(self): + """Issue 164 report a false negative for access-member-before-definition""" + n1, n2 = astroid.extract_node( + """ + class MyClass1: + def __init__(self): + self.first += 5 #@ + self.first = 0 #@ + """ + ) + message = Message( + "access-member-before-definition", node=n1.target, args=("first", n2.lineno) + ) + with self.assertAddsMessages(message): + self.walk(n1.root()) + + @set_config(exclude_protected=("_meta", "_manager")) + def test_exclude_protected(self): + """Test that exclude-protected can be used to + exclude names from protected-access warning. + """ + + node = astroid.parse( + """ + class Protected: + '''empty''' + def __init__(self): + self._meta = 42 + self._manager = 24 + self._teta = 29 + OBJ = Protected() + OBJ._meta + OBJ._manager + OBJ._teta + """ + ) + with self.assertAddsMessages( + Message("protected-access", node=node.body[-1].value, args="_teta") + ): + self.walk(node.root()) + + def test_regression_non_parent_init_called_tracemalloc(self): + # This used to raise a non-parent-init-called on Pylint 1.3 + # See issue https://bitbucket.org/logilab/pylint/issue/308/ + # for reference. + node = astroid.extract_node( + """ + from tracemalloc import Sequence + class _Traces(Sequence): + def __init__(self, traces): #@ + Sequence.__init__(self) + """ + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_super_init_not_called_regression(self): + # This should not emit a super-init-not-called + # warning. It previously did this, because + # ``next(node.infer())`` was used in that checker's + # logic and the first inferred node was an Uninferable object, + # leading to this false positive. + node = astroid.extract_node( + """ + import ctypes + + class Foo(ctypes.BigEndianStructure): + def __init__(self): #@ + ctypes.BigEndianStructure.__init__(self) + """ + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_uninferable_attribute(self): + """Make sure protect-access doesn't raise + an exception Uninferable attributes""" + + node = astroid.extract_node( + """ + class MC(): + @property + def nargs(self): + return 1 if self._nargs else 2 + + class Application(metaclass=MC): + def __new__(cls): + nargs = obj._nargs #@ + """ + ) + with self.assertAddsMessages( + Message("protected-access", node=node.value, args="_nargs") + ): + self.checker.visit_attribute(node.value) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_exceptions.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_exceptions.py new file mode 100644 index 0000000..e1596af --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_exceptions.py @@ -0,0 +1,49 @@ +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Rene Zhang <rz99@cornell.edu> +# Copyright (c) 2015 Steven Myint <hg@stevenmyint.com> +# Copyright (c) 2015 Pavel Roskin <proski@gnu.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Brian Shaginaw <brian.shaginaw@warbyparker.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for pylint.checkers.exceptions.""" +import astroid + +from pylint.checkers import exceptions +from pylint.testutils import CheckerTestCase, Message + + +class TestExceptionsChecker(CheckerTestCase): + """Tests for pylint.checkers.exceptions.""" + + CHECKER_CLASS = exceptions.ExceptionsChecker + + # These tests aren't in the functional test suite, + # since they will be converted with 2to3 for Python 3 + # and `raise (Error, ...)` will be converted to + # `raise Error(...)`, so it beats the purpose of the test. + + def test_raising_bad_type_python3(self): + node = astroid.extract_node("raise (ZeroDivisionError, None) #@") + message = Message("raising-bad-type", node=node, args="tuple") + with self.assertAddsMessages(message): + self.checker.visit_raise(node) + + def test_bad_exception_context_function(self): + node = astroid.extract_node( + """ + def function(): + pass + + try: + pass + except function as exc: + raise Exception from exc #@ + """ + ) + message = Message("bad-exception-context", node=node) + with self.assertAddsMessages(message): + self.checker.visit_raise(node) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_format.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_format.py new file mode 100644 index 0000000..8811b08 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_format.py @@ -0,0 +1,525 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2009-2011, 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 buck <buck.2019@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Harut <yes@harutune.name> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Petr Pulc <petrpulc@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Krzysztof Czapla <k.czapla68@gmail.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 James M. Allen <james.m.allen@gmail.com> +# Copyright (c) 2017 vinnyrose <vinnyrose@users.noreply.github.com> +# Copyright (c) 2018 Bryce Guinta <bryce.guinta@protonmail.com> +# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Check format checker helper functions""" + +from __future__ import unicode_literals + +import tokenize +import os +import tempfile + +import astroid + +from pylint.checkers.format import * +from pylint import reporters +from pylint import lint + + +from pylint.testutils import CheckerTestCase, Message, set_config, _tokenize_str + + +class TestMultiStatementLine(CheckerTestCase): + CHECKER_CLASS = FormatChecker + + def testSingleLineIfStmts(self): + stmt = astroid.extract_node( + """ + if True: pass #@ + """ + ) + self.checker.config.single_line_if_stmt = False + with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): + self.visitFirst(stmt) + self.checker.config.single_line_if_stmt = True + with self.assertNoMessages(): + self.visitFirst(stmt) + stmt = astroid.extract_node( + """ + if True: pass #@ + else: + pass + """ + ) + with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): + self.visitFirst(stmt) + + def testSingleLineClassStmts(self): + stmt = astroid.extract_node( + """ + class MyError(Exception): pass #@ + """ + ) + self.checker.config.single_line_class_stmt = False + with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): + self.visitFirst(stmt) + self.checker.config.single_line_class_stmt = True + with self.assertNoMessages(): + self.visitFirst(stmt) + + stmt = astroid.extract_node( + """ + class MyError(Exception): a='a' #@ + """ + ) + self.checker.config.single_line_class_stmt = False + with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): + self.visitFirst(stmt) + self.checker.config.single_line_class_stmt = True + with self.assertNoMessages(): + self.visitFirst(stmt) + + stmt = astroid.extract_node( + """ + class MyError(Exception): a='a'; b='b' #@ + """ + ) + self.checker.config.single_line_class_stmt = False + with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): + self.visitFirst(stmt) + self.checker.config.single_line_class_stmt = True + with self.assertAddsMessages(Message("multiple-statements", node=stmt.body[0])): + self.visitFirst(stmt) + + def testTryExceptFinallyNoMultipleStatement(self): + tree = astroid.extract_node( + """ + try: #@ + pass + except: + pass + finally: + pass""" + ) + with self.assertNoMessages(): + self.visitFirst(tree) + + def visitFirst(self, tree): + self.checker.process_tokens([]) + self.checker.visit_default(tree.body[0]) + + +class TestSuperfluousParentheses(CheckerTestCase): + CHECKER_CLASS = FormatChecker + + def testCheckKeywordParensHandlesValidCases(self): + self.checker._keywords_with_parens = set() + cases = [ + "if foo:", + "if foo():", + "if (x and y) or z:", + "assert foo()", + "assert ()", + "if (1, 2) in (3, 4):", + "if (a or b) in c:", + "return (x for x in x)", + "if (x for x in x):", + "for x in (x for x in x):", + "not (foo or bar)", + "not (foo or bar) and baz", + ] + with self.assertNoMessages(): + for code in cases: + self.checker._check_keyword_parentheses(_tokenize_str(code), 0) + + def testCheckKeywordParensHandlesUnnecessaryParens(self): + self.checker._keywords_with_parens = set() + cases = [ + (Message("superfluous-parens", line=1, args="if"), "if (foo):", 0), + (Message("superfluous-parens", line=1, args="if"), "if ((foo, bar)):", 0), + (Message("superfluous-parens", line=1, args="if"), "if (foo(bar)):", 0), + ( + Message("superfluous-parens", line=1, args="return"), + "return ((x for x in x))", + 0, + ), + (Message("superfluous-parens", line=1, args="not"), "not (foo)", 0), + (Message("superfluous-parens", line=1, args="not"), "if not (foo):", 1), + (Message("superfluous-parens", line=1, args="if"), "if (not (foo)):", 0), + (Message("superfluous-parens", line=1, args="not"), "if (not (foo)):", 2), + ( + Message("superfluous-parens", line=1, args="for"), + "for (x) in (1, 2, 3):", + 0, + ), + ( + Message("superfluous-parens", line=1, args="if"), + "if (1) in (1, 2, 3):", + 0, + ), + ] + for msg, code, offset in cases: + with self.assertAddsMessages(msg): + self.checker._check_keyword_parentheses(_tokenize_str(code), offset) + + def testCheckIfArgsAreNotUnicode(self): + self.checker._keywords_with_parens = set() + cases = [("if (foo):", 0), ("assert (1 == 1)", 0)] + + for code, offset in cases: + self.checker._check_keyword_parentheses(_tokenize_str(code), offset) + got = self.linter.release_messages() + assert isinstance(got[-1].args, str) + + def testFuturePrintStatementWithoutParensWarning(self): + code = """from __future__ import print_function +print('Hello world!') +""" + tree = astroid.parse(code) + with self.assertNoMessages(): + self.checker.process_module(tree) + self.checker.process_tokens(_tokenize_str(code)) + + def testKeywordParensFalsePositive(self): + self.checker._keywords_with_parens = set() + code = "if 'bar' in (DICT or {}):" + with self.assertNoMessages(): + self.checker._check_keyword_parentheses(_tokenize_str(code), start=2) + + +class TestCheckSpace(CheckerTestCase): + CHECKER_CLASS = FormatChecker + + def testParenthesesGood(self): + good_cases = ["(a)\n", "(a * (b + c))\n", "(#\n a)\n"] + with self.assertNoMessages(): + for code in good_cases: + self.checker.process_tokens(_tokenize_str(code)) + + def testParenthesesBad(self): + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("No", "allowed", "after", "bracket", "( a)\n^"), + ) + ): + self.checker.process_tokens(_tokenize_str("( a)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("No", "allowed", "before", "bracket", "(a )\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("(a )\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("No", "allowed", "before", "bracket", "foo (a)\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("foo (a)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("No", "allowed", "before", "bracket", "{1: 2} [1]\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("{1: 2} [1]\n")) + + def testTrailingCommaGood(self): + with self.assertNoMessages(): + self.checker.process_tokens(_tokenize_str("(a, )\n")) + self.checker.process_tokens(_tokenize_str("(a,)\n")) + + self.checker.config.no_space_check = [] + with self.assertNoMessages(): + self.checker.process_tokens(_tokenize_str("(a,)\n")) + + @set_config(no_space_check=[]) + def testTrailingCommaBad(self): + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("No", "allowed", "before", "bracket", "(a, )\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("(a, )\n")) + + def testComma(self): + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("No", "allowed", "before", "comma", "(a , b)\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("(a , b)\n")) + + def testSpacesAllowedInsideSlices(self): + good_cases = ["[a:b]\n", "[a : b]\n", "[a : ]\n", "[:a]\n", "[:]\n", "[::]\n"] + with self.assertNoMessages(): + for code in good_cases: + self.checker.process_tokens(_tokenize_str(code)) + + def testKeywordSpacingGood(self): + with self.assertNoMessages(): + self.checker.process_tokens(_tokenize_str("foo(foo=bar)\n")) + self.checker.process_tokens(_tokenize_str("foo(foo: int = bar)\n")) + self.checker.process_tokens( + _tokenize_str("foo(foo: module.classname = bar)\n") + ) + self.checker.process_tokens( + _tokenize_str("foo(foo: Dict[int, str] = bar)\n") + ) + self.checker.process_tokens(_tokenize_str("foo(foo: 'int' = bar)\n")) + self.checker.process_tokens( + _tokenize_str("foo(foo: Dict[int, 'str'] = bar)\n") + ) + self.checker.process_tokens(_tokenize_str("lambda x=1: x\n")) + + def testKeywordSpacingBad(self): + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=( + "No", + "allowed", + "before", + "keyword argument assignment", + "(foo =bar)\n ^", + ), + ) + ): + self.checker.process_tokens(_tokenize_str("(foo =bar)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=( + "No", + "allowed", + "after", + "keyword argument assignment", + "(foo= bar)\n ^", + ), + ) + ): + self.checker.process_tokens(_tokenize_str("(foo= bar)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=( + "No", + "allowed", + "around", + "keyword argument assignment", + "(foo = bar)\n ^", + ), + ) + ): + self.checker.process_tokens(_tokenize_str("(foo = bar)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=( + "Exactly one", + "required", + "before", + "keyword argument assignment", + "(foo: int= bar)\n ^", + ), + ) + ): + self.checker.process_tokens(_tokenize_str("(foo: int= bar)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=( + "Exactly one", + "required", + "after", + "keyword argument assignment", + "(foo: int =bar)\n ^", + ), + ) + ): + self.checker.process_tokens(_tokenize_str("(foo: int =bar)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=( + "Exactly one", + "required", + "around", + "keyword argument assignment", + "(foo: int=bar)\n ^", + ), + ) + ): + self.checker.process_tokens(_tokenize_str("(foo: int=bar)\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=( + "Exactly one", + "required", + "around", + "keyword argument assignment", + "(foo: List[int]=bar)\n ^", + ), + ) + ): + self.checker.process_tokens(_tokenize_str("(foo: List[int]=bar)\n")) + # Regression test for #1831 + with self.assertNoMessages(): + self.checker.process_tokens( + _tokenize_str("(arg: Tuple[\n int, str] = None):\n") + ) + + def testOperatorSpacingGood(self): + good_cases = ["a = b\n" "a < b\n" "a\n< b\n"] + with self.assertNoMessages(): + for code in good_cases: + self.checker.process_tokens(_tokenize_str(code)) + + def testOperatorSpacingBad(self): + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("Exactly one", "required", "before", "comparison", "a< b\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("a< b\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("Exactly one", "required", "after", "comparison", "a <b\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("a <b\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("Exactly one", "required", "around", "comparison", "a<b\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("a<b\n")) + + with self.assertAddsMessages( + Message( + "bad-whitespace", + line=1, + args=("Exactly one", "required", "around", "comparison", "a< b\n ^"), + ) + ): + self.checker.process_tokens(_tokenize_str("a< b\n")) + + def testValidTypingAnnotationEllipses(self): + """Make sure ellipses in function typing annotation + doesn't cause a false positive bad-whitespace message""" + with self.assertNoMessages(): + self.checker.process_tokens( + _tokenize_str("def foo(t: Tuple[str, ...] = None):\n") + ) + + def testEmptyLines(self): + self.checker.config.no_space_check = [] + with self.assertAddsMessages(Message("trailing-whitespace", line=2)): + self.checker.process_tokens(_tokenize_str("a = 1\n \nb = 2\n")) + + with self.assertAddsMessages(Message("trailing-whitespace", line=2)): + self.checker.process_tokens(_tokenize_str("a = 1\n\t\nb = 2\n")) + + with self.assertAddsMessages(Message("trailing-whitespace", line=2)): + self.checker.process_tokens(_tokenize_str("a = 1\n\v\nb = 2\n")) + + with self.assertNoMessages(): + self.checker.process_tokens(_tokenize_str("a = 1\n\f\nb = 2\n")) + + self.checker.config.no_space_check = ["empty-line"] + with self.assertNoMessages(): + self.checker.process_tokens(_tokenize_str("a = 1\n \nb = 2\n")) + + with self.assertNoMessages(): + self.checker.process_tokens(_tokenize_str("a = 1\n\t\nb = 2\n")) + + with self.assertNoMessages(): + self.checker.process_tokens(_tokenize_str("a = 1\n\v\nb = 2\n")) + + def test_encoding_token(self): + """Make sure the encoding token doesn't change the checker's behavior + + _tokenize_str doesn't produce an encoding token, but + reading a file does + """ + with self.assertNoMessages(): + encoding_token = tokenize.TokenInfo( + tokenize.ENCODING, "utf-8", (0, 0), (0, 0), "" + ) + tokens = [encoding_token] + _tokenize_str( + "if (\n None):\n pass\n" + ) + self.checker.process_tokens(tokens) + + +def test_disable_global_option_end_of_line(): + """ + Test for issue with disabling tokenizer messages + that extend beyond the scope of the ast tokens + """ + file_ = tempfile.NamedTemporaryFile("w", delete=False) + with file_: + file_.write( + """ +mylist = [ + None + ] + """ + ) + try: + linter = lint.PyLinter() + checker = FormatChecker(linter) + linter.register_checker(checker) + args = linter.load_command_line_configuration( + [file_.name, "-d", "bad-continuation"] + ) + myreporter = reporters.CollectingReporter() + linter.set_reporter(myreporter) + linter.check(args) + assert not myreporter.messages + finally: + os.remove(file_.name) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_imports.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_imports.py new file mode 100644 index 0000000..b5961b2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_imports.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Cezar <celnazli@bitdefender.com> +# Copyright (c) 2015 James Morgensen <james.morgensen@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Marianna Polatoglou <mpolatoglou@bloomberg.net> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the imports checker.""" +import os + +import astroid +from pylint.checkers import imports +from pylint.testutils import CheckerTestCase, Message, set_config +from pylint.interfaces import UNDEFINED + +REGR_DATA = os.path.join(os.path.dirname(__file__), "regrtest_data", "") + + +class TestImportsChecker(CheckerTestCase): + + CHECKER_CLASS = imports.ImportsChecker + + @set_config( + ignored_modules=("external_module", "fake_module.submodule", "foo", "bar") + ) + def test_import_error_skipped(self): + """Make sure that imports do not emit an 'import-error' when the + module is configured to be ignored.""" + + node = astroid.extract_node( + """ + from external_module import anything + """ + ) + with self.assertNoMessages(): + self.checker.visit_importfrom(node) + + node = astroid.extract_node( + """ + from external_module.another_module import anything + """ + ) + with self.assertNoMessages(): + self.checker.visit_importfrom(node) + + node = astroid.extract_node( + """ + import external_module + """ + ) + with self.assertNoMessages(): + self.checker.visit_import(node) + + node = astroid.extract_node( + """ + from fake_module.submodule import anything + """ + ) + with self.assertNoMessages(): + self.checker.visit_importfrom(node) + + node = astroid.extract_node( + """ + from fake_module.submodule.deeper import anything + """ + ) + with self.assertNoMessages(): + self.checker.visit_importfrom(node) + + node = astroid.extract_node( + """ + import foo, bar + """ + ) + msg = Message("multiple-imports", node=node, args="foo, bar") + with self.assertAddsMessages(msg): + self.checker.visit_import(node) + + node = astroid.extract_node( + """ + import foo + import bar + """ + ) + with self.assertNoMessages(): + self.checker.visit_import(node) + + def test_reimported_same_line(self): + """ + Test that duplicate imports on single line raise 'reimported'. + """ + node = astroid.extract_node("from time import sleep, sleep, time") + msg = Message(msg_id="reimported", node=node, args=("sleep", 1)) + with self.assertAddsMessages(msg): + self.checker.visit_importfrom(node) + + def test_relative_beyond_top_level(self): + module = astroid.MANAGER.ast_from_module_name("beyond_top", REGR_DATA) + import_from = module.body[0] + + msg = Message(msg_id="relative-beyond-top-level", node=import_from) + with self.assertAddsMessages(msg): + self.checker.visit_importfrom(import_from) + with self.assertNoMessages(): + self.checker.visit_importfrom(module.body[1]) + with self.assertNoMessages(): + self.checker.visit_importfrom(module.body[2].body[0]) + + def test_wildcard_import_init(self): + module = astroid.MANAGER.ast_from_module_name("init_wildcard", REGR_DATA) + import_from = module.body[0] + + with self.assertNoMessages(): + self.checker.visit_importfrom(import_from) + + def test_wildcard_import_non_init(self): + module = astroid.MANAGER.ast_from_module_name("wildcard", REGR_DATA) + import_from = module.body[0] + + msg = Message( + msg_id="wildcard-import", + node=import_from, + args="empty", + confidence=UNDEFINED, + ) + with self.assertAddsMessages(msg): + self.checker.visit_importfrom(import_from) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_logging.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_logging.py new file mode 100644 index 0000000..a1c111c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_logging.py @@ -0,0 +1,77 @@ +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unittest for the logging checker.""" +import astroid + +from pylint.checkers import logging +from pylint.testutils import CheckerTestCase, Message, set_config + + +class TestLoggingModuleDetection(CheckerTestCase): + CHECKER_CLASS = logging.LoggingChecker + + def test_detects_standard_logging_module(self): + stmts = astroid.extract_node( + """ + import logging #@ + logging.warn('%s' % '%s') #@ + """ + ) + self.checker.visit_module(None) + self.checker.visit_import(stmts[0]) + with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1])): + self.checker.visit_call(stmts[1]) + + def test_dont_crash_on_invalid_format_string(self): + node = astroid.parse( + """ + import logging + logging.error('0} - {1}'.format(1, 2)) + """ + ) + self.walk(node) + + def test_detects_renamed_standard_logging_module(self): + stmts = astroid.extract_node( + """ + import logging as blogging #@ + blogging.warn('%s' % '%s') #@ + """ + ) + self.checker.visit_module(None) + self.checker.visit_import(stmts[0]) + with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1])): + self.checker.visit_call(stmts[1]) + + @set_config(logging_modules=["logging", "my.logging"]) + def test_nonstandard_logging_module(self): + stmts = astroid.extract_node( + """ + from my import logging as blogging #@ + blogging.warn('%s' % '%s') #@ + """ + ) + self.checker.visit_module(None) + self.checker.visit_import(stmts[0]) + with self.assertAddsMessages(Message("logging-not-lazy", node=stmts[1])): + self.checker.visit_call(stmts[1]) + + @set_config(logging_format_style="new") + def test_brace_format_style(self): + stmts = astroid.extract_node( + """ + import logging #@ + logging.error('{}', 1) #@ + """ + ) + self.checker.visit_module(None) + self.checker.visit_import(stmts[0]) + with self.assertNoMessages(): + self.checker.visit_call(stmts[1]) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_misc.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_misc.py new file mode 100644 index 0000000..5143698 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_misc.py @@ -0,0 +1,97 @@ +# Copyright (c) 2013-2014, 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 glegoux <gilles.legoux@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the misc checker.""" + +from pylint.checkers import misc +from pylint.testutils import ( + CheckerTestCase, + Message, + set_config, + _create_file_backed_module, +) + + +class TestFixme(CheckerTestCase): + CHECKER_CLASS = misc.EncodingChecker + + def test_fixme_with_message(self): + with _create_file_backed_module( + """a = 1 + # FIXME message + """ + ) as module: + with self.assertAddsMessages( + Message(msg_id="fixme", line=2, args="FIXME message") + ): + self.checker.process_module(module) + + def test_todo_without_message(self): + with _create_file_backed_module( + """a = 1 + # TODO + """ + ) as module: + with self.assertAddsMessages(Message(msg_id="fixme", line=2, args="TODO")): + self.checker.process_module(module) + + def test_xxx_without_space(self): + with _create_file_backed_module( + """a = 1 + #XXX + """ + ) as module: + with self.assertAddsMessages(Message(msg_id="fixme", line=2, args="XXX")): + self.checker.process_module(module) + + def test_xxx_middle(self): + with _create_file_backed_module( + """a = 1 + # midle XXX + """ + ) as module: + with self.assertNoMessages(): + self.checker.process_module(module) + + def test_without_space_fixme(self): + with _create_file_backed_module( + """a = 1 + #FIXME + """ + ) as module: + with self.assertAddsMessages(Message(msg_id="fixme", line=2, args="FIXME")): + self.checker.process_module(module) + + @set_config(notes=[]) + def test_absent_codetag(self): + with _create_file_backed_module( + """a = 1 + # FIXME + # TODO + # XXX + """ + ) as module: + with self.assertNoMessages(): + self.checker.process_module(module) + + @set_config(notes=["CODETAG"]) + def test_other_present_codetag(self): + with _create_file_backed_module( + """a = 1 + # CODETAG + # FIXME + """ + ) as module: + with self.assertAddsMessages( + Message(msg_id="fixme", line=2, args="CODETAG") + ): + self.checker.process_module(module) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_python3.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_python3.py new file mode 100644 index 0000000..9969354 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_python3.py @@ -0,0 +1,1207 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014-2015 Brett Cannon <brett@python.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2015 Cosmin Poieana <cmin@ropython.org> +# Copyright (c) 2015 Viorel Stirbu <viorels@gmail.com> +# Copyright (c) 2016-2017 Roy Williams <roy.williams.iii@gmail.com> +# Copyright (c) 2016 Roy Williams <rwilliams@lyft.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Daniel Miller <millerdev@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the python3 checkers.""" +from __future__ import absolute_import + +import sys +import textwrap + +import pytest + +import astroid + +from pylint import testutils +from pylint.checkers import python3 as checker +from pylint.interfaces import INFERENCE_FAILURE, INFERENCE + + +# Decorator for any tests that will fail under Python 3 +python2_only = pytest.mark.skipif(sys.version_info[0] > 2, reason="Python 2 only") + +# TODO(cpopa): Port these to the functional test framework instead. + + +class TestPython3Checker(testutils.CheckerTestCase): + + CHECKER_CLASS = checker.Python3Checker + + def check_bad_builtin(self, builtin_name): + node = astroid.extract_node(builtin_name + " #@") + message = builtin_name.lower() + "-builtin" + with self.assertAddsMessages(testutils.Message(message, node=node)): + self.checker.visit_name(node) + + @python2_only + def test_bad_builtins(self): + builtins = [ + "apply", + "buffer", + "cmp", + "coerce", + "execfile", + "file", + "input", + "intern", + "long", + "raw_input", + "round", + "reduce", + "StandardError", + "unichr", + "unicode", + "xrange", + "reload", + ] + for builtin in builtins: + self.check_bad_builtin(builtin) + + def as_iterable_in_for_loop_test(self, fxn): + code = "for x in {}(): pass".format(fxn) + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def as_used_by_iterable_in_for_loop_test(self, fxn): + checker = "{}-builtin-not-iterating".format(fxn) + node = astroid.extract_node( + """ + for x in (whatever( + {}() #@ + )): + pass + """.format( + fxn + ) + ) + message = testutils.Message(checker, node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def as_iterable_in_genexp_test(self, fxn): + code = "x = (x for x in {}())".format(fxn) + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def as_iterable_in_listcomp_test(self, fxn): + code = "x = [x for x in {}(None, [1])]".format(fxn) + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def as_used_in_variant_in_genexp_test(self, fxn): + checker = "{}-builtin-not-iterating".format(fxn) + node = astroid.extract_node( + """ + list( + __({}(x)) + for x in [1] + ) + """.format( + fxn + ) + ) + message = testutils.Message(checker, node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def as_used_in_variant_in_listcomp_test(self, fxn): + checker = "{}-builtin-not-iterating".format(fxn) + node = astroid.extract_node( + """ + [ + __({}(None, x)) + for x in [[1]]] + """.format( + fxn + ) + ) + message = testutils.Message(checker, node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def as_argument_to_callable_constructor_test(self, fxn, callable_fn): + module = astroid.parse("x = {}({}())".format(callable_fn, fxn)) + with self.assertNoMessages(): + self.walk(module) + + def as_argument_to_materialized_filter(self, callable_fn): + module = astroid.parse("list(filter(None, {}()))".format(callable_fn)) + with self.assertNoMessages(): + self.walk(module) + + def as_argument_to_random_fxn_test(self, fxn): + checker = "{}-builtin-not-iterating".format(fxn) + node = astroid.extract_node( + """ + y( + {}() #@ + ) + """.format( + fxn + ) + ) + message = testutils.Message(checker, node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def as_argument_to_str_join_test(self, fxn): + code = "x = ''.join({}())".format(fxn) + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def as_iterable_in_unpacking(self, fxn): + node = astroid.extract_node( + """ + a, b = __({}()) + """.format( + fxn + ) + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def as_assignment(self, fxn): + checker = "{}-builtin-not-iterating".format(fxn) + node = astroid.extract_node( + """ + a = __({}()) + """.format( + fxn + ) + ) + message = testutils.Message(checker, node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def iterating_context_tests(self, fxn): + """Helper for verifying a function isn't used as an iterator.""" + self.as_iterable_in_for_loop_test(fxn) + self.as_used_by_iterable_in_for_loop_test(fxn) + self.as_iterable_in_genexp_test(fxn) + self.as_iterable_in_listcomp_test(fxn) + self.as_used_in_variant_in_genexp_test(fxn) + self.as_used_in_variant_in_listcomp_test(fxn) + self.as_argument_to_random_fxn_test(fxn) + self.as_argument_to_str_join_test(fxn) + self.as_iterable_in_unpacking(fxn) + self.as_assignment(fxn) + self.as_argument_to_materialized_filter(fxn) + + for func in ( + "iter", + "list", + "tuple", + "sorted", + "set", + "sum", + "any", + "all", + "enumerate", + "dict", + ): + self.as_argument_to_callable_constructor_test(fxn, func) + + def test_dict_subclasses_methods_in_iterating_context(self): + iterating, not_iterating = astroid.extract_node( + """ + from __future__ import absolute_import + from collections import defaultdict + d = defaultdict(list) + a, b = d.keys() #@ + x = d.keys() #@ + """ + ) + + with self.assertNoMessages(): + self.checker.visit_call(iterating.value) + + message = testutils.Message("dict-keys-not-iterating", node=not_iterating.value) + with self.assertAddsMessages(message): + self.checker.visit_call(not_iterating.value) + + def test_dict_methods_in_iterating_context(self): + iterating_code = [ + "for x in {}(): pass", + "(x for x in {}())", + "[x for x in {}()]", + "iter({}())", + "a, b = {}()", + "max({}())", + "min({}())", + "3 in {}()", + "set().update({}())", + "[].extend({}())", + "{{}}.update({}())", + """ + from __future__ import absolute_import + from itertools import chain + chain.from_iterable({}()) + """, + ] + non_iterating_code = ["x = __({}())", "__({}())[0]"] + + for method in ("keys", "items", "values"): + dict_method = "{{}}.{}".format(method) + + for code in iterating_code: + with_value = code.format(dict_method) + module = astroid.parse(with_value) + with self.assertNoMessages(): + self.walk(module) + + for code in non_iterating_code: + with_value = code.format(dict_method) + node = astroid.extract_node(with_value) + + checker = "dict-{}-not-iterating".format(method) + message = testutils.Message(checker, node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_map_in_iterating_context(self): + self.iterating_context_tests("map") + + def test_zip_in_iterating_context(self): + self.iterating_context_tests("zip") + + def test_range_in_iterating_context(self): + self.iterating_context_tests("range") + + def test_filter_in_iterating_context(self): + self.iterating_context_tests("filter") + + def defined_method_test(self, method, warning): + """Helper for verifying that a certain method is not defined.""" + node = astroid.extract_node( + """ + class Foo(object): + def __{}__(self, other): #@ + pass""".format( + method + ) + ) + message = testutils.Message(warning, node=node) + with self.assertAddsMessages(message): + self.checker.visit_functiondef(node) + + def test_delslice_method(self): + self.defined_method_test("delslice", "delslice-method") + + def test_getslice_method(self): + self.defined_method_test("getslice", "getslice-method") + + def test_setslice_method(self): + self.defined_method_test("setslice", "setslice-method") + + def test_coerce_method(self): + self.defined_method_test("coerce", "coerce-method") + + def test_oct_method(self): + self.defined_method_test("oct", "oct-method") + + def test_hex_method(self): + self.defined_method_test("hex", "hex-method") + + def test_nonzero_method(self): + self.defined_method_test("nonzero", "nonzero-method") + + def test_cmp_method(self): + self.defined_method_test("cmp", "cmp-method") + + def test_div_method(self): + self.defined_method_test("div", "div-method") + + def test_idiv_method(self): + self.defined_method_test("idiv", "idiv-method") + + def test_rdiv_method(self): + self.defined_method_test("rdiv", "rdiv-method") + + def test_eq_and_hash_method(self): + """Helper for verifying that a certain method is not defined.""" + node = astroid.extract_node( + """ + class Foo(object): #@ + def __eq__(self, other): + pass + def __hash__(self): + pass""" + ) + with self.assertNoMessages(): + self.checker.visit_classdef(node) + + def test_eq_and_hash_is_none(self): + """Helper for verifying that a certain method is not defined.""" + node = astroid.extract_node( + """ + class Foo(object): #@ + def __eq__(self, other): + pass + __hash__ = None""" + ) + with self.assertNoMessages(): + self.checker.visit_classdef(node) + + def test_eq_without_hash_method(self): + """Helper for verifying that a certain method is not defined.""" + node = astroid.extract_node( + """ + class Foo(object): #@ + def __eq__(self, other): + pass""" + ) + message = testutils.Message("eq-without-hash", node=node) + with self.assertAddsMessages(message): + self.checker.visit_classdef(node) + + @python2_only + def test_print_statement(self): + node = astroid.extract_node('print "Hello, World!" #@') + message = testutils.Message("print-statement", node=node) + with self.assertAddsMessages(message): + self.checker.visit_print(node) + + @python2_only + def test_backtick(self): + node = astroid.extract_node("`test`") + message = testutils.Message("backtick", node=node) + with self.assertAddsMessages(message): + self.checker.visit_repr(node) + + def test_relative_import(self): + node = astroid.extract_node("import string #@") + message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(message): + self.checker.visit_import(node) + with self.assertNoMessages(): + # message should only be added once + self.checker.visit_import(node) + + def test_relative_from_import(self): + node = astroid.extract_node("from os import path #@") + message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(message): + self.checker.visit_importfrom(node) + with self.assertNoMessages(): + # message should only be added once + self.checker.visit_importfrom(node) + + def test_absolute_import(self): + module_import = astroid.parse( + "from __future__ import absolute_import; import os" + ) + module_from = astroid.parse( + "from __future__ import absolute_import; from os import path" + ) + with self.assertNoMessages(): + for module in (module_import, module_from): + self.walk(module) + + def test_import_star_module_level(self): + node = astroid.extract_node( + """ + def test(): + from lala import * #@ + """ + ) + absolute = testutils.Message("no-absolute-import", node=node) + star = testutils.Message("import-star-module-level", node=node) + with self.assertAddsMessages(absolute, star): + self.checker.visit_importfrom(node) + + def test_division(self): + node = astroid.extract_node("3 / 2 #@") + message = testutils.Message("old-division", node=node) + with self.assertAddsMessages(message): + self.checker.visit_binop(node) + + def test_division_with_future_statement(self): + module = astroid.parse("from __future__ import division; 3 / 2") + with self.assertNoMessages(): + self.walk(module) + + def test_floor_division(self): + node = astroid.extract_node(" 3 // 2 #@") + with self.assertNoMessages(): + self.checker.visit_binop(node) + + def test_division_by_float(self): + left_node = astroid.extract_node("3.0 / 2 #@") + right_node = astroid.extract_node(" 3 / 2.0 #@") + with self.assertNoMessages(): + for node in (left_node, right_node): + self.checker.visit_binop(node) + + def test_dict_iter_method(self): + for meth in ("keys", "values", "items"): + node = astroid.extract_node("x.iter%s() #@" % meth) + message = testutils.Message("dict-iter-method", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_dict_iter_method_on_dict(self): + nodes = astroid.extract_node( + """ + from collections import defaultdict + {}.iterkeys() #@ + defaultdict(list).iterkeys() #@ + class Someclass(dict): + pass + Someclass().iterkeys() #@ + + # Emits even though we are not sure they are dicts + x.iterkeys() #@ + + def func(x): + x.iterkeys() #@ + """ + ) + for node in nodes: + message = testutils.Message("dict-iter-method", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_dict_not_iter_method(self): + arg_node = astroid.extract_node("x.iterkeys(x) #@") + stararg_node = astroid.extract_node("x.iterkeys(*x) #@") + kwarg_node = astroid.extract_node("x.iterkeys(y=x) #@") + with self.assertNoMessages(): + for node in (arg_node, stararg_node, kwarg_node): + self.checker.visit_call(node) + + def test_dict_view_method(self): + for meth in ("keys", "values", "items"): + node = astroid.extract_node("x.view%s() #@" % meth) + message = testutils.Message("dict-view-method", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_dict_viewkeys(self): + nodes = astroid.extract_node( + """ + from collections import defaultdict + {}.viewkeys() #@ + defaultdict(list).viewkeys() #@ + class Someclass(dict): + pass + Someclass().viewkeys() #@ + + # Emits even though they might not be dicts + x.viewkeys() #@ + + def func(x): + x.viewkeys() #@ + """ + ) + for node in nodes: + message = testutils.Message("dict-view-method", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_next_method(self): + node = astroid.extract_node("x.next() #@") + message = testutils.Message("next-method-called", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_not_next_method(self): + arg_node = astroid.extract_node("x.next(x) #@") + stararg_node = astroid.extract_node("x.next(*x) #@") + kwarg_node = astroid.extract_node("x.next(y=x) #@") + with self.assertNoMessages(): + for node in (arg_node, stararg_node, kwarg_node): + self.checker.visit_call(node) + + def test_metaclass_assignment(self): + node = astroid.extract_node( + """ + class Foo(object): #@ + __metaclass__ = type""" + ) + message = testutils.Message("metaclass-assignment", node=node) + with self.assertAddsMessages(message): + self.checker.visit_classdef(node) + + def test_metaclass_global_assignment(self): + module = astroid.parse("__metaclass__ = type") + with self.assertNoMessages(): + self.walk(module) + + @python2_only + def test_parameter_unpacking(self): + node = astroid.extract_node("def func((a, b)):#@\n pass") + arg = node.args.args[0] + with self.assertAddsMessages( + testutils.Message("parameter-unpacking", node=arg) + ): + self.checker.visit_arguments(node.args) + + @python2_only + def test_old_raise_syntax(self): + node = astroid.extract_node('raise Exception, "test"') + message = testutils.Message("old-raise-syntax", node=node) + with self.assertAddsMessages(message): + self.checker.visit_raise(node) + + def test_xreadlines_attribute(self): + node = astroid.extract_node( + """ + f.xreadlines #@ + """ + ) + message = testutils.Message("xreadlines-attribute", node=node) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + def test_exception_message_attribute(self): + node = astroid.extract_node( + """ + try: + raise Exception("test") + except Exception as e: + e.message #@ + """ + ) + message = testutils.Message("exception-message-attribute", node=node) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + def test_normal_message_attribute(self): + node = astroid.extract_node( + """ + e.message #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_attribute(node) + + def test_invalid_codec(self): + node = astroid.extract_node('foobar.encode("hex") #@') + message = testutils.Message("invalid-str-codec", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_valid_codec(self): + node = astroid.extract_node('foobar.encode("ascii", "ignore") #@') + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_visit_call_with_kwarg(self): + node = astroid.extract_node('foobar.raz(encoding="hex") #@') + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_invalid_open_codec(self): + node = astroid.extract_node('open(foobar, encoding="hex") #@') + message = testutils.Message("invalid-str-codec", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_valid_open_codec(self): + node = astroid.extract_node('open(foobar, encoding="palmos") #@') + with self.assertNoMessages(): + self.checker.visit_call(node) + + @python2_only + def test_raising_string(self): + node = astroid.extract_node('raise "Test"') + message = testutils.Message("raising-string", node=node) + with self.assertAddsMessages(message): + self.checker.visit_raise(node) + + @python2_only + def test_checker_disabled_by_default(self): + node = astroid.parse( + textwrap.dedent( + """ + abc = 1l + raise Exception, "test" + raise "test" + `abc` + """ + ) + ) + with self.assertNoMessages(): + self.walk(node) + + def test_using_cmp_argument(self): + nodes = astroid.extract_node( + """ + [].sort(cmp=lambda x: x) #@ + a = list(range(x)) + a.sort(cmp=lambda x: x) #@ + + sorted([], cmp=lambda x: x) #@ + """ + ) + for node in nodes: + message = testutils.Message("using-cmp-argument", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_sys_maxint(self): + node = astroid.extract_node( + """ + import sys + sys.maxint #@ + """ + ) + message = testutils.Message("sys-max-int", node=node) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + def test_itertools_izip(self): + node = astroid.extract_node( + """ + from itertools import izip #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + message = testutils.Message("deprecated-itertools-function", node=node) + with self.assertAddsMessages(absolute_import_message, message): + self.checker.visit_importfrom(node) + + def test_deprecated_types_fields(self): + node = astroid.extract_node( + """ + from types import StringType #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + message = testutils.Message("deprecated-types-field", node=node) + with self.assertAddsMessages(absolute_import_message, message): + self.checker.visit_importfrom(node) + + def test_sys_maxint_imort_from(self): + node = astroid.extract_node( + """ + from sys import maxint #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + message = testutils.Message("sys-max-int", node=node) + with self.assertAddsMessages(absolute_import_message, message): + self.checker.visit_importfrom(node) + + def test_object_maxint(self): + node = astroid.extract_node( + """ + sys = object() + sys.maxint #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_attribute(node) + + def test_bad_import(self): + node = astroid.extract_node( + """ + import urllib2, sys #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + message = testutils.Message("bad-python3-import", node=node) + with self.assertAddsMessages(absolute_import_message, message): + self.checker.visit_import(node) + + def test_bad_import_turtle(self): + node = astroid.extract_node( + """ + import turtle #@ + turtle.Turtle() + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(absolute_import_message): + self.checker.visit_import(node) + + def test_bad_import_dbm(self): + node = astroid.extract_node( + """ + from dbm import open as open_ #@ + open_("dummy.db") + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(absolute_import_message): + self.checker.visit_importfrom(node) + + @python2_only + def test_bad_import_not_on_relative(self): + samples = ["from .commands import titi", "from . import commands"] + for code in samples: + node = astroid.extract_node(code) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(absolute_import_message): + self.checker.visit_importfrom(node) + self.checker._future_absolute_import = False + + def test_bad_import_conditional(self): + node = astroid.extract_node( + """ + import six + if six.PY2: + import urllib2 #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(absolute_import_message): + self.checker.visit_import(node) + + def test_bad_import_try_except_handler(self): + node = astroid.extract_node( + """ + try: + from hashlib import sha + except: + import sha #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(absolute_import_message): + self.checker.visit_import(node) + + def test_bad_import_try(self): + node = astroid.extract_node( + """ + try: + import md5 #@ + except: + from hashlib import md5 + finally: + pass + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(absolute_import_message): + self.checker.visit_import(node) + + def test_bad_import_try_finally(self): + node = astroid.extract_node( + """ + try: + import Queue #@ + finally: + import queue + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + message = testutils.Message("bad-python3-import", node=node) + with self.assertAddsMessages(absolute_import_message, message): + self.checker.visit_import(node) + + def test_bad_import_from(self): + node = astroid.extract_node( + """ + from cStringIO import StringIO #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + message = testutils.Message("bad-python3-import", node=node) + with self.assertAddsMessages(absolute_import_message, message): + self.checker.visit_importfrom(node) + + def test_bad_string_attribute(self): + node = astroid.extract_node( + """ + import string + string.maketrans #@ + """ + ) + message = testutils.Message("deprecated-string-function", node=node) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + def test_bad_operator_attribute(self): + node = astroid.extract_node( + """ + import operator + operator.div #@ + """ + ) + message = testutils.Message("deprecated-operator-function", node=node) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + def test_comprehension_escape(self): + assign, escaped_node = astroid.extract_node( + """ + a = [i for i in range(10)] #@ + i #@ + """ + ) + good_module = astroid.parse( + """ + {c for c in range(10)} #@ + {j:j for j in range(10)} #@ + [image_child] = [x for x in range(10)] + thumbnail = func(__(image_child)) + """ + ) + message = testutils.Message("comprehension-escape", node=escaped_node) + with self.assertAddsMessages(message): + self.checker.visit_listcomp(assign.value) + + with self.assertNoMessages(): + self.walk(good_module) + + def test_comprehension_escape_newly_introduced(self): + node = astroid.extract_node( + """ + [i for i in range(3)] + for i in range(3): + i + """ + ) + with self.assertNoMessages(): + self.walk(node) + + def test_exception_escape(self): + module = astroid.parse( + """ + try: 1/0 + except ValueError as exc: + pass + exc #@ + try: + 2/0 + except (ValueError, TypeError) as exc: + exc = 2 + exc #@ + try: + 2/0 + except (ValueError, TypeError): #@ + exc = 2 + """ + ) + message = testutils.Message("exception-escape", node=module.body[1].value) + with self.assertAddsMessages(message): + self.checker.visit_excepthandler(module.body[0].handlers[0]) + with self.assertNoMessages(): + self.checker.visit_excepthandler(module.body[2].handlers[0]) + self.checker.visit_excepthandler(module.body[4].handlers[0]) + + def test_bad_sys_attribute(self): + node = astroid.extract_node( + """ + import sys + sys.exc_clear #@ + """ + ) + message = testutils.Message("deprecated-sys-function", node=node) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + def test_bad_urllib_attribute(self): + nodes = astroid.extract_node( + """ + import urllib + urllib.addbase #@ + urllib.splithost #@ + urllib.urlretrieve #@ + urllib.urlopen #@ + urllib.urlencode #@ + """ + ) + for node in nodes: + message = testutils.Message("deprecated-urllib-function", node=node) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + def test_ok_string_attribute(self): + node = astroid.extract_node( + """ + import string + string.ascii_letters #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_attribute(node) + + def test_bad_string_call(self): + node = astroid.extract_node( + """ + import string + string.upper("hello world") #@ + """ + ) + message = testutils.Message("deprecated-string-function", node=node) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_ok_shadowed_call(self): + node = astroid.extract_node( + """ + import six.moves.configparser + six.moves.configparser.ConfigParser() #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_ok_string_call(self): + node = astroid.extract_node( + """ + import string + string.Foramtter() #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_bad_string_import_from(self): + node = astroid.extract_node( + """ + from string import atoi #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + message = testutils.Message("deprecated-string-function", node=node) + with self.assertAddsMessages(absolute_import_message, message): + self.checker.visit_importfrom(node) + + def test_ok_string_import_from(self): + node = astroid.extract_node( + """ + from string import digits #@ + """ + ) + absolute_import_message = testutils.Message("no-absolute-import", node=node) + with self.assertAddsMessages(absolute_import_message): + self.checker.visit_importfrom(node) + + def test_bad_str_translate_call_string_literal(self): + node = astroid.extract_node( + """ + foobar.translate(None, 'abc123') #@ + """ + ) + message = testutils.Message( + "deprecated-str-translate-call", node=node, confidence=INFERENCE_FAILURE + ) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_bad_str_translate_call_variable(self): + node = astroid.extract_node( + """ + def raz(foobar): + foobar.translate(None, 'hello') #@ + """ + ) + message = testutils.Message( + "deprecated-str-translate-call", node=node, confidence=INFERENCE_FAILURE + ) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_bad_str_translate_call_infer_str(self): + node = astroid.extract_node( + """ + foobar = "hello world" + foobar.translate(None, foobar) #@ + """ + ) + message = testutils.Message( + "deprecated-str-translate-call", node=node, confidence=INFERENCE + ) + with self.assertAddsMessages(message): + self.checker.visit_call(node) + + def test_ok_str_translate_call_integer(self): + node = astroid.extract_node( + """ + foobar.translate(None, 33) #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_ok_str_translate_call_keyword(self): + node = astroid.extract_node( + """ + foobar.translate(None, 'foobar', raz=33) #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_ok_str_translate_call_not_str(self): + node = astroid.extract_node( + """ + foobar = {} + foobar.translate(None, 'foobar') #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_non_py2_conditional(self): + code = """ + from __future__ import absolute_import + import sys + x = {} + if sys.maxsize: + x.iterkeys() #@ + """ + node = astroid.extract_node(code) + module = node.parent.parent + message = testutils.Message("dict-iter-method", node=node) + with self.assertAddsMessages(message): + self.walk(module) + + def test_six_conditional(self): + code = """ + from __future__ import absolute_import + import six + x = {} + if six.PY2: + x.iterkeys() + """ + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def test_versioninfo_conditional(self): + code = """ + from __future__ import absolute_import + import sys + x = {} + if sys.version_info[0] == 2: + x.iterkeys() + """ + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def test_versioninfo_tuple_conditional(self): + code = """ + from __future__ import absolute_import + import sys + x = {} + if sys.version_info == (2, 7): + x.iterkeys() + """ + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def test_six_ifexp_conditional(self): + code = """ + from __future__ import absolute_import + import six + import string + string.translate if six.PY2 else None + """ + module = astroid.parse(code) + with self.assertNoMessages(): + self.walk(module) + + def test_next_defined(self): + node = astroid.extract_node( + """ + class Foo(object): + def next(self): #@ + pass""" + ) + message = testutils.Message("next-method-defined", node=node) + with self.assertAddsMessages(message): + self.checker.visit_functiondef(node) + + def test_next_defined_too_many_args(self): + node = astroid.extract_node( + """ + class Foo(object): + def next(self, foo=None): #@ + pass""" + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_next_defined_static_method_too_many_args(self): + node = astroid.extract_node( + """ + class Foo(object): + @staticmethod + def next(self): #@ + pass""" + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + + def test_next_defined_static_method(self): + node = astroid.extract_node( + """ + class Foo(object): + @staticmethod + def next(): #@ + pass""" + ) + message = testutils.Message("next-method-defined", node=node) + with self.assertAddsMessages(message): + self.checker.visit_functiondef(node) + + def test_next_defined_class_method(self): + node = astroid.extract_node( + """ + class Foo(object): + @classmethod + def next(cls): #@ + pass""" + ) + message = testutils.Message("next-method-defined", node=node) + with self.assertAddsMessages(message): + self.checker.visit_functiondef(node) + + +@python2_only +class TestPython3TokenChecker(testutils.CheckerTestCase): + + CHECKER_CLASS = checker.Python3TokenChecker + + def _test_token_message(self, code, symbolic_message): + tokens = testutils._tokenize_str(code) + message = testutils.Message(symbolic_message, line=1) + with self.assertAddsMessages(message): + self.checker.process_tokens(tokens) + + def test_long_suffix(self): + for code in ("1l", "1L"): + self._test_token_message(code, "long-suffix") + + def test_old_ne_operator(self): + self._test_token_message("1 <> 2", "old-ne-operator") + + def test_old_octal_literal(self): + for octal in ("045", "055", "075", "077", "076543"): + self._test_token_message(octal, "old-octal-literal") + + # Make sure we are catching only octals. + for non_octal in ("45", "00", "085", "08", "1"): + tokens = testutils._tokenize_str(non_octal) + with self.assertNoMessages(): + self.checker.process_tokens(tokens) + + def test_non_ascii_bytes_literal(self): + code = 'b"测试"' + self._test_token_message(code, "non-ascii-bytes-literal") + for code in ("测试", "测试", "abcdef", b"\x80"): + tokens = testutils._tokenize_str(code) + with self.assertNoMessages(): + self.checker.process_tokens(tokens) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_similar.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_similar.py new file mode 100644 index 0000000..f2cd901 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_similar.py @@ -0,0 +1,198 @@ +# Copyright (c) 2010, 2012, 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012 Ry4an Brase <ry4an-hg@ry4an.org> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import sys +from os.path import join, dirname, abspath +from contextlib import redirect_stdout + +from io import StringIO +import pytest + +from pylint.checkers import similar + +SIMILAR1 = join(dirname(abspath(__file__)), "input", "similar1") +SIMILAR2 = join(dirname(abspath(__file__)), "input", "similar2") +MULTILINE = join(dirname(abspath(__file__)), "input", "multiline-import") +HIDE_CODE_WITH_IMPORTS = join( + dirname(abspath(__file__)), "input", "hide_code_with_imports.py" +) + + +def test_ignore_comments(): + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run(["--ignore-comments", SIMILAR1, SIMILAR2]) + assert ex.value.code == 0 + assert ( + output.getvalue().strip() + == ( + """ +10 similar lines in 2 files +==%s:0 +==%s:0 + import one + from two import two + three + four + five + six + seven + eight + nine + ''' ten +TOTAL lines=44 duplicates=10 percent=22.73 +""" + % (SIMILAR1, SIMILAR2) + ).strip() + ) + + +def test_ignore_docsrings(): + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run(["--ignore-docstrings", SIMILAR1, SIMILAR2]) + assert ex.value.code == 0 + assert ( + output.getvalue().strip() + == ( + """ +8 similar lines in 2 files +==%s:6 +==%s:6 + seven + eight + nine + ''' ten + ELEVEN + twelve ''' + thirteen + fourteen + +5 similar lines in 2 files +==%s:0 +==%s:0 + import one + from two import two + three + four + five +TOTAL lines=44 duplicates=13 percent=29.55 +""" + % ((SIMILAR1, SIMILAR2) * 2) + ).strip() + ) + + +def test_ignore_imports(): + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run(["--ignore-imports", SIMILAR1, SIMILAR2]) + assert ex.value.code == 0 + assert ( + output.getvalue().strip() + == """ +TOTAL lines=44 duplicates=0 percent=0.00 +""".strip() + ) + + +def test_multiline_imports(): + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run([MULTILINE, MULTILINE]) + assert ex.value.code == 0 + assert ( + output.getvalue().strip() + == ( + """ +8 similar lines in 2 files +==%s:0 +==%s:0 + from foo import ( + bar, + baz, + quux, + quuux, + quuuux, + quuuuux, + ) +TOTAL lines=16 duplicates=8 percent=50.00 +""" + % (MULTILINE, MULTILINE) + ).strip() + ) + + +def test_ignore_multiline_imports(): + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run(["--ignore-imports", MULTILINE, MULTILINE]) + assert ex.value.code == 0 + assert ( + output.getvalue().strip() + == """ +TOTAL lines=16 duplicates=0 percent=0.00 +""".strip() + ) + + +def test_no_hide_code_with_imports(): + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run(["--ignore-imports"] + 2 * [HIDE_CODE_WITH_IMPORTS]) + assert ex.value.code == 0 + assert "TOTAL lines=32 duplicates=16 percent=50.00" in output.getvalue() + + +def test_ignore_nothing(): + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run([SIMILAR1, SIMILAR2]) + assert ex.value.code == 0 + assert ( + output.getvalue().strip() + == ( + """ +5 similar lines in 2 files +==%s:0 +==%s:0 + import one + from two import two + three + four + five +TOTAL lines=44 duplicates=5 percent=11.36 +""" + % (SIMILAR1, SIMILAR2) + ).strip() + ) + + +def test_help(): + output = StringIO() + with redirect_stdout(output): + try: + similar.Run(["--help"]) + except SystemExit as ex: + assert ex.code == 0 + else: + pytest.fail("not system exit") + + +def test_no_args(): + output = StringIO() + with redirect_stdout(output): + try: + similar.Run([]) + except SystemExit as ex: + assert ex.code == 1 + else: + pytest.fail("not system exit") diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_spelling.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_spelling.py new file mode 100644 index 0000000..f6b5ec2 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_spelling.py @@ -0,0 +1,306 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Pedro Algarvio <pedro@algarvio.me> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unittest for the spelling checker.""" + +import pytest + +import astroid + +from pylint.checkers import spelling +from pylint.testutils import CheckerTestCase, Message, set_config, _tokenize_str + +# try to create enchant dictionary +try: + import enchant +except ImportError: + enchant = None + +spell_dict = None +if enchant is not None: + try: + enchant.Dict("en_US") + spell_dict = "en_US" + except enchant.DictNotFoundError: + pass + + +class TestSpellingChecker(CheckerTestCase): + CHECKER_CLASS = spelling.SpellingChecker + + skip_on_missing_package_or_dict = pytest.mark.skipif( + spell_dict is None, + reason="missing python-enchant package or missing spelling dictionaries", + ) + + def _get_msg_suggestions(self, word, count=4): + return "'{}'".format( + "' or '".join(self.checker.spelling_dict.suggest(word)[:count]) + ) + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_check_bad_coment(self): + with self.assertAddsMessages( + Message( + "wrong-spelling-in-comment", + line=1, + args=( + "coment", + "# bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment"), + ), + ) + ): + self.checker.process_tokens(_tokenize_str("# bad coment")) + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + @set_config(max_spelling_suggestions=2) + def test_check_bad_coment_custom_suggestion_count(self): + with self.assertAddsMessages( + Message( + "wrong-spelling-in-comment", + line=1, + args=( + "coment", + "# bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment", count=2), + ), + ) + ): + self.checker.process_tokens(_tokenize_str("# bad coment")) + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_check_bad_docstring(self): + stmt = astroid.extract_node('def fff():\n """bad coment"""\n pass') + with self.assertAddsMessages( + Message( + "wrong-spelling-in-docstring", + line=2, + args=( + "coment", + "bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment"), + ), + ) + ): + self.checker.visit_functiondef(stmt) + + stmt = astroid.extract_node('class Abc(object):\n """bad coment"""\n pass') + with self.assertAddsMessages( + Message( + "wrong-spelling-in-docstring", + line=2, + args=( + "coment", + "bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment"), + ), + ) + ): + self.checker.visit_classdef(stmt) + + @pytest.mark.skipif(True, reason="pyenchant's tokenizer strips these") + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_invalid_docstring_characters(self): + stmt = astroid.extract_node('def fff():\n """test\\x00"""\n pass') + with self.assertAddsMessages( + Message("invalid-characters-in-docstring", line=2, args=("test\x00",)) + ): + self.checker.visit_functiondef(stmt) + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_shebangs(self): + self.checker.process_tokens(_tokenize_str("#!/usr/bin/env python")) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_python_coding_comments(self): + self.checker.process_tokens(_tokenize_str("# -*- coding: utf-8 -*-")) + assert self.linter.release_messages() == [] + self.checker.process_tokens(_tokenize_str("# coding=utf-8")) + assert self.linter.release_messages() == [] + self.checker.process_tokens(_tokenize_str("# vim: set fileencoding=utf-8 :")) + assert self.linter.release_messages() == [] + # Now with a shebang first + self.checker.process_tokens( + _tokenize_str("#!/usr/bin/env python\n# -*- coding: utf-8 -*-") + ) + assert self.linter.release_messages() == [] + self.checker.process_tokens( + _tokenize_str("#!/usr/bin/env python\n# coding=utf-8") + ) + assert self.linter.release_messages() == [] + self.checker.process_tokens( + _tokenize_str("#!/usr/bin/env python\n# vim: set fileencoding=utf-8 :") + ) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_top_level_pylint_enable_disable_comments(self): + self.checker.process_tokens( + _tokenize_str("# Line 1\n Line 2\n# pylint: disable=ungrouped-imports") + ) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_words_with_numbers(self): + self.checker.process_tokens(_tokenize_str("\n# 0ne\n# Thr33\n# Sh3ll")) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_wiki_words(self): + stmt = astroid.extract_node( + 'class ComentAbc(object):\n """ComentAbc with a bad coment"""\n pass' + ) + with self.assertAddsMessages( + Message( + "wrong-spelling-in-docstring", + line=2, + args=( + "coment", + "ComentAbc with a bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment"), + ), + ) + ): + self.checker.visit_classdef(stmt) + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_camel_cased_words(self): + stmt = astroid.extract_node( + 'class ComentAbc(object):\n """comentAbc with a bad coment"""\n pass' + ) + with self.assertAddsMessages( + Message( + "wrong-spelling-in-docstring", + line=2, + args=( + "coment", + "comentAbc with a bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment"), + ), + ) + ): + self.checker.visit_classdef(stmt) + + # With just a single upper case letter in the end + stmt = astroid.extract_node( + 'class ComentAbc(object):\n """argumentN with a bad coment"""\n pass' + ) + with self.assertAddsMessages( + Message( + "wrong-spelling-in-docstring", + line=2, + args=( + "coment", + "argumentN with a bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment"), + ), + ) + ): + self.checker.visit_classdef(stmt) + + for ccn in ( + "xmlHttpRequest", + "newCustomer", + "newCustomerId", + "innerStopwatch", + "supportsIpv6OnIos", + "affine3D", + ): + stmt = astroid.extract_node( + 'class TestClass(object):\n """{} comment"""\n pass'.format(ccn) + ) + self.checker.visit_classdef(stmt) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_words_with_underscores(self): + stmt = astroid.extract_node( + 'def fff(param_name):\n """test param_name"""\n pass' + ) + self.checker.visit_functiondef(stmt) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_email_address(self): + self.checker.process_tokens(_tokenize_str("# uname@domain.tld")) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_urls(self): + self.checker.process_tokens(_tokenize_str("# https://github.com/rfk/pyenchant")) + assert self.linter.release_messages() == [] + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_skip_sphinx_directives(self): + stmt = astroid.extract_node( + 'class ComentAbc(object):\n """This is :class:`ComentAbc` with a bad coment"""\n pass' + ) + with self.assertAddsMessages( + Message( + "wrong-spelling-in-docstring", + line=2, + args=( + "coment", + "This is :class:`ComentAbc` with a bad coment", + " ^^^^^^", + self._get_msg_suggestions("coment"), + ), + ) + ): + self.checker.visit_classdef(stmt) + + @skip_on_missing_package_or_dict + @set_config(spelling_dict=spell_dict) + def test_handle_words_joined_by_forward_slash(self): + stmt = astroid.extract_node( + ''' + class ComentAbc(object): + """This is Comment/Abcz with a bad comment""" + pass + ''' + ) + with self.assertAddsMessages( + Message( + "wrong-spelling-in-docstring", + line=3, + args=( + "Abcz", + "This is Comment/Abcz with a bad comment", + " ^^^^", + self._get_msg_suggestions("Abcz"), + ), + ) + ): + self.checker.visit_classdef(stmt) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_stdlib.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_stdlib.py new file mode 100644 index 0000000..f425b0f --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_stdlib.py @@ -0,0 +1,117 @@ +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Cezar <celnazli@bitdefender.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Martin <MartinBasti@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import contextlib + +import astroid + +from pylint.checkers import stdlib +from pylint.testutils import CheckerTestCase, Message +from pylint.interfaces import UNDEFINED + + +@contextlib.contextmanager +def _add_transform(manager, node, transform, predicate=None): + manager.register_transform(node, transform, predicate) + try: + yield + finally: + manager.unregister_transform(node, transform, predicate) + + +class TestStdlibChecker(CheckerTestCase): + CHECKER_CLASS = stdlib.StdlibChecker + + def test_deprecated_no_qname_on_unexpected_nodes(self): + # Test that we don't crash on nodes which don't have + # a qname method. While this test might seem weird since + # it uses a transform, it's actually testing a crash that + # happened in production, but there was no way to retrieve + # the code for which this occurred (how an AssignAttr + # got to be the result of a function inference + # beats me..) + + def infer_func(node, context=None): + new_node = astroid.AssignAttr() + new_node.parent = node + yield new_node + + manager = astroid.MANAGER + transform = astroid.inference_tip(infer_func) + with _add_transform(manager, astroid.Name, transform): + node = astroid.extract_node( + """ + call_something() + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_copy_environ(self): + # shallow copy of os.environ should be reported + node = astroid.extract_node( + """ + import copy, os + copy.copy(os.environ) + """ + ) + with self.assertAddsMessages( + Message(msg_id="shallow-copy-environ", node=node, confidence=UNDEFINED) + ): + self.checker.visit_call(node) + + def test_copy_environ_hidden(self): + # shallow copy of os.environ should be reported + # hide function names to be sure that checker is not just matching text + node = astroid.extract_node( + """ + from copy import copy as test_cp + import os as o + test_cp(o.environ) + """ + ) + with self.assertAddsMessages( + Message(msg_id="shallow-copy-environ", node=node, confidence=UNDEFINED) + ): + self.checker.visit_call(node) + + def test_copy_dict(self): + # copy of dict is OK + node = astroid.extract_node( + """ + import copy + test_dict = {} + copy.copy(test_dict) + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_copy_uninferable(self): + # copy of uninferable object should not raise exception, nor make + # the checker crash + node = astroid.extract_node( + """ + import copy + from missing_library import MissingObject + copy.copy(MissingObject) + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_deepcopy_environ(self): + # deepcopy of os.environ is OK + node = astroid.extract_node( + """ + import copy, os + copy.deepcopy(os.environ) + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(node) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_strings.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_strings.py new file mode 100644 index 0000000..4cac737 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_strings.py @@ -0,0 +1,86 @@ +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import astroid + +from pylint.checkers import strings +from pylint.testutils import CheckerTestCase, Message + + +TEST_TOKENS = ( + '"X"', + "'X'", + "'''X'''", + '"""X"""', + 'r"X"', + "R'X'", + 'u"X"', + "F'X'", + 'f"X"', + "F'X'", + 'fr"X"', + 'Fr"X"', + 'fR"X"', + 'FR"X"', + 'rf"X"', + 'rF"X"', + 'Rf"X"', + 'RF"X"', +) + + +class TestStringChecker(CheckerTestCase): + CHECKER_CLASS = strings.StringFormatChecker + + def test_format_bytes(self): + code = "b'test'.format(1, 2)" + node = astroid.extract_node(code) + with self.assertNoMessages(): + self.checker.visit_call(node) + + def test_format_types(self): + for code in ("'%s' % 1", "'%d' % 1", "'%f' % 1"): + with self.assertNoMessages(): + node = astroid.extract_node(code) + self.checker.visit_binop(node) + + for code in ( + "'%s' % 1", + "'%(key)s' % {'key' : 1}", + "'%d' % 1", + "'%(key)d' % {'key' : 1}", + "'%f' % 1", + "'%(key)f' % {'key' : 1}", + "'%d' % 1.1", + "'%(key)d' % {'key' : 1.1}", + "'%s' % []", + "'%(key)s' % {'key' : []}", + "'%s' % None", + "'%(key)s' % {'key' : None}", + ): + with self.assertNoMessages(): + node = astroid.extract_node(code) + self.checker.visit_binop(node) + + for code, arg_type, format_type in [ + ("'%d' % '1'", "builtins.str", "d"), + ("'%(key)d' % {'key' : '1'}", "builtins.str", "d"), + ("'%x' % 1.1", "builtins.float", "x"), + ("'%(key)x' % {'key' : 1.1}", "builtins.float", "x"), + ("'%d' % []", "builtins.list", "d"), + ("'%(key)d' % {'key' : []}", "builtins.list", "d"), + ]: + node = astroid.extract_node(code) + with self.assertAddsMessages( + Message( + "bad-string-format-type", node=node, args=(arg_type, format_type) + ) + ): + self.checker.visit_binop(node) + + def test_str_eval(self): + for token in TEST_TOKENS: + assert strings.str_eval(token) == "X" diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_typecheck.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_typecheck.py new file mode 100644 index 0000000..173210c --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_typecheck.py @@ -0,0 +1,317 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Holger Peters <email@holger-peters.de> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Filipe Brandenburger <filbranden@google.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unittest for the type checker.""" +import sys + +import pytest + +import astroid + +from pylint.checkers import typecheck +from pylint.testutils import CheckerTestCase, Message, set_config + + +def c_extension_missing(): + """Coverage module has C-extension, which we can reuse for test""" + try: + import coverage.tracer as _ + + return False + except ImportError: + _ = None + return True + + +needs_c_extension = pytest.mark.skipif( + c_extension_missing(), reason="Requires coverage (source of C-extension)" +) + + +class TestTypeChecker(CheckerTestCase): + "Tests for pylint.checkers.typecheck" + CHECKER_CLASS = typecheck.TypeChecker + + def test_no_member_in_getattr(self): + """Make sure that a module attribute access is checked by pylint. + """ + + node = astroid.extract_node( + """ + import optparse + optparse.THIS_does_not_EXIST + """ + ) + with self.assertAddsMessages( + Message( + "no-member", + node=node, + args=("Module", "optparse", "THIS_does_not_EXIST", ""), + ) + ): + self.checker.visit_attribute(node) + + @set_config(ignored_modules=("argparse",)) + def test_no_member_in_getattr_ignored(self): + """Make sure that a module attribute access check is omitted with a + module that is configured to be ignored. + """ + + node = astroid.extract_node( + """ + import argparse + argparse.THIS_does_not_EXIST + """ + ) + with self.assertNoMessages(): + self.checker.visit_attribute(node) + + @set_config(ignored_classes=("xml.etree.",)) + def test_ignored_modules_invalid_pattern(self): + node = astroid.extract_node( + """ + import xml + xml.etree.Lala + """ + ) + message = Message( + "no-member", node=node, args=("Module", "xml.etree", "Lala", "") + ) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + @set_config(ignored_modules=("xml.etree*",)) + def test_ignored_modules_patterns(self): + node = astroid.extract_node( + """ + import xml + xml.etree.portocola #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_attribute(node) + + @set_config(ignored_classes=("xml.*",)) + def test_ignored_classes_no_recursive_pattern(self): + node = astroid.extract_node( + """ + import xml + xml.etree.ElementTree.Test + """ + ) + message = Message( + "no-member", node=node, args=("Module", "xml.etree.ElementTree", "Test", "") + ) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + @set_config(ignored_classes=("optparse.Values",)) + def test_ignored_classes_qualified_name(self): + """Test that ignored-classes supports qualified name for ignoring.""" + node = astroid.extract_node( + """ + import optparse + optparse.Values.lala + """ + ) + with self.assertNoMessages(): + self.checker.visit_attribute(node) + + @set_config(ignored_classes=("Values",)) + def test_ignored_classes_only_name(self): + """Test that ignored_classes works with the name only.""" + node = astroid.extract_node( + """ + import optparse + optparse.Values.lala + """ + ) + with self.assertNoMessages(): + self.checker.visit_attribute(node) + + @set_config(suggestion_mode=False) + @needs_c_extension + def test_nomember_on_c_extension_error_msg(self): + node = astroid.extract_node( + """ + from coverage import tracer + tracer.CTracer #@ + """ + ) + message = Message( + "no-member", node=node, args=("Module", "coverage.tracer", "CTracer", "") + ) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + @set_config(suggestion_mode=True) + @needs_c_extension + def test_nomember_on_c_extension_info_msg(self): + node = astroid.extract_node( + """ + from coverage import tracer + tracer.CTracer #@ + """ + ) + message = Message( + "c-extension-no-member", + node=node, + args=("Module", "coverage.tracer", "CTracer", ""), + ) + with self.assertAddsMessages(message): + self.checker.visit_attribute(node) + + @set_config( + contextmanager_decorators=( + "contextlib.contextmanager", + ".custom_contextmanager", + ) + ) + def test_custom_context_manager(self): + """Test that @custom_contextmanager is recognized as configured.""" + node = astroid.extract_node( + """ + from contextlib import contextmanager + def custom_contextmanager(f): + return contextmanager(f) + @custom_contextmanager + def dec(): + yield + with dec(): + pass + """ + ) + with self.assertNoMessages(): + self.checker.visit_with(node) + + def test_invalid_metaclass(self): + module = astroid.parse( + """ + import six + + class InvalidAsMetaclass(object): + pass + + @six.add_metaclass(int) + class FirstInvalid(object): + pass + + @six.add_metaclass(InvalidAsMetaclass) + class SecondInvalid(object): + pass + + @six.add_metaclass(2) + class ThirdInvalid(object): + pass + """ + ) + for class_obj, metaclass_name in ( + ("ThirdInvalid", "2"), + ("SecondInvalid", "InvalidAsMetaclass"), + ("FirstInvalid", "int"), + ): + classdef = module[class_obj] + message = Message( + "invalid-metaclass", node=classdef, args=(metaclass_name,) + ) + with self.assertAddsMessages(message): + self.checker.visit_classdef(classdef) + + @pytest.mark.skipif(sys.version_info[0] < 3, reason="Needs Python 3.") + def test_invalid_metaclass_function_metaclasses(self): + module = astroid.parse( + """ + def invalid_metaclass_1(name, bases, attrs): + return int + def invalid_metaclass_2(name, bases, attrs): + return 1 + class Invalid(metaclass=invalid_metaclass_1): + pass + class InvalidSecond(metaclass=invalid_metaclass_2): + pass + """ + ) + for class_obj, metaclass_name in (("Invalid", "int"), ("InvalidSecond", "1")): + classdef = module[class_obj] + message = Message( + "invalid-metaclass", node=classdef, args=(metaclass_name,) + ) + with self.assertAddsMessages(message): + self.checker.visit_classdef(classdef) + + @pytest.mark.skipif(sys.version_info < (3, 5), reason="Needs Python 3.5.") + def test_typing_namedtuple_not_callable_issue1295(self): + module = astroid.parse( + """ + import typing + Named = typing.NamedTuple('Named', [('foo', int), ('bar', int)]) + named = Named(1, 2) + """ + ) + call = module.body[-1].value + callables = call.func.inferred() + assert len(callables) == 1 + assert callables[0].callable() + with self.assertNoMessages(): + self.checker.visit_call(call) + + @pytest.mark.skipif(sys.version_info < (3, 5), reason="Needs Python 3.5.") + def test_typing_namedtuple_unsubscriptable_object_issue1295(self): + module = astroid.parse( + """ + import typing + MyType = typing.Tuple[str, str] + """ + ) + subscript = module.body[-1].value + with self.assertNoMessages(): + self.checker.visit_subscript(subscript) + + def test_staticmethod_multiprocessing_call(self): + """Make sure not-callable isn't raised for descriptors + + astroid can't process descriptors correctly so + pylint needs to ignore not-callable for them + right now + + Test for https://github.com/PyCQA/pylint/issues/1699 + """ + call = astroid.extract_node( + """ + import multiprocessing + multiprocessing.current_process() #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(call) + + def test_descriptor_call(self): + call = astroid.extract_node( + """ + def func(): + pass + + class ADescriptor: + def __get__(self, instance, owner): + return func + + class AggregateCls: + a = ADescriptor() + + AggregateCls().a() #@ + """ + ) + with self.assertNoMessages(): + self.checker.visit_call(call) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_variables.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_variables.py new file mode 100644 index 0000000..a9b590a --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checker_variables.py @@ -0,0 +1,284 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2018 Bryce Guinta <bryce.guinta@protonmail.com> +# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2018 mar-chi-pan <mar.polatoglou@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the variables checker.""" +import sys +import os +import re + +import astroid + +from pylint.checkers import variables +from pylint.testutils import CheckerTestCase, linter, set_config, Message +from pylint.interfaces import UNDEFINED + + +class TestVariablesChecker(CheckerTestCase): + + CHECKER_CLASS = variables.VariablesChecker + + def test_bitbucket_issue_78(self): + """ Issue 78 report a false positive for unused-module """ + module = astroid.parse( + """ + from sys import path + path += ['stuff'] + def func(): + other = 1 + return len(other) + """ + ) + with self.assertNoMessages(): + self.walk(module) + + @set_config(ignored_modules=("argparse",)) + def test_no_name_in_module_skipped(self): + """Make sure that 'from ... import ...' does not emit a + 'no-name-in-module' with a module that is configured + to be ignored. + """ + + node = astroid.extract_node( + """ + from argparse import THIS_does_not_EXIST + """ + ) + with self.assertNoMessages(): + self.checker.visit_importfrom(node) + + def test_all_elements_without_parent(self): + node = astroid.extract_node("__all__ = []") + node.value.elts.append(astroid.Const("test")) + root = node.root() + with self.assertNoMessages(): + self.checker.visit_module(root) + self.checker.leave_module(root) + + def test_redefined_builtin_ignored(self): + node = astroid.parse( + """ + from future.builtins import open + """ + ) + with self.assertNoMessages(): + self.checker.visit_module(node) + + @set_config(redefining_builtins_modules=("os",)) + def test_redefined_builtin_custom_modules(self): + node = astroid.parse( + """ + from os import open + """ + ) + with self.assertNoMessages(): + self.checker.visit_module(node) + + @set_config(redefining_builtins_modules=("os",)) + def test_redefined_builtin_modname_not_ignored(self): + node = astroid.parse( + """ + from future.builtins import open + """ + ) + with self.assertAddsMessages( + Message("redefined-builtin", node=node.body[0], args="open") + ): + self.checker.visit_module(node) + + @set_config(redefining_builtins_modules=("os",)) + def test_redefined_builtin_in_function(self): + node = astroid.extract_node( + """ + def test(): + from os import open + """ + ) + with self.assertNoMessages(): + self.checker.visit_module(node.root()) + self.checker.visit_functiondef(node) + + def test_unassigned_global(self): + node = astroid.extract_node( + """ + def func(): + global sys #@ + import sys, lala + """ + ) + msg = Message("global-statement", node=node, confidence=UNDEFINED) + with self.assertAddsMessages(msg): + self.checker.visit_global(node) + + +class TestVariablesCheckerWithTearDown(CheckerTestCase): + + CHECKER_CLASS = variables.VariablesChecker + + def setup_method(self): + super(TestVariablesCheckerWithTearDown, self).setup_method() + self._to_consume_backup = self.checker._to_consume + self.checker._to_consume = [] + + def teardown_method(self, method): + self.checker._to_consume = self._to_consume_backup + + @set_config(callbacks=("callback_", "_callback")) + def test_custom_callback_string(self): + """ Test the --calbacks option works. """ + node = astroid.extract_node( + """ + def callback_one(abc): + ''' should not emit unused-argument. ''' + """ + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) + + node = astroid.extract_node( + """ + def two_callback(abc, defg): + ''' should not emit unused-argument. ''' + """ + ) + with self.assertNoMessages(): + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) + + node = astroid.extract_node( + """ + def normal_func(abc): + ''' should emit unused-argument. ''' + """ + ) + with self.assertAddsMessages( + Message("unused-argument", node=node["abc"], args="abc") + ): + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) + + node = astroid.extract_node( + """ + def cb_func(abc): + ''' Previous callbacks are overridden. ''' + """ + ) + with self.assertAddsMessages( + Message("unused-argument", node=node["abc"], args="abc") + ): + self.checker.visit_functiondef(node) + self.checker.leave_functiondef(node) + + @set_config(redefining_builtins_modules=("os",)) + def test_redefined_builtin_modname_not_ignored(self): + node = astroid.parse( + """ + from future.builtins import open + """ + ) + with self.assertAddsMessages( + Message("redefined-builtin", node=node.body[0], args="open") + ): + self.checker.visit_module(node) + + @set_config(redefining_builtins_modules=("os",)) + def test_redefined_builtin_in_function(self): + node = astroid.extract_node( + """ + def test(): + from os import open + """ + ) + with self.assertNoMessages(): + self.checker.visit_module(node.root()) + self.checker.visit_functiondef(node) + + def test_import_as_underscore(self): + node = astroid.parse( + """ + import math as _ + """ + ) + with self.assertNoMessages(): + self.walk(node) + + def test_lambda_in_classdef(self): + # Make sure lambda doesn't raises + # Undefined-method in class def + + # Issue 1824 + # https://github.com/PyCQA/pylint/issues/1824 + node = astroid.parse( + """ + class MyObject(object): + method1 = lambda func: func() + method2 = lambda function: function() + """ + ) + with self.assertNoMessages(): + self.walk(node) + + def test_nested_lambda(self): + """Make sure variables from parent lambdas + aren't noted as undefined + + https://github.com/PyCQA/pylint/issues/760 + """ + node = astroid.parse( + """ + lambda x: lambda: x + 1 + """ + ) + with self.assertNoMessages(): + self.walk(node) + + @set_config(ignored_argument_names=re.compile("arg")) + def test_ignored_argument_names_no_message(self): + """Make sure is_ignored_argument_names properly ignores + function arguments""" + node = astroid.parse( + """ + def fooby(arg): + pass + """ + ) + with self.assertNoMessages(): + self.walk(node) + + @set_config(ignored_argument_names=re.compile("args|kwargs")) + def test_ignored_argument_names_starred_args(self): + node = astroid.parse( + """ + def fooby(*args, **kwargs): + pass + """ + ) + with self.assertNoMessages(): + self.walk(node) + + +class TestMissingSubmodule(CheckerTestCase): + CHECKER_CLASS = variables.VariablesChecker + + def test_package_all(self): + regr_data = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "regrtest_data" + ) + sys.path.insert(0, regr_data) + try: + linter.check(os.path.join(regr_data, "package_all")) + got = linter.reporter.finalize().strip() + assert got == "E: 3: Undefined variable name 'missing' in __all__" + finally: + sys.path.pop(0) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checkers_utils.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checkers_utils.py new file mode 100644 index 0000000..3471912 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_checkers_utils.py @@ -0,0 +1,172 @@ +# Copyright (c) 2010 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2013-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Caio Carrara <ccarrara@redhat.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Tests for the pylint.checkers.utils module.""" + +import astroid + +from pylint.checkers import utils +import pytest + + +@pytest.mark.parametrize( + "name,expected", + [ + ("min", True), + ("__builtins__", True), + ("__path__", False), + ("__file__", False), + ("whatever", False), + ("mybuiltin", False), + ], +) +def testIsBuiltin(name, expected): + assert utils.is_builtin(name) == expected + + +@pytest.mark.parametrize( + "fn,kw", + [("foo(3)", {"keyword": "bar"}), ("foo(one=a, two=b, three=c)", {"position": 1})], +) +def testGetArgumentFromCallError(fn, kw): + with pytest.raises(utils.NoSuchArgumentError): + node = astroid.extract_node(fn) + utils.get_argument_from_call(node, **kw) + + +@pytest.mark.parametrize( + "fn,kw", [("foo(bar=3)", {"keyword": "bar"}), ("foo(a, b, c)", {"position": 1})] +) +def testGetArgumentFromCallExists(fn, kw): + node = astroid.extract_node(fn) + assert utils.get_argument_from_call(node, **kw) is not None + + +def testGetArgumentFromCall(): + node = astroid.extract_node("foo(a, not_this_one=1, this_one=2)") + arg = utils.get_argument_from_call(node, position=2, keyword="this_one") + assert 2 == arg.value + + node = astroid.extract_node("foo(a)") + with pytest.raises(utils.NoSuchArgumentError): + utils.get_argument_from_call(node, position=1) + with pytest.raises(ValueError): + utils.get_argument_from_call(node, None, None) + name = utils.get_argument_from_call(node, position=0) + assert name.name == "a" + + +def test_error_of_type(): + nodes = astroid.extract_node( + """ + try: pass + except AttributeError: #@ + pass + try: pass + except Exception: #@ + pass + except: #@ + pass + """ + ) + assert utils.error_of_type(nodes[0], AttributeError) + assert utils.error_of_type(nodes[0], (AttributeError,)) + assert not utils.error_of_type(nodes[0], Exception) + assert utils.error_of_type(nodes[1], Exception) + assert utils.error_of_type(nodes[2], ImportError) + + +def test_node_ignores_exception(): + nodes = astroid.extract_node( + """ + try: + 1/0 #@ + except ZeroDivisionError: + pass + try: + 1/0 #@ + except Exception: + pass + try: + 2/0 #@ + except: + pass + try: + 1/0 #@ + except ValueError: + pass + """ + ) + assert utils.node_ignores_exception(nodes[0], ZeroDivisionError) + assert not utils.node_ignores_exception(nodes[1], ZeroDivisionError) + assert utils.node_ignores_exception(nodes[2], ZeroDivisionError) + assert not utils.node_ignores_exception(nodes[3], ZeroDivisionError) + + +def test_is_subclass_of_node_b_derived_from_node_a(): + nodes = astroid.extract_node( + """ + class Superclass: #@ + pass + + class Subclass(Superclass): #@ + pass + """ + ) + assert utils.is_subclass_of(nodes[1], nodes[0]) + + +def test_is_subclass_of_node_b_not_derived_from_node_a(): + nodes = astroid.extract_node( + """ + class OneClass: #@ + pass + + class AnotherClass: #@ + pass + """ + ) + assert not utils.is_subclass_of(nodes[1], nodes[0]) + + +def test_is_subclass_of_not_classdefs(): + node = astroid.extract_node( + """ + class OneClass: #@ + pass + """ + ) + assert not utils.is_subclass_of(None, node) + assert not utils.is_subclass_of(node, None) + assert not utils.is_subclass_of(None, None) + + +def test_parse_format_method_string(): + samples = [ + ("{}", 1), + ("{}:{}", 2), + ("{field}", 1), + ("{:5}", 1), + ("{:10}", 1), + ("{field:10}", 1), + ("{field:10}{{}}", 1), + ("{:5}{!r:10}", 2), + ("{:5}{}{{}}{}", 3), + ("{0}{1}{0}", 2), + ("Coordinates: {latitude}, {longitude}", 2), + ("X: {0[0]}; Y: {0[1]}", 1), + ("{:*^30}", 1), + ("{!r:}", 1), + ] + for fmt, count in samples: + keys, num_args, pos_args = utils.parse_format_method_string(fmt) + keyword_args = len(set(k for k, l in keys if not isinstance(k, int))) + assert keyword_args + num_args + pos_args == count diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_config.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_config.py new file mode 100644 index 0000000..17e48d5 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_config.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015 Aru Sahni <arusahni@gmail.com> +# Copyright (c) 2016-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Unit tests for the config module.""" + +import re +import sre_constants + +from pylint import config +import pytest + + +RE_PATTERN_TYPE = getattr(re, "Pattern", getattr(re, "_pattern_type", None)) + + +def test__regexp_validator_valid(): + result = config._regexp_validator(None, None, "test_.*") + assert isinstance(result, RE_PATTERN_TYPE) + assert result.pattern == "test_.*" + + +def test__regexp_validator_invalid(): + with pytest.raises(sre_constants.error): + config._regexp_validator(None, None, "test_)") + + +def test__csv_validator_no_spaces(): + values = ["One", "Two", "Three"] + result = config._csv_validator(None, None, ",".join(values)) + assert isinstance(result, list) + assert len(result) == 3 + for i, value in enumerate(values): + assert result[i] == value + + +def test__csv_validator_spaces(): + values = ["One", "Two", "Three"] + result = config._csv_validator(None, None, ", ".join(values)) + assert isinstance(result, list) + assert len(result) == 3 + for i, value in enumerate(values): + assert result[i] == value + + +def test__regexp_csv_validator_valid(): + pattern_strings = ["test_.*", "foo\\.bar", "^baz$"] + result = config._regexp_csv_validator(None, None, ",".join(pattern_strings)) + for i, regex in enumerate(result): + assert isinstance(regex, RE_PATTERN_TYPE) + assert regex.pattern == pattern_strings[i] + + +def test__regexp_csv_validator_invalid(): + pattern_strings = ["test_.*", "foo\\.bar", "^baz)$"] + with pytest.raises(sre_constants.error): + config._regexp_csv_validator(None, None, ",".join(pattern_strings)) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_lint.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_lint.py new file mode 100644 index 0000000..48af48d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_lint.py @@ -0,0 +1,823 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2009 Charles Hebert <charles.hebert@logilab.fr> +# Copyright (c) 2011-2014 Google, Inc. +# Copyright (c) 2012 Kevin Jing Qiu <kevin.jing.qiu@gmail.com> +# Copyright (c) 2012 Anthony VEREZ <anthony.verez.external@cassidian.com> +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2013-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Noam Yorav-Raphael <noamraph@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com> +# Copyright (c) 2017 Pierre Sassoulas <pierre.sassoulas@cea.fr> +# Copyright (c) 2017 Craig Citro <craigcitro@gmail.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2018 Randall Leeds <randall@bleeds.info> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2018 Pierre Sassoulas <pierre.sassoulas@wisebim.fr> +# Copyright (c) 2018 Reverb C <reverbc@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +from contextlib import contextmanager, redirect_stdout +import sys +import os +import re +import tempfile +from shutil import rmtree +from os import getcwd, chdir +from os.path import join, basename, dirname, isdir, abspath, sep +from importlib import reload +from io import StringIO + +from pylint import config, lint +from pylint.lint import PyLinter, Run, preprocess_options, ArgumentPreprocessingError +from pylint.utils import ( + MSG_STATE_SCOPE_CONFIG, + MSG_STATE_SCOPE_MODULE, + MSG_STATE_CONFIDENCE, + MessagesStore, + MessageDefinition, + FileState, + tokenize_module, +) +from pylint.exceptions import InvalidMessageError, UnknownMessageError +import pylint.testutils as testutils +from pylint.reporters import text +from pylint import checkers +from pylint.checkers.utils import check_messages +from pylint import exceptions +from pylint import interfaces +import pytest + +if os.name == "java": + if os._name == "nt": + HOME = "USERPROFILE" + else: + HOME = "HOME" +else: + if sys.platform == "win32": + HOME = "USERPROFILE" + else: + HOME = "HOME" + +try: + PYPY_VERSION_INFO = sys.pypy_version_info +except AttributeError: + PYPY_VERSION_INFO = None + + +@contextmanager +def fake_home(): + folder = tempfile.mkdtemp("fake-home") + old_home = os.environ.get(HOME) + try: + os.environ[HOME] = folder + yield + finally: + os.environ.pop("PYLINTRC", "") + if old_home is None: + del os.environ[HOME] + else: + os.environ[HOME] = old_home + rmtree(folder, ignore_errors=True) + + +def remove(file): + try: + os.remove(file) + except OSError: + pass + + +HERE = abspath(dirname(__file__)) +INPUTDIR = join(HERE, "input") +REGRTEST_DATA = join(HERE, "regrtest_data") + + +@contextmanager +def tempdir(): + """Create a temp directory and change the current location to it. + + This is supposed to be used with a *with* statement. + """ + tmp = tempfile.mkdtemp() + + # Get real path of tempfile, otherwise test fail on mac os x + current_dir = getcwd() + chdir(tmp) + abs_tmp = abspath(".") + + try: + yield abs_tmp + finally: + chdir(current_dir) + rmtree(abs_tmp) + + +def create_files(paths, chroot="."): + """Creates directories and files found in <path>. + + :param paths: list of relative paths to files or directories + :param chroot: the root directory in which paths will be created + + >>> from os.path import isdir, isfile + >>> isdir('/tmp/a') + False + >>> create_files(['a/b/foo.py', 'a/b/c/', 'a/b/c/d/e.py'], '/tmp') + >>> isdir('/tmp/a') + True + >>> isdir('/tmp/a/b/c') + True + >>> isfile('/tmp/a/b/c/d/e.py') + True + >>> isfile('/tmp/a/b/foo.py') + True + """ + dirs, files = set(), set() + for path in paths: + path = join(chroot, path) + filename = basename(path) + # path is a directory path + if filename == "": + dirs.add(path) + # path is a filename path + else: + dirs.add(dirname(path)) + files.add(path) + for dirpath in dirs: + if not isdir(dirpath): + os.makedirs(dirpath) + for filepath in files: + open(filepath, "w").close() + + +@pytest.fixture +def fake_path(): + orig = list(sys.path) + fake = [1, 2, 3] + sys.path[:] = fake + yield fake + sys.path[:] = orig + + +def test_no_args(fake_path): + with lint.fix_import_path([]): + assert sys.path == ["."] + fake_path + assert sys.path == fake_path + + +@pytest.mark.parametrize( + "case", [["a/b/"], ["a/b"], ["a/b/__init__.py"], ["a/"], ["a"]] +) +def test_one_arg(fake_path, case): + with tempdir() as chroot: + create_files(["a/b/__init__.py"]) + expected = [join(chroot, "a")] + ["."] + fake_path + + assert sys.path == fake_path + with lint.fix_import_path(case): + assert sys.path == expected + assert sys.path == fake_path + + +@pytest.mark.parametrize( + "case", + [ + ["a/b", "a/c"], + ["a/c/", "a/b/"], + ["a/b/__init__.py", "a/c/__init__.py"], + ["a", "a/c/__init__.py"], + ], +) +def test_two_similar_args(fake_path, case): + with tempdir() as chroot: + create_files(["a/b/__init__.py", "a/c/__init__.py"]) + expected = [join(chroot, "a")] + ["."] + fake_path + + assert sys.path == fake_path + with lint.fix_import_path(case): + assert sys.path == expected + assert sys.path == fake_path + + +@pytest.mark.parametrize( + "case", + [ + ["a/b/c/__init__.py", "a/d/__init__.py", "a/e/f.py"], + ["a/b/c", "a", "a/e"], + ["a/b/c", "a", "a/b/c", "a/e", "a"], + ], +) +def test_more_args(fake_path, case): + with tempdir() as chroot: + create_files(["a/b/c/__init__.py", "a/d/__init__.py", "a/e/f.py"]) + expected = ( + [ + join(chroot, suffix) + for suffix in [sep.join(("a", "b")), "a", sep.join(("a", "e"))] + ] + + ["."] + + fake_path + ) + + assert sys.path == fake_path + with lint.fix_import_path(case): + assert sys.path == expected + assert sys.path == fake_path + + +@pytest.fixture(scope="module") +def disable(disable): + return ["I"] + + +@pytest.fixture(scope="module") +def reporter(reporter): + return testutils.TestReporter + + +@pytest.fixture +def init_linter(linter): + linter.open() + linter.set_current_module("toto") + linter.file_state = FileState("toto") + return linter + + +def test_pylint_visit_method_taken_in_account(linter): + class CustomChecker(checkers.BaseChecker): + __implements__ = interfaces.IAstroidChecker + name = "custom" + msgs = {"W9999": ("", "custom", "")} + + @check_messages("custom") + def visit_class(self, _): + pass + + linter.register_checker(CustomChecker(linter)) + linter.open() + out = StringIO() + linter.set_reporter(text.TextReporter(out)) + linter.check("abc") + + +def test_enable_message(init_linter): + linter = init_linter + assert linter.is_message_enabled("W0101") + assert linter.is_message_enabled("W0102") + linter.disable("W0101", scope="package") + linter.disable("W0102", scope="module", line=1) + assert not linter.is_message_enabled("W0101") + assert not linter.is_message_enabled("W0102", 1) + linter.set_current_module("tutu") + assert not linter.is_message_enabled("W0101") + assert linter.is_message_enabled("W0102") + linter.enable("W0101", scope="package") + linter.enable("W0102", scope="module", line=1) + assert linter.is_message_enabled("W0101") + assert linter.is_message_enabled("W0102", 1) + + +def test_enable_message_category(init_linter): + linter = init_linter + assert linter.is_message_enabled("W0101") + assert linter.is_message_enabled("C0202") + linter.disable("W", scope="package") + linter.disable("C", scope="module", line=1) + assert not linter.is_message_enabled("W0101") + assert linter.is_message_enabled("C0202") + assert not linter.is_message_enabled("C0202", line=1) + linter.set_current_module("tutu") + assert not linter.is_message_enabled("W0101") + assert linter.is_message_enabled("C0202") + linter.enable("W", scope="package") + linter.enable("C", scope="module", line=1) + assert linter.is_message_enabled("W0101") + assert linter.is_message_enabled("C0202") + assert linter.is_message_enabled("C0202", line=1) + + +def test_message_state_scope(init_linter): + class FakeConfig(object): + confidence = ["HIGH"] + + linter = init_linter + linter.disable("C0202") + assert MSG_STATE_SCOPE_CONFIG == linter.get_message_state_scope("C0202") + linter.disable("W0101", scope="module", line=3) + assert MSG_STATE_SCOPE_CONFIG == linter.get_message_state_scope("C0202") + assert MSG_STATE_SCOPE_MODULE == linter.get_message_state_scope("W0101", 3) + linter.enable("W0102", scope="module", line=3) + assert MSG_STATE_SCOPE_MODULE == linter.get_message_state_scope("W0102", 3) + linter.config = FakeConfig() + assert MSG_STATE_CONFIDENCE == linter.get_message_state_scope( + "this-is-bad", confidence=interfaces.INFERENCE + ) + + +def test_enable_message_block(init_linter): + linter = init_linter + linter.open() + filepath = join(REGRTEST_DATA, "func_block_disable_msg.py") + linter.set_current_module("func_block_disable_msg") + astroid = linter.get_ast(filepath, "func_block_disable_msg") + linter.process_tokens(tokenize_module(astroid)) + fs = linter.file_state + fs.collect_block_lines(linter.msgs_store, astroid) + # global (module level) + assert linter.is_message_enabled("W0613") + assert linter.is_message_enabled("E1101") + # meth1 + assert linter.is_message_enabled("W0613", 13) + # meth2 + assert not linter.is_message_enabled("W0613", 18) + # meth3 + assert not linter.is_message_enabled("E1101", 24) + assert linter.is_message_enabled("E1101", 26) + # meth4 + assert not linter.is_message_enabled("E1101", 32) + assert linter.is_message_enabled("E1101", 36) + # meth5 + assert not linter.is_message_enabled("E1101", 42) + assert not linter.is_message_enabled("E1101", 43) + assert linter.is_message_enabled("E1101", 46) + assert not linter.is_message_enabled("E1101", 49) + assert not linter.is_message_enabled("E1101", 51) + # meth6 + assert not linter.is_message_enabled("E1101", 57) + assert linter.is_message_enabled("E1101", 61) + assert not linter.is_message_enabled("E1101", 64) + assert not linter.is_message_enabled("E1101", 66) + + assert linter.is_message_enabled("E0602", 57) + assert linter.is_message_enabled("E0602", 61) + assert not linter.is_message_enabled("E0602", 62) + assert linter.is_message_enabled("E0602", 64) + assert linter.is_message_enabled("E0602", 66) + # meth7 + assert not linter.is_message_enabled("E1101", 70) + assert linter.is_message_enabled("E1101", 72) + assert linter.is_message_enabled("E1101", 75) + assert linter.is_message_enabled("E1101", 77) + + fs = linter.file_state + assert 17 == fs._suppression_mapping["W0613", 18] + assert 30 == fs._suppression_mapping["E1101", 33] + assert ("E1101", 46) not in fs._suppression_mapping + assert 1 == fs._suppression_mapping["C0302", 18] + assert 1 == fs._suppression_mapping["C0302", 50] + # This is tricky. While the disable in line 106 is disabling + # both 108 and 110, this is usually not what the user wanted. + # Therefore, we report the closest previous disable comment. + assert 106 == fs._suppression_mapping["E1101", 108] + assert 109 == fs._suppression_mapping["E1101", 110] + + +def test_enable_by_symbol(init_linter): + """messages can be controlled by symbolic names. + + The state is consistent across symbols and numbers. + """ + linter = init_linter + assert linter.is_message_enabled("W0101") + assert linter.is_message_enabled("unreachable") + assert linter.is_message_enabled("W0102") + assert linter.is_message_enabled("dangerous-default-value") + linter.disable("unreachable", scope="package") + linter.disable("dangerous-default-value", scope="module", line=1) + assert not linter.is_message_enabled("W0101") + assert not linter.is_message_enabled("unreachable") + assert not linter.is_message_enabled("W0102", 1) + assert not linter.is_message_enabled("dangerous-default-value", 1) + linter.set_current_module("tutu") + assert not linter.is_message_enabled("W0101") + assert not linter.is_message_enabled("unreachable") + assert linter.is_message_enabled("W0102") + assert linter.is_message_enabled("dangerous-default-value") + linter.enable("unreachable", scope="package") + linter.enable("dangerous-default-value", scope="module", line=1) + assert linter.is_message_enabled("W0101") + assert linter.is_message_enabled("unreachable") + assert linter.is_message_enabled("W0102", 1) + assert linter.is_message_enabled("dangerous-default-value", 1) + + +def test_enable_report(linter): + assert linter.report_is_enabled("RP0001") + linter.disable("RP0001") + assert not linter.report_is_enabled("RP0001") + linter.enable("RP0001") + assert linter.report_is_enabled("RP0001") + + +def test_report_output_format_aliased(linter): + text.register(linter) + linter.set_option("output-format", "text") + assert linter.reporter.__class__.__name__ == "TextReporter" + + +def test_set_unsupported_reporter(linter): + text.register(linter) + with pytest.raises(exceptions.InvalidReporterError): + linter.set_option("output-format", "missing.module.Class") + + +def test_set_option_1(linter): + linter.set_option("disable", "C0111,W0234") + assert not linter.is_message_enabled("C0111") + assert not linter.is_message_enabled("W0234") + assert linter.is_message_enabled("W0113") + assert not linter.is_message_enabled("missing-docstring") + assert not linter.is_message_enabled("non-iterator-returned") + + +def test_set_option_2(linter): + linter.set_option("disable", ("C0111", "W0234")) + assert not linter.is_message_enabled("C0111") + assert not linter.is_message_enabled("W0234") + assert linter.is_message_enabled("W0113") + assert not linter.is_message_enabled("missing-docstring") + assert not linter.is_message_enabled("non-iterator-returned") + + +def test_enable_checkers(linter): + linter.disable("design") + assert not ("design" in [c.name for c in linter.prepare_checkers()]) + linter.enable("design") + assert "design" in [c.name for c in linter.prepare_checkers()] + + +def test_errors_only(linter): + linter.error_mode() + checkers = linter.prepare_checkers() + checker_names = {c.name for c in checkers} + should_not = {"design", "format", "metrics", "miscellaneous", "similarities"} + assert set() == should_not & checker_names + + +def test_disable_similar(linter): + linter.set_option("disable", "RP0801") + linter.set_option("disable", "R0801") + assert not ("similarities" in [c.name for c in linter.prepare_checkers()]) + + +def test_disable_alot(linter): + """check that we disabled a lot of checkers""" + linter.set_option("reports", False) + linter.set_option("disable", "R,C,W") + checker_names = [c.name for c in linter.prepare_checkers()] + for cname in ("design", "metrics", "similarities"): + assert not (cname in checker_names), cname + + +def test_addmessage(linter): + linter.set_reporter(testutils.TestReporter()) + linter.open() + linter.set_current_module("0123") + linter.add_message("C0301", line=1, args=(1, 2)) + linter.add_message("line-too-long", line=2, args=(3, 4)) + assert [ + "C: 1: Line too long (1/2)", + "C: 2: Line too long (3/4)", + ] == linter.reporter.messages + + +def test_addmessage_invalid(linter): + linter.set_reporter(testutils.TestReporter()) + linter.open() + linter.set_current_module("0123") + + with pytest.raises(InvalidMessageError) as cm: + linter.add_message("line-too-long", args=(1, 2)) + assert str(cm.value) == "Message C0301 must provide line, got None" + + with pytest.raises(InvalidMessageError) as cm: + linter.add_message("line-too-long", line=2, node="fake_node", args=(1, 2)) + assert ( + str(cm.value) + == "Message C0301 must only provide line, got line=2, node=fake_node" + ) + + with pytest.raises(InvalidMessageError) as cm: + linter.add_message("C0321") + assert str(cm.value) == "Message C0321 must provide Node, got None" + + +def test_init_hooks_called_before_load_plugins(): + with pytest.raises(RuntimeError): + Run(["--load-plugins", "unexistant", "--init-hook", "raise RuntimeError"]) + with pytest.raises(RuntimeError): + Run(["--init-hook", "raise RuntimeError", "--load-plugins", "unexistant"]) + + +def test_analyze_explicit_script(linter): + linter.set_reporter(testutils.TestReporter()) + linter.check(os.path.join(os.path.dirname(__file__), "data", "ascript")) + assert ["C: 2: Line too long (175/100)"] == linter.reporter.messages + + +def test_python3_checker_disabled(linter): + checker_names = [c.name for c in linter.prepare_checkers()] + assert "python3" not in checker_names + + linter.set_option("enable", "python3") + checker_names = [c.name for c in linter.prepare_checkers()] + assert "python3" in checker_names + + +def test_full_documentation(linter): + out = StringIO() + linter.print_full_documentation(out) + output = out.getvalue() + # A few spot checks only + for re_str in [ + # autogenerated text + "^Pylint global options and switches$", + "Verbatim name of the checker is ``python3``", + # messages + "^:old-octal-literal \\(E1608\\):", + # options + "^:dummy-variables-rgx:", + ]: + regexp = re.compile(re_str, re.MULTILINE) + assert re.search(regexp, output) + + +@pytest.fixture +def pop_pylintrc(): + os.environ.pop("PYLINTRC", None) + + +@pytest.mark.usefixtures("pop_pylintrc") +def test_pylint_home(): + uhome = os.path.expanduser("~") + if uhome == "~": + expected = ".pylint.d" + else: + expected = os.path.join(uhome, ".pylint.d") + assert config.PYLINT_HOME == expected + + try: + pylintd = join(tempfile.gettempdir(), ".pylint.d") + os.environ["PYLINTHOME"] = pylintd + try: + reload(config) + assert config.PYLINT_HOME == pylintd + finally: + try: + os.remove(pylintd) + except: + pass + finally: + del os.environ["PYLINTHOME"] + + +@pytest.mark.skipif( + PYPY_VERSION_INFO, + reason="TOX runs this test from within the repo and finds " + "the project's pylintrc.", +) +@pytest.mark.usefixtures("pop_pylintrc") +def test_pylintrc(): + with fake_home(): + current_dir = getcwd() + chdir(os.path.dirname(os.path.abspath(sys.executable))) + try: + assert config.find_pylintrc() is None + os.environ["PYLINTRC"] = join(tempfile.gettempdir(), ".pylintrc") + assert config.find_pylintrc() is None + os.environ["PYLINTRC"] = "." + assert config.find_pylintrc() is None + finally: + chdir(current_dir) + reload(config) + + +@pytest.mark.usefixtures("pop_pylintrc") +def test_pylintrc_parentdir(): + with tempdir() as chroot: + + create_files( + [ + "a/pylintrc", + "a/b/__init__.py", + "a/b/pylintrc", + "a/b/c/__init__.py", + "a/b/c/d/__init__.py", + "a/b/c/d/e/.pylintrc", + ] + ) + with fake_home(): + assert config.find_pylintrc() is None + results = { + "a": join(chroot, "a", "pylintrc"), + "a/b": join(chroot, "a", "b", "pylintrc"), + "a/b/c": join(chroot, "a", "b", "pylintrc"), + "a/b/c/d": join(chroot, "a", "b", "pylintrc"), + "a/b/c/d/e": join(chroot, "a", "b", "c", "d", "e", ".pylintrc"), + } + for basedir, expected in results.items(): + os.chdir(join(chroot, basedir)) + assert config.find_pylintrc() == expected + + +@pytest.mark.usefixtures("pop_pylintrc") +def test_pylintrc_parentdir_no_package(): + with tempdir() as chroot: + with fake_home(): + create_files(["a/pylintrc", "a/b/pylintrc", "a/b/c/d/__init__.py"]) + assert config.find_pylintrc() is None + results = { + "a": join(chroot, "a", "pylintrc"), + "a/b": join(chroot, "a", "b", "pylintrc"), + "a/b/c": None, + "a/b/c/d": None, + } + for basedir, expected in results.items(): + os.chdir(join(chroot, basedir)) + assert config.find_pylintrc() == expected + + +class TestPreprocessOptions(object): + def _callback(self, name, value): + self.args.append((name, value)) + + def test_value_equal(self): + self.args = [] + preprocess_options( + ["--foo", "--bar=baz", "--qu=ux"], + {"foo": (self._callback, False), "qu": (self._callback, True)}, + ) + assert [("foo", None), ("qu", "ux")] == self.args + + def test_value_space(self): + self.args = [] + preprocess_options(["--qu", "ux"], {"qu": (self._callback, True)}) + assert [("qu", "ux")] == self.args + + def test_error_missing_expected_value(self): + with pytest.raises(ArgumentPreprocessingError): + preprocess_options(["--foo", "--bar", "--qu=ux"], {"bar": (None, True)}) + with pytest.raises(ArgumentPreprocessingError): + preprocess_options(["--foo", "--bar"], {"bar": (None, True)}) + + def test_error_unexpected_value(self): + with pytest.raises(ArgumentPreprocessingError): + preprocess_options( + ["--foo", "--bar=spam", "--qu=ux"], {"bar": (None, False)} + ) + + +@pytest.fixture +def store(): + store = MessagesStore() + + class Checker(object): + name = "achecker" + msgs = { + "W1234": ( + "message", + "msg-symbol", + "msg description.", + {"old_names": [("W0001", "old-symbol")]}, + ), + "E1234": ( + "Duplicate keyword argument %r in %s call", + "duplicate-keyword-arg", + "Used when a function call passes the same keyword argument multiple times.", + {"maxversion": (2, 6)}, + ), + } + + store.register_messages(Checker()) + return store + + +class TestMessagesStore(object): + def _compare_messages(self, desc, msg, checkerref=False): + assert desc == msg.format_help(checkerref=checkerref) + + def test_check_message_id(self, store): + assert isinstance(store.get_message_definition("W1234"), MessageDefinition) + with pytest.raises(UnknownMessageError): + store.get_message_definition("YB12") + + def test_message_help(self, store): + msg = store.get_message_definition("W1234") + self._compare_messages( + """:msg-symbol (W1234): *message* + msg description. This message belongs to the achecker checker.""", + msg, + checkerref=True, + ) + self._compare_messages( + """:msg-symbol (W1234): *message* + msg description.""", + msg, + checkerref=False, + ) + + def test_message_help_minmax(self, store): + # build the message manually to be python version independent + msg = store.get_message_definition("E1234") + self._compare_messages( + """:duplicate-keyword-arg (E1234): *Duplicate keyword argument %r in %s call* + Used when a function call passes the same keyword argument multiple times. + This message belongs to the achecker checker. It can't be emitted when using + Python >= 2.6.""", + msg, + checkerref=True, + ) + self._compare_messages( + """:duplicate-keyword-arg (E1234): *Duplicate keyword argument %r in %s call* + Used when a function call passes the same keyword argument multiple times. + This message can't be emitted when using Python >= 2.6.""", + msg, + checkerref=False, + ) + + def test_list_messages(self, store): + output = StringIO() + with redirect_stdout(output): + store.list_messages() + # cursory examination of the output: we're mostly testing it completes + assert ":msg-symbol (W1234): *message*" in output.getvalue() + + def test_add_renamed_message(self, store): + store.add_renamed_message("W1234", "old-bad-name", "msg-symbol") + assert "msg-symbol" == store.get_message_definition("W1234").symbol + assert "msg-symbol" == store.get_message_definition("old-bad-name").symbol + + def test_add_renamed_message_invalid(self, store): + # conflicting message ID + with pytest.raises(InvalidMessageError) as cm: + store.add_renamed_message( + "W1234", "old-msg-symbol", "duplicate-keyword-arg" + ) + expected = ( + "Message id 'W1234' cannot have both 'msg-symbol' and 'old-msg-symbol' " + "as symbolic name." + ) + assert str(cm.value) == expected + + def test_renamed_message_register(self, store): + assert "msg-symbol" == store.get_message_definition("W0001").symbol + assert "msg-symbol" == store.get_message_definition("old-symbol").symbol + + +def test_custom_should_analyze_file(): + """Check that we can write custom should_analyze_file that work + even for arguments. + """ + + class CustomPyLinter(PyLinter): + def should_analyze_file(self, modname, path, is_argument=False): + if os.path.basename(path) == "wrong.py": + return False + + return super(CustomPyLinter, self).should_analyze_file( + modname, path, is_argument=is_argument + ) + + package_dir = os.path.join(HERE, "regrtest_data", "bad_package") + wrong_file = os.path.join(package_dir, "wrong.py") + + for jobs in [1, 2]: + reporter = testutils.TestReporter() + linter = CustomPyLinter() + linter.config.jobs = jobs + linter.config.persistent = 0 + linter.open() + linter.set_reporter(reporter) + + try: + sys.path.append(os.path.dirname(package_dir)) + linter.check([package_dir, wrong_file]) + finally: + sys.path.pop() + + messages = reporter.messages + assert len(messages) == 1 + assert "invalid syntax" in messages[0] + + +def test_filename_with__init__(init_linter): + # This tracks a regression where a file whose name ends in __init__.py, + # such as flycheck__init__.py, would accidentally lead to linting the + # entire containing directory. + reporter = testutils.TestReporter() + linter = init_linter + linter.open() + linter.set_reporter(reporter) + filepath = join(INPUTDIR, "not__init__.py") + linter.check([filepath]) + messages = reporter.messages + assert len(messages) == 0 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_diadefs.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_diadefs.py new file mode 100644 index 0000000..6414979 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_diadefs.py @@ -0,0 +1,177 @@ +# Copyright (c) 2008-2010, 2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" +unit test for the extensions.diadefslib modules +""" + +import pytest + +import astroid + +from pylint.pyreverse.inspector import Linker +from pylint.pyreverse.diadefslib import * + +from unittest_pyreverse_writer import Config, get_project + + +def _process_classes(classes): + """extract class names of a list""" + return sorted([(isinstance(c.node, astroid.ClassDef), c.title) for c in classes]) + + +def _process_relations(relations): + """extract relation indices from a relation list""" + result = [] + for rel_type, rels in relations.items(): + for rel in rels: + result.append((rel_type, rel.from_object.title, rel.to_object.title)) + result.sort() + return result + + +@pytest.fixture +def HANDLER(): + return DiadefsHandler(Config()) + + +@pytest.fixture(scope="module") +def PROJECT(): + return get_project("data") + + +def test_option_values(HANDLER, PROJECT): + """test for ancestor, associated and module options""" + df_h = DiaDefGenerator(Linker(PROJECT), HANDLER) + cl_config = Config() + cl_config.classes = ["Specialization"] + cl_h = DiaDefGenerator(Linker(PROJECT), DiadefsHandler(cl_config)) + assert (0, 0) == df_h._get_levels() + assert False == df_h.module_names + assert (-1, -1) == cl_h._get_levels() + assert True == cl_h.module_names + for hndl in [df_h, cl_h]: + hndl.config.all_ancestors = True + hndl.config.all_associated = True + hndl.config.module_names = True + hndl._set_default_options() + assert (-1, -1) == hndl._get_levels() + assert True == hndl.module_names + handler = DiadefsHandler(Config()) + df_h = DiaDefGenerator(Linker(PROJECT), handler) + cl_config = Config() + cl_config.classes = ["Specialization"] + cl_h = DiaDefGenerator(Linker(PROJECT), DiadefsHandler(cl_config)) + for hndl in [df_h, cl_h]: + hndl.config.show_ancestors = 2 + hndl.config.show_associated = 1 + hndl.config.module_names = False + hndl._set_default_options() + assert (2, 1) == hndl._get_levels() + assert False == hndl.module_names + + # def test_default_values(): + """test efault values for package or class diagrams""" + # TODO : should test difference between default values for package + # or class diagrams + + +class TestDefaultDiadefGenerator(object): + def test_known_values1(self, HANDLER, PROJECT): + dd = DefaultDiadefGenerator(Linker(PROJECT), HANDLER).visit(PROJECT) + assert len(dd) == 2 + keys = [d.TYPE for d in dd] + assert keys == ["package", "class"] + pd = dd[0] + assert pd.title == "packages No Name" + modules = sorted( + [(isinstance(m.node, astroid.Module), m.title) for m in pd.objects] + ) + assert modules == [ + (True, "data"), + (True, "data.clientmodule_test"), + (True, "data.suppliermodule_test"), + ] + cd = dd[1] + assert cd.title == "classes No Name" + classes = _process_classes(cd.objects) + assert classes == [ + (True, "Ancestor"), + (True, "DoNothing"), + (True, "Interface"), + (True, "Specialization"), + ] + + _should_rels = [ + ("association", "DoNothing", "Ancestor"), + ("association", "DoNothing", "Specialization"), + ("implements", "Ancestor", "Interface"), + ("specialization", "Specialization", "Ancestor"), + ] + + def test_exctract_relations(self, HANDLER, PROJECT): + """test extract_relations between classes""" + cd = DefaultDiadefGenerator(Linker(PROJECT), HANDLER).visit(PROJECT)[1] + cd.extract_relationships() + relations = _process_relations(cd.relationships) + assert relations == self._should_rels + + def test_functional_relation_extraction(self): + """functional test of relations extraction; + different classes possibly in different modules""" + # XXX should be catching pyreverse environnement problem but doesn't + # pyreverse doesn't extracts the relations but this test ok + project = get_project("data") + handler = DiadefsHandler(Config()) + diadefs = handler.get_diadefs(project, Linker(project, tag=True)) + cd = diadefs[1] + relations = _process_relations(cd.relationships) + assert relations == self._should_rels + + def test_known_values2(self, HANDLER): + project = get_project("data.clientmodule_test") + dd = DefaultDiadefGenerator(Linker(project), HANDLER).visit(project) + assert len(dd) == 1 + keys = [d.TYPE for d in dd] + assert keys == ["class"] + cd = dd[0] + assert cd.title == "classes No Name" + classes = _process_classes(cd.objects) + assert classes == [(True, "Ancestor"), (True, "Specialization")] + + +def test_known_values1(HANDLER, PROJECT): + HANDLER.config.classes = ["Specialization"] + cdg = ClassDiadefGenerator(Linker(PROJECT), HANDLER) + special = "data.clientmodule_test.Specialization" + cd = cdg.class_diagram(PROJECT, special) + assert cd.title == special + classes = _process_classes(cd.objects) + assert classes == [ + (True, "data.clientmodule_test.Ancestor"), + (True, special), + (True, "data.suppliermodule_test.DoNothing"), + ] + + +def test_known_values2(HANDLER, PROJECT): + HANDLER.config.classes = ["Specialization"] + HANDLER.config.module_names = False + cd = ClassDiadefGenerator(Linker(PROJECT), HANDLER).class_diagram( + PROJECT, "data.clientmodule_test.Specialization" + ) + assert cd.title == "data.clientmodule_test.Specialization" + classes = _process_classes(cd.objects) + assert classes == [ + (True, "Ancestor"), + (True, "DoNothing"), + (True, "Specialization"), + ] diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_inspector.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_inspector.py new file mode 100644 index 0000000..f87bddb --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_inspector.py @@ -0,0 +1,125 @@ +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" + for the visitors.diadefs module +""" +import os + +import pytest + +import astroid +from astroid import nodes +from astroid import bases + +from pylint.pyreverse import inspector +from unittest_pyreverse_writer import get_project + + +@pytest.fixture +def project(): + project = get_project("data", "data") + linker = inspector.Linker(project) + linker.visit(project) + return project + + +def test_class_implements(project): + klass = project.get_module("data.clientmodule_test")["Ancestor"] + assert hasattr(klass, "implements") + assert len(klass.implements) == 1 + assert isinstance(klass.implements[0], nodes.ClassDef) + assert klass.implements[0].name == "Interface" + + +def test_class_implements_specialization(project): + klass = project.get_module("data.clientmodule_test")["Specialization"] + assert hasattr(klass, "implements") + assert len(klass.implements) == 0 + + +def test_locals_assignment_resolution(project): + klass = project.get_module("data.clientmodule_test")["Specialization"] + assert hasattr(klass, "locals_type") + type_dict = klass.locals_type + assert len(type_dict) == 2 + keys = sorted(type_dict.keys()) + assert keys == ["TYPE", "top"] + assert len(type_dict["TYPE"]) == 1 + assert type_dict["TYPE"][0].value == "final class" + assert len(type_dict["top"]) == 1 + assert type_dict["top"][0].value == "class" + + +def test_instance_attrs_resolution(project): + klass = project.get_module("data.clientmodule_test")["Specialization"] + assert hasattr(klass, "instance_attrs_type") + type_dict = klass.instance_attrs_type + assert len(type_dict) == 2 + keys = sorted(type_dict.keys()) + assert keys == ["_id", "relation"] + assert isinstance(type_dict["relation"][0], bases.Instance), type_dict["relation"] + assert type_dict["relation"][0].name == "DoNothing" + assert type_dict["_id"][0] is astroid.Uninferable + + +def test_concat_interfaces(): + cls = astroid.extract_node( + ''' + class IMachin: pass + + class Correct2: + """docstring""" + __implements__ = (IMachin,) + + class BadArgument: + """docstring""" + __implements__ = (IMachin,) + + class InterfaceCanNowBeFound: #@ + """docstring""" + __implements__ = BadArgument.__implements__ + Correct2.__implements__ + ''' + ) + interfaces = inspector.interfaces(cls) + assert [i.name for i in interfaces] == ["IMachin"] + + +def test_interfaces(): + module = astroid.parse( + """ + class Interface(object): pass + class MyIFace(Interface): pass + class AnotherIFace(Interface): pass + class Concrete0(object): + __implements__ = MyIFace + class Concrete1: + __implements__ = (MyIFace, AnotherIFace) + class Concrete2: + __implements__ = (MyIFace, AnotherIFace) + class Concrete23(Concrete1): pass + """ + ) + + for klass, interfaces in ( + ("Concrete0", ["MyIFace"]), + ("Concrete1", ["MyIFace", "AnotherIFace"]), + ("Concrete2", ["MyIFace", "AnotherIFace"]), + ("Concrete23", ["MyIFace", "AnotherIFace"]), + ): + klass = module[klass] + assert [i.name for i in inspector.interfaces(klass)] == interfaces + + +def test_from_directory(project): + expected = os.path.join("pylint", "test", "data", "__init__.py") + assert project.name == "data" + assert project.path.endswith(expected) + + +def test_project_node(project): + expected = ["data", "data.clientmodule_test", "data.suppliermodule_test"] + assert sorted(project.keys()) == expected diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_writer.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_writer.py new file mode 100644 index 0000000..cf2e915 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_pyreverse_writer.py @@ -0,0 +1,136 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2008, 2010, 2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +""" +unit test for visitors.diadefs and extensions.diadefslib modules +""" + + +import os +import codecs +from difflib import unified_diff + +import pytest + +from pylint.pyreverse.inspector import Linker, project_from_files +from pylint.pyreverse.diadefslib import DefaultDiadefGenerator, DiadefsHandler +from pylint.pyreverse.writer import DotWriter +from pylint.pyreverse.utils import get_visibility + + +_DEFAULTS = { + "all_ancestors": None, + "show_associated": None, + "module_names": None, + "output_format": "dot", + "diadefs_file": None, + "quiet": 0, + "show_ancestors": None, + "classes": (), + "all_associated": None, + "mode": "PUB_ONLY", + "show_builtin": False, + "only_classnames": False, +} + + +class Config(object): + """config object for tests""" + + def __init__(self): + for attr, value in _DEFAULTS.items(): + setattr(self, attr, value) + + +def _file_lines(path): + # we don't care about the actual encoding, but python3 forces us to pick one + with codecs.open(path, encoding="latin1") as stream: + lines = [ + line.strip() + for line in stream.readlines() + if ( + line.find("squeleton generated by ") == -1 + and not line.startswith('__revision__ = "$Id:') + ) + ] + return [line for line in lines if line] + + +def get_project(module, name="No Name"): + """return an astroid project representation""" + + def _astroid_wrapper(func, modname): + return func(modname) + + return project_from_files([module], _astroid_wrapper, project_name=name) + + +DOT_FILES = ["packages_No_Name.dot", "classes_No_Name.dot"] + + +@pytest.fixture(scope="module") +def setup(): + project = get_project(os.path.join(os.path.dirname(__file__), "data")) + linker = Linker(project) + CONFIG = Config() + handler = DiadefsHandler(CONFIG) + dd = DefaultDiadefGenerator(linker, handler).visit(project) + for diagram in dd: + diagram.extract_relationships() + writer = DotWriter(CONFIG) + writer.write(dd) + yield + for fname in DOT_FILES: + try: + os.remove(fname) + except: + continue + + +@pytest.mark.usefixtures("setup") +@pytest.mark.parametrize("generated_file", DOT_FILES) +def test_dot_files(generated_file): + expected_file = os.path.join(os.path.dirname(__file__), "data", generated_file) + generated = _file_lines(generated_file) + expected = _file_lines(expected_file) + generated = "\n".join(generated) + expected = "\n".join(expected) + files = "\n *** expected : %s, generated : %s \n" % (expected_file, generated_file) + assert expected == generated, "%s%s" % ( + files, + "\n".join( + line for line in unified_diff(expected.splitlines(), generated.splitlines()) + ), + ) + os.remove(generated_file) + + +@pytest.mark.parametrize( + "names, expected", + [ + (["__reduce_ex__", "__setattr__"], "special"), + (["__g_", "____dsf", "__23_9"], "private"), + (["simple"], "public"), + ( + ["_", "__", "___", "____", "_____", "___e__", "_nextsimple", "_filter_it_"], + "protected", + ), + ], +) +def test_get_visibility(names, expected): + for name in names: + got = get_visibility(name) + assert got == expected, "got %s instead of %s for value %s" % ( + got, + expected, + name, + ) diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_reporters_json.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_reporters_json.py new file mode 100644 index 0000000..ba78538 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_reporters_json.py @@ -0,0 +1,53 @@ +# Copyright (c) 2014 Vlad Temian <vladtemian@gmail.com> +# Copyright (c) 2015-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2017 guillaume2 <guillaume.peillex@gmail.col> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""Test for the JSON reporter.""" + +import json + +from io import StringIO + +from pylint.lint import PyLinter +from pylint import checkers +from pylint.reporters.json import JSONReporter + + +def test_simple_json_output(): + output = StringIO() + + reporter = JSONReporter() + linter = PyLinter(reporter=reporter) + checkers.initialize(linter) + + linter.config.persistent = 0 + linter.reporter.set_output(output) + linter.open() + linter.set_current_module("0123") + linter.add_message("line-too-long", line=1, args=(1, 2)) + + # we call this method because we didn't actually run the checkers + reporter.display_messages(None) + + expected_result = [ + [ + ("column", 0), + ("line", 1), + ("message", "Line too long (1/2)"), + ("message-id", "C0301"), + ("module", "0123"), + ("obj", ""), + ("path", "0123"), + ("symbol", "line-too-long"), + ("type", "convention"), + ] + ] + report_result = json.loads(output.getvalue()) + report_result = [sorted(report_result[0].items(), key=lambda item: item[0])] + assert report_result == expected_result diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_reporting.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_reporting.py new file mode 100644 index 0000000..88f2ce4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_reporting.py @@ -0,0 +1,81 @@ +# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014 Calin Don <calin.don@gmail.com> +# Copyright (c) 2014 Google, Inc. +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016-2017 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import warnings + +from io import StringIO + +from pylint.lint import PyLinter +from pylint import checkers +from pylint.reporters.text import TextReporter, ParseableTextReporter +import pytest + + +@pytest.fixture(scope="module") +def reporter(reporter): + return TextReporter + + +@pytest.fixture(scope="module") +def disable(disable): + return ["I"] + + +def test_template_option(linter): + output = StringIO() + linter.reporter.set_output(output) + linter.set_option("msg-template", "{msg_id}:{line:03d}") + linter.open() + linter.set_current_module("0123") + linter.add_message("C0301", line=1, args=(1, 2)) + linter.add_message("line-too-long", line=2, args=(3, 4)) + assert ( + output.getvalue() == "************* Module 0123\n" "C0301:001\n" "C0301:002\n" + ) + + +def test_parseable_output_deprecated(): + with warnings.catch_warnings(record=True) as cm: + warnings.simplefilter("always") + ParseableTextReporter() + + assert len(cm) == 1 + assert isinstance(cm[0].message, DeprecationWarning) + + +def test_parseable_output_regression(): + output = StringIO() + with warnings.catch_warnings(record=True): + linter = PyLinter(reporter=ParseableTextReporter()) + + checkers.initialize(linter) + linter.config.persistent = 0 + linter.reporter.set_output(output) + linter.set_option("output-format", "parseable") + linter.open() + linter.set_current_module("0123") + linter.add_message("line-too-long", line=1, args=(1, 2)) + assert ( + output.getvalue() == "************* Module 0123\n" + "0123:1: [C0301(line-too-long), ] " + "Line too long (1/2)\n" + ) + + +def test_display_results_is_renamed(): + class CustomReporter(TextReporter): + def _display(self, layout): + return None + + reporter = CustomReporter() + with pytest.raises(AttributeError): + reporter.display_results diff --git a/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_utils.py b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_utils.py new file mode 100644 index 0000000..7bdf502 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/test/unittest_utils.py @@ -0,0 +1,453 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2015 Aru Sahni <arusahni@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2017-2018 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2017 Pierre Sassoulas <pierre.sassoulas@cea.fr> +# Copyright (c) 2017 ttenhoeve-aa <ttenhoeve@appannie.com> +# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2018 Pierre Sassoulas <pierre.sassoulas@wisebim.fr> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +import io +import re +import warnings + +import astroid + +from pylint import utils +from pylint.checkers.utils import check_messages, get_node_last_lineno +from pylint.exceptions import InvalidMessageError +import pytest + + +class TestPyLintASTWalker(object): + class MockLinter(object): + def __init__(self, msgs): + self._msgs = msgs + + def is_message_enabled(self, msgid): + return self._msgs.get(msgid, True) + + class Checker(object): + def __init__(self): + self.called = set() + + @check_messages("first-message") + def visit_module(self, module): + self.called.add("module") + + @check_messages("second-message") + def visit_call(self, module): + raise NotImplementedError + + @check_messages("second-message", "third-message") + def visit_assignname(self, module): + self.called.add("assignname") + + @check_messages("second-message") + def leave_assignname(self, module): + raise NotImplementedError + + def test_check_messages(self): + linter = self.MockLinter( + {"first-message": True, "second-message": False, "third-message": True} + ) + walker = utils.PyLintASTWalker(linter) + checker = self.Checker() + walker.add_checker(checker) + walker.walk(astroid.parse("x = func()")) + assert {"module", "assignname"} == checker.called + + def test_deprecated_methods(self): + class Checker(object): + def __init__(self): + self.called = False + + @check_messages("first-message") + def visit_assname(self, node): + self.called = True + + linter = self.MockLinter({"first-message": True}) + walker = utils.PyLintASTWalker(linter) + checker = Checker() + walker.add_checker(checker) + with warnings.catch_warnings(record=True): + warnings.simplefilter("always") + walker.walk(astroid.parse("x = 1")) + + assert not checker.called + + +def test__basename_in_blacklist_re_match(): + patterns = [re.compile(".*enchilada.*"), re.compile("unittest_.*")] + assert utils._basename_in_blacklist_re("unittest_utils.py", patterns) + assert utils._basename_in_blacklist_re("cheese_enchiladas.xml", patterns) + + +def test__basename_in_blacklist_re_nomatch(): + patterns = [re.compile(".*enchilada.*"), re.compile("unittest_.*")] + assert not utils._basename_in_blacklist_re("test_utils.py", patterns) + assert not utils._basename_in_blacklist_re("enchilad.py", patterns) + + +@pytest.fixture +def store(): + return utils.MessagesStore() + + +@pytest.mark.parametrize( + "messages,expected", + [ + ( + { + "W1234": ("message one", "msg-symbol-one", "msg description"), + "W4321": ("message two", "msg-symbol-two", "msg description"), + }, + r"Inconsistent checker part in message id 'W4321' (expected 'x12xx' because we already had ['W1234']).", + ), + ( + { + "W1233": ( + "message two", + "msg-symbol-two", + "msg description", + {"old_names": [("W1234", "old-symbol")]}, + ), + "W1234": ("message one", "msg-symbol-one", "msg description"), + }, + "Message id 'W1234' cannot have both 'old-symbol' and 'msg-symbol-one' as symbolic name.", + ), + ( + { + "W1234": ("message one", "msg-symbol-one", "msg description"), + "W1235": ( + "message two", + "msg-symbol-two", + "msg description", + {"old_names": [("W1234", "old-symbol")]}, + ), + }, + "Message id 'W1234' cannot have both 'msg-symbol-one' and 'old-symbol' as symbolic name.", + ), + ( + { + "W1234": ( + "message one", + "msg-symbol-one", + "msg description", + {"old_names": [("W1201", "old-symbol-one")]}, + ), + "W1235": ( + "message two", + "msg-symbol-two", + "msg description", + {"old_names": [("W1201", "old-symbol-two")]}, + ), + }, + "Message id 'W1201' cannot have both 'old-symbol-one' and 'old-symbol-two' as symbolic name.", + ), + ( + { + "W1234": ("message one", "msg-symbol", "msg description"), + "W1235": ("message two", "msg-symbol", "msg description"), + }, + "Message symbol 'msg-symbol' cannot be used for 'W1234' and 'W1235' at the same time.", + ), + ( + { + "W1233": ( + "message two", + "msg-symbol-two", + "msg description", + {"old_names": [("W1230", "msg-symbol-one")]}, + ), + "W1234": ("message one", "msg-symbol-one", "msg description"), + }, + "Message symbol 'msg-symbol-one' cannot be used for 'W1230' and 'W1234' at the same time.", + ), + ( + { + "W1234": ("message one", "msg-symbol-one", "msg description"), + "W1235": ( + "message two", + "msg-symbol-two", + "msg description", + {"old_names": [("W1230", "msg-symbol-one")]}, + ), + }, + "Message symbol 'msg-symbol-one' cannot be used for 'W1234' and 'W1235' at the same time.", + ), + ( + { + "W1234": ( + "message one", + "msg-symbol-one", + "msg description", + {"old_names": [("W1230", "old-symbol-one")]}, + ), + "W1235": ( + "message two", + "msg-symbol-two", + "msg description", + {"old_names": [("W1231", "old-symbol-one")]}, + ), + }, + "Message symbol 'old-symbol-one' cannot be used for 'W1230' and 'W1235' at the same time.", + ), + ], +) +def test_register_error(store, messages, expected): + class Checker(object): + name = "checker" + msgs = messages + + with pytest.raises(InvalidMessageError) as cm: + store.register_messages(Checker()) + assert str(cm.value) == expected + + +def test_register_error_new_id_duplicate_of_new(store): + class CheckerOne(object): + name = "checker_one" + msgs = {"W1234": ("message one", "msg-symbol-one", "msg description.")} + + class CheckerTwo(object): + name = "checker_two" + msgs = {"W1234": ("message two", "msg-symbol-two", "another msg description.")} + + store.register_messages(CheckerOne()) + test_register_error( + store, + {"W1234": ("message two", "msg-symbol-two", "another msg description.")}, + "Message id 'W1234' cannot have both 'msg-symbol-one' and 'msg-symbol-two' as symbolic name.", + ) + + +@pytest.mark.parametrize( + "msgid,expected", + [ + ("Q1234", "Bad message type Q in 'Q1234'"), + ("W12345", "Invalid message id 'W12345'"), + ], +) +def test_create_invalid_message_type(msgid, expected): + with pytest.raises(InvalidMessageError) as cm: + utils.MessageDefinition("checker", msgid, "msg", "descr", "symbol", "scope") + assert str(cm.value) == expected + + +def test_decoding_stream_unknown_encoding(): + """decoding_stream should fall back to *some* decoding when given an + unknown encoding. + """ + binary_io = io.BytesIO(b"foo\nbar") + stream = utils.decoding_stream(binary_io, "garbage-encoding") + # should still act like a StreamReader + ret = stream.readlines() + assert ret == ["foo\n", "bar"] + + +def test_decoding_stream_known_encoding(): + binary_io = io.BytesIO("€".encode("cp1252")) + stream = utils.decoding_stream(binary_io, "cp1252") + assert stream.read() == "€" + + +class TestGetNodeLastLineno: + def test_get_node_last_lineno_simple(self): + node = astroid.extract_node( + """ + pass + """ + ) + assert get_node_last_lineno(node) == 2 + + def test_get_node_last_lineno_if_simple(self): + node = astroid.extract_node( + """ + if True: + print(1) + pass + """ + ) + assert get_node_last_lineno(node) == 4 + + def test_get_node_last_lineno_if_elseif_else(self): + node = astroid.extract_node( + """ + if True: + print(1) + elif False: + print(2) + else: + print(3) + """ + ) + assert get_node_last_lineno(node) == 7 + + def test_get_node_last_lineno_while(self): + node = astroid.extract_node( + """ + while True: + print(1) + """ + ) + assert get_node_last_lineno(node) == 3 + + def test_get_node_last_lineno_while_else(self): + node = astroid.extract_node( + """ + while True: + print(1) + else: + print(2) + """ + ) + assert get_node_last_lineno(node) == 5 + + def test_get_node_last_lineno_for(self): + node = astroid.extract_node( + """ + for x in range(0, 5): + print(1) + """ + ) + assert get_node_last_lineno(node) == 3 + + def test_get_node_last_lineno_for_else(self): + node = astroid.extract_node( + """ + for x in range(0, 5): + print(1) + else: + print(2) + """ + ) + assert get_node_last_lineno(node) == 5 + + def test_get_node_last_lineno_try(self): + node = astroid.extract_node( + """ + try: + print(1) + except ValueError: + print(2) + except Exception: + print(3) + """ + ) + assert get_node_last_lineno(node) == 7 + + def test_get_node_last_lineno_try_except_else(self): + node = astroid.extract_node( + """ + try: + print(1) + except Exception: + print(2) + print(3) + else: + print(4) + """ + ) + assert get_node_last_lineno(node) == 8 + + def test_get_node_last_lineno_try_except_finally(self): + node = astroid.extract_node( + """ + try: + print(1) + except Exception: + print(2) + finally: + print(4) + """ + ) + assert get_node_last_lineno(node) == 7 + + def test_get_node_last_lineno_try_except_else_finally(self): + node = astroid.extract_node( + """ + try: + print(1) + except Exception: + print(2) + else: + print(3) + finally: + print(4) + """ + ) + assert get_node_last_lineno(node) == 9 + + def test_get_node_last_lineno_with(self): + node = astroid.extract_node( + """ + with x as y: + print(1) + pass + """ + ) + assert get_node_last_lineno(node) == 4 + + def test_get_node_last_lineno_method(self): + node = astroid.extract_node( + """ + def x(a, b): + print(a, b) + pass + """ + ) + assert get_node_last_lineno(node) == 4 + + def test_get_node_last_lineno_decorator(self): + node = astroid.extract_node( + """ + @decor() + def x(a, b): + print(a, b) + pass + """ + ) + assert get_node_last_lineno(node) == 5 + + def test_get_node_last_lineno_class(self): + node = astroid.extract_node( + """ + class C(object): + CONST = True + + def x(self, b): + print(b) + + def y(self): + pass + pass + """ + ) + assert get_node_last_lineno(node) == 10 + + def test_get_node_last_lineno_combined(self): + node = astroid.extract_node( + """ + class C(object): + CONST = True + + def y(self): + try: + pass + except: + pass + finally: + pass + """ + ) + assert get_node_last_lineno(node) == 11 diff --git a/basic python programmes/venv/Lib/site-packages/pylint/testutils.py b/basic python programmes/venv/Lib/site-packages/pylint/testutils.py new file mode 100644 index 0000000..f22b897 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/testutils.py @@ -0,0 +1,305 @@ +# Copyright (c) 2012-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com> +# Copyright (c) 2013-2017 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2013-2014 Google, Inc. +# Copyright (c) 2013 buck@yelp.com <buck@yelp.com> +# Copyright (c) 2014 LCD 47 <lcd047@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Ricardo Gemignani <ricardo.gemignani@gmail.com> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2015 Pavel Roskin <proski@gnu.org> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com> +# Copyright (c) 2016 Roy Williams <roy.williams.iii@gmail.com> +# Copyright (c) 2016 xmo-odoo <xmo-odoo@users.noreply.github.com> +# Copyright (c) 2017 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""functional/non regression tests for pylint""" +from __future__ import print_function + +import collections +import contextlib +import functools +from glob import glob +import os +from os import linesep, getcwd, sep +from os.path import abspath, basename, dirname, join, splitext +import sys +import tempfile +import tokenize + +from io import StringIO + +import astroid +from pylint import checkers +from pylint.utils import PyLintASTWalker +from pylint.reporters import BaseReporter +from pylint.interfaces import IReporter +from pylint.lint import PyLinter + +# Utils + +SYS_VERS_STR = "%d%d%d" % sys.version_info[:3] +TITLE_UNDERLINES = ["", "=", "-", "."] +PREFIX = abspath(dirname(__file__)) +PY3K = sys.version_info[0] == 3 + + +def _get_tests_info(input_dir, msg_dir, prefix, suffix): + """get python input examples and output messages + + We use following conventions for input files and messages: + for different inputs: + test for python >= x.y -> input = <name>_pyxy.py + test for python < x.y -> input = <name>_py_xy.py + for one input and different messages: + message for python >= x.y -> message = <name>_pyxy.txt + lower versions -> message with highest num + """ + result = [] + for fname in glob(join(input_dir, prefix + "*" + suffix)): + infile = basename(fname) + fbase = splitext(infile)[0] + # filter input files : + pyrestr = fbase.rsplit("_py", 1)[-1] # like _26 or 26 + if pyrestr.isdigit(): # '24', '25'... + if SYS_VERS_STR < pyrestr: + continue + if pyrestr.startswith("_") and pyrestr[1:].isdigit(): + # skip test for higher python versions + if SYS_VERS_STR >= pyrestr[1:]: + continue + messages = glob(join(msg_dir, fbase + "*.txt")) + # the last one will be without ext, i.e. for all or upper versions: + if messages: + for outfile in sorted(messages, reverse=True): + py_rest = outfile.rsplit("_py", 1)[-1][:-4] + if py_rest.isdigit() and SYS_VERS_STR >= py_rest: + break + else: + # This will provide an error message indicating the missing filename. + outfile = join(msg_dir, fbase + ".txt") + result.append((infile, outfile)) + return result + + +class TestReporter(BaseReporter): + """reporter storing plain text messages""" + + __implements__ = IReporter + + def __init__(self): # pylint: disable=super-init-not-called + + self.message_ids = {} + self.reset() + self.path_strip_prefix = getcwd() + sep + + def reset(self): + self.out = StringIO() + self.messages = [] + + def handle_message(self, msg): + """manage message of different type and in the context of path """ + obj = msg.obj + line = msg.line + msg_id = msg.msg_id + msg = msg.msg + self.message_ids[msg_id] = 1 + if obj: + obj = ":%s" % obj + sigle = msg_id[0] + if PY3K and linesep != "\n": + # 2to3 writes os.linesep instead of using + # the previosly used line separators + msg = msg.replace("\r\n", "\n") + self.messages.append("%s:%3s%s: %s" % (sigle, line, obj, msg)) + + def finalize(self): + self.messages.sort() + for msg in self.messages: + print(msg, file=self.out) + result = self.out.getvalue() + self.reset() + return result + + # pylint: disable=unused-argument + def on_set_current_module(self, module, filepath): + pass + + # pylint: enable=unused-argument + + def display_reports(self, layout): + """ignore layouts""" + + _display = None + + +class MinimalTestReporter(BaseReporter): + def handle_message(self, msg): + self.messages.append(msg) + + def on_set_current_module(self, module, filepath): + self.messages = [] + + _display = None + + +class Message( + collections.namedtuple("Message", ["msg_id", "line", "node", "args", "confidence"]) +): + def __new__(cls, msg_id, line=None, node=None, args=None, confidence=None): + return tuple.__new__(cls, (msg_id, line, node, args, confidence)) + + def __eq__(self, other): + if isinstance(other, Message): + if self.confidence and other.confidence: + return super(Message, self).__eq__(other) + return self[:-1] == other[:-1] + return NotImplemented # pragma: no cover + + __hash__ = None + + +class UnittestLinter: + """A fake linter class to capture checker messages.""" + + # pylint: disable=unused-argument, no-self-use + + def __init__(self): + self._messages = [] + self.stats = {} + + def release_messages(self): + try: + return self._messages + finally: + self._messages = [] + + def add_message( + self, msg_id, line=None, node=None, args=None, confidence=None, col_offset=None + ): + # Do not test col_offset for now since changing Message breaks everything + self._messages.append(Message(msg_id, line, node, args, confidence)) + + def is_message_enabled(self, *unused_args, **unused_kwargs): + return True + + def add_stats(self, **kwargs): + for name, value in kwargs.items(): + self.stats[name] = value + return self.stats + + @property + def options_providers(self): + return linter.options_providers + + +def set_config(**kwargs): + """Decorator for setting config values on a checker.""" + + def _wrapper(fun): + @functools.wraps(fun) + def _forward(self): + for key, value in kwargs.items(): + setattr(self.checker.config, key, value) + if isinstance(self, CheckerTestCase): + # reopen checker in case, it may be interested in configuration change + self.checker.open() + fun(self) + + return _forward + + return _wrapper + + +class CheckerTestCase: + """A base testcase class for unit testing individual checker classes.""" + + CHECKER_CLASS = None + CONFIG = {} + + def setup_method(self): + self.linter = UnittestLinter() + self.checker = self.CHECKER_CLASS(self.linter) # pylint: disable=not-callable + for key, value in self.CONFIG.items(): + setattr(self.checker.config, key, value) + self.checker.open() + + @contextlib.contextmanager + def assertNoMessages(self): + """Assert that no messages are added by the given method.""" + with self.assertAddsMessages(): + yield + + @contextlib.contextmanager + def assertAddsMessages(self, *messages): + """Assert that exactly the given method adds the given messages. + + The list of messages must exactly match *all* the messages added by the + method. Additionally, we check to see whether the args in each message can + actually be substituted into the message string. + """ + yield + got = self.linter.release_messages() + msg = "Expected messages did not match actual.\n" "Expected:\n%s\nGot:\n%s" % ( + "\n".join(repr(m) for m in messages), + "\n".join(repr(m) for m in got), + ) + assert list(messages) == got, msg + + def walk(self, node): + """recursive walk on the given node""" + walker = PyLintASTWalker(linter) + walker.add_checker(self.checker) + walker.walk(node) + + +# Init +test_reporter = TestReporter() +linter = PyLinter() +linter.set_reporter(test_reporter) +linter.config.persistent = 0 +checkers.initialize(linter) + + +def _tokenize_str(code): + return list(tokenize.generate_tokens(StringIO(code).readline)) + + +@contextlib.contextmanager +def _create_tempfile(content=None): + """Create a new temporary file. + + If *content* parameter is given, then it will be written + in the temporary file, before passing it back. + This is a context manager and should be used with a *with* statement. + """ + # Can't use tempfile.NamedTemporaryFile here + # because on Windows the file must be closed before writing to it, + # see http://bugs.python.org/issue14243 + file_handle, tmp = tempfile.mkstemp() + if content: + if sys.version_info >= (3, 0): + # erff + os.write(file_handle, bytes(content, "ascii")) + else: + os.write(file_handle, content) + try: + yield tmp + finally: + os.close(file_handle) + os.remove(tmp) + + +@contextlib.contextmanager +def _create_file_backed_module(code): + """Create an astroid module for the given code, backed by a real file.""" + with _create_tempfile() as temp: + module = astroid.parse(code) + module.file = temp + yield module diff --git a/basic python programmes/venv/Lib/site-packages/pylint/utils.py b/basic python programmes/venv/Lib/site-packages/pylint/utils.py new file mode 100644 index 0000000..76afdea --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/pylint/utils.py @@ -0,0 +1,1476 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2006-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr> +# Copyright (c) 2009 Vincent +# Copyright (c) 2009 Mads Kiilerich <mads@kiilerich.com> +# Copyright (c) 2012-2014 Google, Inc. +# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2014-2015 Michal Nowikowski <godfryd@gmail.com> +# Copyright (c) 2014 LCD 47 <lcd047@gmail.com> +# Copyright (c) 2014 Brett Cannon <brett@python.org> +# Copyright (c) 2014 Arun Persaud <arun@nubati.net> +# Copyright (c) 2014 Damien Nozay <damien.nozay@gmail.com> +# Copyright (c) 2015 Aru Sahni <arusahni@gmail.com> +# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org> +# Copyright (c) 2015 Simu Toni <simutoni@gmail.com> +# Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro> +# Copyright (c) 2016 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net> +# Copyright (c) 2016 Glenn Matthews <glmatthe@cisco.com> +# Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk> +# Copyright (c) 2016 xmo-odoo <xmo-odoo@users.noreply.github.com> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Pierre Sassoulas <pierre.sassoulas@cea.fr> +# Copyright (c) 2017 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2017 Chris Lamb <chris@chris-lamb.co.uk> +# Copyright (c) 2017 Anthony Sottile <asottile@umich.edu> +# Copyright (c) 2017 Thomas Hisch <t.hisch@gmail.com> +# Copyright (c) 2017 Mikhail Fesenko <proggga@gmail.com> +# Copyright (c) 2017 Craig Citro <craigcitro@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Pierre Sassoulas <pierre.sassoulas@wisebim.fr> +# Copyright (c) 2018 Reverb C <reverbc@users.noreply.github.com> +# Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com> + +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/master/COPYING + +"""some various utilities and helper classes, most of them used in the +main pylint class +""" +from __future__ import print_function + +import codecs +import collections +from inspect import cleandoc +import os +from os.path import dirname, basename, splitext, exists, isdir, join, normpath +import re +import sys +import tokenize +import warnings +import textwrap + +from astroid import nodes, Module +from astroid import modutils + +from pylint.interfaces import IRawChecker, ITokenChecker, UNDEFINED, implements +from pylint.reporters.ureports.nodes import Section +from pylint.exceptions import InvalidMessageError, UnknownMessageError, EmptyReportError + + +MSG_TYPES = { + "I": "info", + "C": "convention", + "R": "refactor", + "W": "warning", + "E": "error", + "F": "fatal", +} +MSG_TYPES_LONG = {v: k for k, v in MSG_TYPES.items()} + +MSG_TYPES_STATUS = {"I": 0, "C": 16, "R": 8, "W": 4, "E": 2, "F": 1} + +_MSG_ORDER = "EWRCIF" +MSG_STATE_SCOPE_CONFIG = 0 +MSG_STATE_SCOPE_MODULE = 1 +MSG_STATE_CONFIDENCE = 2 + +# Allow stopping after the first semicolon/hash encountered, +# so that an option can be continued with the reasons +# why it is active or disabled. +OPTION_RGX = re.compile(r"\s*#.*\bpylint:\s*([^;#]+)[;#]{0,1}") + +# The line/node distinction does not apply to fatal errors and reports. +_SCOPE_EXEMPT = "FR" + + +class WarningScope: + LINE = "line-based-msg" + NODE = "node-based-msg" + + +_MsgBase = collections.namedtuple( + "_MsgBase", + [ + "msg_id", + "symbol", + "msg", + "C", + "category", + "confidence", + "abspath", + "path", + "module", + "obj", + "line", + "column", + ], +) + + +class Message(_MsgBase): + """This class represent a message to be issued by the reporters""" + + def __new__(cls, msg_id, symbol, location, msg, confidence): + return _MsgBase.__new__( + cls, + msg_id, + symbol, + msg, + msg_id[0], + MSG_TYPES[msg_id[0]], + confidence, + *location + ) + + def format(self, template): + """Format the message according to the given template. + + The template format is the one of the format method : + cf. http://docs.python.org/2/library/string.html#formatstrings + """ + # For some reason, _asdict on derived namedtuples does not work with + # Python 3.4. Needs some investigation. + return template.format(**dict(zip(self._fields, self))) + + +def get_module_and_frameid(node): + """return the module name and the frame id in the module""" + frame = node.frame() + module, obj = "", [] + while frame: + if isinstance(frame, Module): + module = frame.name + else: + obj.append(getattr(frame, "name", "<lambda>")) + try: + frame = frame.parent.frame() + except AttributeError: + frame = None + obj.reverse() + return module, ".".join(obj) + + +def category_id(cid): + cid = cid.upper() + if cid in MSG_TYPES: + return cid + return MSG_TYPES_LONG.get(cid) + + +def safe_decode(line, encoding, *args, **kwargs): + """return decoded line from encoding or decode with default encoding""" + try: + return line.decode(encoding or sys.getdefaultencoding(), *args, **kwargs) + except LookupError: + return line.decode(sys.getdefaultencoding(), *args, **kwargs) + + +def decoding_stream(stream, encoding, errors="strict"): + try: + reader_cls = codecs.getreader(encoding or sys.getdefaultencoding()) + except LookupError: + reader_cls = codecs.getreader(sys.getdefaultencoding()) + return reader_cls(stream, errors) + + +def tokenize_module(module): + with module.stream() as stream: + readline = stream.readline + return list(tokenize.tokenize(readline)) + + +def build_message_def(checker, msgid, msg_tuple): + if implements(checker, (IRawChecker, ITokenChecker)): + default_scope = WarningScope.LINE + else: + default_scope = WarningScope.NODE + options = {} + if len(msg_tuple) > 3: + (msg, symbol, descr, options) = msg_tuple + elif len(msg_tuple) > 2: + (msg, symbol, descr) = msg_tuple + else: + # messages should have a symbol, but for backward compatibility + # they may not. + (msg, descr) = msg_tuple + warnings.warn( + "[pylint 0.26] description of message %s doesn't include " + "a symbolic name" % msgid, + DeprecationWarning, + ) + symbol = None + options.setdefault("scope", default_scope) + return MessageDefinition(checker, msgid, msg, descr, symbol, **options) + + +class MessageDefinition: + def __init__( + self, + checker, + msgid, + msg, + descr, + symbol, + scope, + minversion=None, + maxversion=None, + old_names=None, + ): + self.checker = checker + if len(msgid) != 5: + raise InvalidMessageError("Invalid message id %r" % msgid) + if not msgid[0] in MSG_TYPES: + raise InvalidMessageError("Bad message type %s in %r" % (msgid[0], msgid)) + self.msgid = msgid + self.msg = msg + self.descr = descr + self.symbol = symbol + self.scope = scope + self.minversion = minversion + self.maxversion = maxversion + self.old_names = old_names or [] + + def __repr__(self): + return "MessageDefinition:{}".format(self.__dict__) + + def may_be_emitted(self): + """return True if message may be emitted using the current interpreter""" + if self.minversion is not None and self.minversion > sys.version_info: + return False + if self.maxversion is not None and self.maxversion <= sys.version_info: + return False + return True + + def format_help(self, checkerref=False): + """return the help string for the given message id""" + desc = self.descr + if checkerref: + desc += " This message belongs to the %s checker." % self.checker.name + title = self.msg + if self.symbol: + msgid = "%s (%s)" % (self.symbol, self.msgid) + else: + msgid = self.msgid + if self.minversion or self.maxversion: + restr = [] + if self.minversion: + restr.append("< %s" % ".".join([str(n) for n in self.minversion])) + if self.maxversion: + restr.append(">= %s" % ".".join([str(n) for n in self.maxversion])) + restr = " or ".join(restr) + if checkerref: + desc += " It can't be emitted when using Python %s." % restr + else: + desc += " This message can't be emitted when using Python %s." % restr + desc = _normalize_text(" ".join(desc.split()), indent=" ") + if title != "%s": + title = title.splitlines()[0] + + return ":%s: *%s*\n%s" % (msgid, title.rstrip(" "), desc) + return ":%s:\n%s" % (msgid, desc) + + +class MessagesHandlerMixIn: + """a mix-in class containing all the messages related methods for the main + lint class + """ + + __by_id_managed_msgs = [] # type: ignore + + def __init__(self): + self._msgs_state = {} + self.msg_status = 0 + + def _checker_messages(self, checker): + for known_checker in self._checkers[checker.lower()]: + for msgid in known_checker.msgs: + yield msgid + + @classmethod + def clear_by_id_managed_msgs(cls): + cls.__by_id_managed_msgs.clear() + + @classmethod + def get_by_id_managed_msgs(cls): + return cls.__by_id_managed_msgs + + def _register_by_id_managed_msg(self, msgid, line, is_disabled=True): + """If the msgid is a numeric one, then register it to inform the user + it could furnish instead a symbolic msgid.""" + try: + msg = self.msgs_store.get_message_definition(msgid) + if msgid == msg.msgid: + MessagesHandlerMixIn.__by_id_managed_msgs.append( + (self.current_name, msg.msgid, msg.symbol, line, is_disabled) + ) + except UnknownMessageError: + pass + + def disable(self, msgid, scope="package", line=None, ignore_unknown=False): + """don't output message of the given id""" + self._set_msg_status( + msgid, enable=False, scope=scope, line=line, ignore_unknown=ignore_unknown + ) + self._register_by_id_managed_msg(msgid, line) + + def enable(self, msgid, scope="package", line=None, ignore_unknown=False): + """reenable message of the given id""" + self._set_msg_status( + msgid, enable=True, scope=scope, line=line, ignore_unknown=ignore_unknown + ) + self._register_by_id_managed_msg(msgid, line, is_disabled=False) + + def _set_msg_status( + self, msgid, enable, scope="package", line=None, ignore_unknown=False + ): + assert scope in ("package", "module") + + if msgid == "all": + for _msgid in MSG_TYPES: + self._set_msg_status(_msgid, enable, scope, line, ignore_unknown) + if enable and not self._python3_porting_mode: + # Don't activate the python 3 porting checker if it wasn't activated explicitly. + self.disable("python3") + return + + # msgid is a category? + catid = category_id(msgid) + if catid is not None: + for _msgid in self.msgs_store._msgs_by_category.get(catid): + self._set_msg_status(_msgid, enable, scope, line) + return + + # msgid is a checker name? + if msgid.lower() in self._checkers: + msgs_store = self.msgs_store + for checker in self._checkers[msgid.lower()]: + for _msgid in checker.msgs: + if _msgid in msgs_store._alternative_names: + self._set_msg_status(_msgid, enable, scope, line) + return + + # msgid is report id? + if msgid.lower().startswith("rp"): + if enable: + self.enable_report(msgid) + else: + self.disable_report(msgid) + return + + try: + # msgid is a symbolic or numeric msgid. + msg = self.msgs_store.get_message_definition(msgid) + except UnknownMessageError: + if ignore_unknown: + return + raise + + if scope == "module": + self.file_state.set_msg_status(msg, line, enable) + if not enable and msg.symbol != "locally-disabled": + self.add_message( + "locally-disabled", line=line, args=(msg.symbol, msg.msgid) + ) + else: + msgs = self._msgs_state + msgs[msg.msgid] = enable + # sync configuration object + self.config.enable = [ + self._message_symbol(mid) for mid, val in sorted(msgs.items()) if val + ] + self.config.disable = [ + self._message_symbol(mid) + for mid, val in sorted(msgs.items()) + if not val + ] + + def _message_symbol(self, msgid): + """Get the message symbol of the given message id + + Return the original message id if the message does not + exist. + """ + try: + return self.msgs_store.get_message_definition(msgid).symbol + except UnknownMessageError: + return msgid + + def get_message_state_scope(self, msgid, line=None, confidence=UNDEFINED): + """Returns the scope at which a message was enabled/disabled.""" + if self.config.confidence and confidence.name not in self.config.confidence: + return MSG_STATE_CONFIDENCE + try: + if line in self.file_state._module_msgs_state[msgid]: + return MSG_STATE_SCOPE_MODULE + except (KeyError, TypeError): + return MSG_STATE_SCOPE_CONFIG + return None + + def is_message_enabled(self, msg_descr, line=None, confidence=None): + """return true if the message associated to the given message id is + enabled + + msgid may be either a numeric or symbolic message id. + """ + if self.config.confidence and confidence: + if confidence.name not in self.config.confidence: + return False + try: + msgid = self.msgs_store.get_message_definition(msg_descr).msgid + except UnknownMessageError: + # The linter checks for messages that are not registered + # due to version mismatch, just treat them as message IDs + # for now. + msgid = msg_descr + if line is None: + return self._msgs_state.get(msgid, True) + try: + return self.file_state._module_msgs_state[msgid][line] + except KeyError: + # Check if the message's line is after the maximum line existing in ast tree. + # This line won't appear in the ast tree and won't be referred in + #  self.file_state._module_msgs_state + # This happens for example with a commented line at the end of a module. + max_line_number = self.file_state.get_effective_max_line_number() + if max_line_number and line > max_line_number: + fallback = True + lines = self.file_state._raw_module_msgs_state.get(msgid, {}) + + # Doesn't consider scopes, as a disable can be in a different scope + # than that of the current line. + closest_lines = reversed( + [ + (message_line, enable) + for message_line, enable in lines.items() + if message_line <= line + ] + ) + last_line, is_enabled = next(closest_lines, (None, None)) + if last_line is not None: + fallback = is_enabled + + return self._msgs_state.get(msgid, fallback) + return self._msgs_state.get(msgid, True) + + def add_message( + self, + msg_descr, + line=None, + node=None, + args=None, + confidence=UNDEFINED, + col_offset=None, + ): + """Adds a message given by ID or name. + + If provided, the message string is expanded using args. + + AST checkers must provide the node argument (but may optionally + provide line if the line number is different), raw and token checkers + must provide the line argument. + """ + msg_info = self.msgs_store.get_message_definition(msg_descr) + msgid = msg_info.msgid + # backward compatibility, message may not have a symbol + symbol = msg_info.symbol or msgid + # Fatal messages and reports are special, the node/scope distinction + # does not apply to them. + if msgid[0] not in _SCOPE_EXEMPT: + if msg_info.scope == WarningScope.LINE: + if line is None: + raise InvalidMessageError( + "Message %s must provide line, got None" % msgid + ) + if node is not None: + raise InvalidMessageError( + "Message %s must only provide line, " + "got line=%s, node=%s" % (msgid, line, node) + ) + elif msg_info.scope == WarningScope.NODE: + # Node-based warnings may provide an override line. + if node is None: + raise InvalidMessageError( + "Message %s must provide Node, got None" % msgid + ) + + if line is None and node is not None: + line = node.fromlineno + if col_offset is None and hasattr(node, "col_offset"): + col_offset = ( + node.col_offset + ) # XXX measured in bytes for utf-8, divide by two for chars? + + # should this message be displayed + if not self.is_message_enabled(msgid, line, confidence): + self.file_state.handle_ignored_message( + self.get_message_state_scope(msgid, line, confidence), + msgid, + line, + node, + args, + confidence, + ) + return + # update stats + msg_cat = MSG_TYPES[msgid[0]] + self.msg_status |= MSG_TYPES_STATUS[msgid[0]] + self.stats[msg_cat] += 1 + self.stats["by_module"][self.current_name][msg_cat] += 1 + try: + self.stats["by_msg"][symbol] += 1 + except KeyError: + self.stats["by_msg"][symbol] = 1 + # expand message ? + msg = msg_info.msg + if args: + msg %= args + # get module and object + if node is None: + module, obj = self.current_name, "" + abspath = self.current_file + else: + module, obj = get_module_and_frameid(node) + abspath = node.root().file + path = abspath.replace(self.reporter.path_strip_prefix, "", 1) + # add the message + self.reporter.handle_message( + Message( + msgid, + symbol, + (abspath, path, module, obj, line or 1, col_offset or 0), + msg, + confidence, + ) + ) + + def print_full_documentation(self, stream=None): + """output a full documentation in ReST format""" + if not stream: + stream = sys.stdout + + print("Pylint global options and switches", file=stream) + print("----------------------------------", file=stream) + print("", file=stream) + print("Pylint provides global options and switches.", file=stream) + print("", file=stream) + + by_checker = {} + for checker in self.get_checkers(): + if checker.name == "master": + if checker.options: + for section, options in checker.options_by_section(): + if section is None: + title = "General options" + else: + title = "%s options" % section.capitalize() + print(title, file=stream) + print("~" * len(title), file=stream) + _rest_format_section(stream, None, options) + print("", file=stream) + else: + name = checker.name + try: + by_checker[name]["options"] += checker.options_and_values() + by_checker[name]["msgs"].update(checker.msgs) + by_checker[name]["reports"] += checker.reports + except KeyError: + by_checker[name] = { + "options": list(checker.options_and_values()), + "msgs": dict(checker.msgs), + "reports": list(checker.reports), + } + + print("Pylint checkers' options and switches", file=stream) + print("-------------------------------------", file=stream) + print("", file=stream) + print("Pylint checkers can provide three set of features:", file=stream) + print("", file=stream) + print("* options that control their execution,", file=stream) + print("* messages that they can raise,", file=stream) + print("* reports that they can generate.", file=stream) + print("", file=stream) + print("Below is a list of all checkers and their features.", file=stream) + print("", file=stream) + + for checker, info in sorted(by_checker.items()): + self._print_checker_doc(checker, info, stream=stream) + + @staticmethod + def _print_checker_doc(checker_name, info, stream=None): + """Helper method for print_full_documentation. + + Also used by doc/exts/pylint_extensions.py. + """ + if not stream: + stream = sys.stdout + + doc = info.get("doc") + module = info.get("module") + msgs = info.get("msgs") + options = info.get("options") + reports = info.get("reports") + + checker_title = "%s checker" % (checker_name.replace("_", " ").title()) + + if module: + # Provide anchor to link against + print(".. _%s:\n" % module, file=stream) + print(checker_title, file=stream) + print("~" * len(checker_title), file=stream) + print("", file=stream) + if module: + print("This checker is provided by ``%s``." % module, file=stream) + print("Verbatim name of the checker is ``%s``." % checker_name, file=stream) + print("", file=stream) + if doc: + # Provide anchor to link against + title = "{} Documentation".format(checker_title) + print(title, file=stream) + print("^" * len(title), file=stream) + print(cleandoc(doc), file=stream) + print("", file=stream) + if options: + title = "{} Options".format(checker_title) + print(title, file=stream) + print("^" * len(title), file=stream) + _rest_format_section(stream, None, options) + print("", file=stream) + if msgs: + title = "{} Messages".format(checker_title) + print(title, file=stream) + print("^" * len(title), file=stream) + for msgid, msg in sorted( + msgs.items(), key=lambda kv: (_MSG_ORDER.index(kv[0][0]), kv[1]) + ): + msg = build_message_def(checker_name, msgid, msg) + print(msg.format_help(checkerref=False), file=stream) + print("", file=stream) + if reports: + title = "{} Reports".format(checker_title) + print(title, file=stream) + print("^" * len(title), file=stream) + for report in reports: + print(":%s: %s" % report[:2], file=stream) + print("", file=stream) + print("", file=stream) + + +class FileState: + """Hold internal state specific to the currently analyzed file""" + + def __init__(self, modname=None): + self.base_name = modname + self._module_msgs_state = {} + self._raw_module_msgs_state = {} + self._ignored_msgs = collections.defaultdict(set) + self._suppression_mapping = {} + self._effective_max_line_number = None + + def collect_block_lines(self, msgs_store, module_node): + """Walk the AST to collect block level options line numbers.""" + for msg, lines in self._module_msgs_state.items(): + self._raw_module_msgs_state[msg] = lines.copy() + orig_state = self._module_msgs_state.copy() + self._module_msgs_state = {} + self._suppression_mapping = {} + self._effective_max_line_number = module_node.tolineno + self._collect_block_lines(msgs_store, module_node, orig_state) + + def _collect_block_lines(self, msgs_store, node, msg_state): + """Recursively walk (depth first) AST to collect block level options + line numbers. + """ + for child in node.get_children(): + self._collect_block_lines(msgs_store, child, msg_state) + first = node.fromlineno + last = node.tolineno + # first child line number used to distinguish between disable + # which are the first child of scoped node with those defined later. + # For instance in the code below: + # + # 1. def meth8(self): + # 2. """test late disabling""" + # 3. # pylint: disable=E1102 + # 4. print self.blip + # 5. # pylint: disable=E1101 + # 6. print self.bla + # + # E1102 should be disabled from line 1 to 6 while E1101 from line 5 to 6 + # + # this is necessary to disable locally messages applying to class / + # function using their fromlineno + if ( + isinstance(node, (nodes.Module, nodes.ClassDef, nodes.FunctionDef)) + and node.body + ): + firstchildlineno = node.body[0].fromlineno + else: + firstchildlineno = last + for msgid, lines in msg_state.items(): + for lineno, state in list(lines.items()): + original_lineno = lineno + if first > lineno or last < lineno: + continue + # Set state for all lines for this block, if the + # warning is applied to nodes. + if msgs_store.get_message_definition(msgid).scope == WarningScope.NODE: + if lineno > firstchildlineno: + state = True + first_, last_ = node.block_range(lineno) + else: + first_ = lineno + last_ = last + for line in range(first_, last_ + 1): + # do not override existing entries + if line in self._module_msgs_state.get(msgid, ()): + continue + if line in lines: # state change in the same block + state = lines[line] + original_lineno = line + if not state: + self._suppression_mapping[(msgid, line)] = original_lineno + try: + self._module_msgs_state[msgid][line] = state + except KeyError: + self._module_msgs_state[msgid] = {line: state} + del lines[lineno] + + def set_msg_status(self, msg, line, status): + """Set status (enabled/disable) for a given message at a given line""" + assert line > 0 + try: + self._module_msgs_state[msg.msgid][line] = status + except KeyError: + self._module_msgs_state[msg.msgid] = {line: status} + + def handle_ignored_message( + self, state_scope, msgid, line, node, args, confidence + ): # pylint: disable=unused-argument + """Report an ignored message. + + state_scope is either MSG_STATE_SCOPE_MODULE or MSG_STATE_SCOPE_CONFIG, + depending on whether the message was disabled locally in the module, + or globally. The other arguments are the same as for add_message. + """ + if state_scope == MSG_STATE_SCOPE_MODULE: + try: + orig_line = self._suppression_mapping[(msgid, line)] + self._ignored_msgs[(msgid, orig_line)].add(line) + except KeyError: + pass + + def iter_spurious_suppression_messages(self, msgs_store): + for warning, lines in self._raw_module_msgs_state.items(): + for line, enable in lines.items(): + if not enable and (warning, line) not in self._ignored_msgs: + yield "useless-suppression", line, ( + msgs_store.get_msg_display_string(warning), + ) + # don't use iteritems here, _ignored_msgs may be modified by add_message + for (warning, from_), lines in list(self._ignored_msgs.items()): + for line in lines: + yield "suppressed-message", line, ( + msgs_store.get_msg_display_string(warning), + from_, + ) + + def get_effective_max_line_number(self): + return self._effective_max_line_number + + +class MessagesStore: + """The messages store knows information about every possible message but has + no particular state during analysis. + """ + + def __init__(self): + # Primary registry for all active messages (i.e. all messages + # that can be emitted by pylint for the underlying Python + # version). It contains the 1:1 mapping from symbolic names + # to message definition objects. + # Keys are msg ids, values are a 2-uple with the msg type and the + # msg itself + self._messages = {} + # Maps alternative names (numeric IDs, deprecated names) to + # message definitions. May contain several names for each definition + # object. + self._alternative_names = {} + self._msgs_by_category = collections.defaultdict(list) + + @property + def messages(self): + """The list of all active messages.""" + return self._messages.values() + + def add_renamed_message(self, old_id, old_symbol, new_symbol): + """Register the old ID and symbol for a warning that was renamed. + + This allows users to keep using the old ID/symbol in suppressions. + """ + msg = self.get_message_definition(new_symbol) + msg.old_names.append((old_id, old_symbol)) + self._register_alternative_name(msg, old_id, old_symbol) + + @staticmethod + def get_checker_message_definitions(checker): + """Return the list of messages definitions for a checker. + + :param BaseChecker checker: + :rtype: list + :return: A list of MessageDefinition. + """ + message_definitions = [] + for msgid, msg_tuple in sorted(checker.msgs.items()): + message = build_message_def(checker, msgid, msg_tuple) + message_definitions.append(message) + return message_definitions + + def register_messages(self, checker): + """Register messages from a checker. + + :param BaseChecker checker: + """ + messages = self.get_checker_message_definitions(checker) + self._check_checker_consistency(messages) + for message in messages: + self.register_message(message) + + def register_message(self, message): + """Register a MessageDefinition with consistency in mind. + + :param MessageDefinition message: The message definition being added. + """ + self._check_id_and_symbol_consistency(message.msgid, message.symbol) + self._check_symbol(message.msgid, message.symbol) + self._check_msgid(message.msgid, message.symbol) + for old_name in message.old_names: + self._check_symbol(message.msgid, old_name[1]) + self._messages[message.symbol] = message + self._register_alternative_name(message, message.msgid, message.symbol) + for old_id, old_symbol in message.old_names: + self._register_alternative_name(message, old_id, old_symbol) + self._msgs_by_category[message.msgid[0]].append(message.msgid) + + @staticmethod + def _check_checker_consistency(messages): + """Check the msgid consistency in a list of messages definitions. + + msg ids for a checker should be a string of len 4, where the two first + characters are the checker id and the two last the msg id in this + checker. + + :param list messages: List of MessageDefinition. + :raises InvalidMessageError: If the checker id in the messages are not + always the same + """ + checker_id = None + existing_ids = [] + for message in messages: + if checker_id is not None and checker_id != message.msgid[1:3]: + error_msg = "Inconsistent checker part in message id " + error_msg += "'{}' (expected 'x{checker_id}xx' ".format( + message.msgid, checker_id=checker_id + ) + error_msg += "because we already had {existing_ids}).".format( + existing_ids=existing_ids + ) + raise InvalidMessageError(error_msg) + checker_id = message.msgid[1:3] + existing_ids.append(message.msgid) + + def _register_alternative_name(self, msg, msgid, symbol): + """helper for register_message()""" + self._check_id_and_symbol_consistency(msgid, symbol) + self._alternative_names[msgid] = msg + self._alternative_names[symbol] = msg + + def _check_symbol(self, msgid, symbol): + """Check that a symbol is not already used. """ + other_message = self._messages.get(symbol) + if other_message: + self._raise_duplicate_msg_id(symbol, msgid, other_message.msgid) + else: + alternative_msgid = None + alternative_message = self._alternative_names.get(symbol) + if alternative_message: + if alternative_message.symbol == symbol: + alternative_msgid = alternative_message.msgid + else: + for old_msgid, old_symbol in alternative_message.old_names: + if old_symbol == symbol: + alternative_msgid = old_msgid + break + if msgid != alternative_msgid: + self._raise_duplicate_msg_id(symbol, msgid, alternative_msgid) + + def _check_msgid(self, msgid, symbol): + for message in self._messages.values(): + if message.msgid == msgid: + self._raise_duplicate_symbol(msgid, symbol, message.symbol) + + def _check_id_and_symbol_consistency(self, msgid, symbol): + try: + alternative = self._alternative_names[msgid] + except KeyError: + alternative = False + try: + if not alternative: + alternative = self._alternative_names[symbol] + except KeyError: + # There is no alternative names concerning this msgid/symbol. + # So nothing to check + return None + old_symbolic_name = None + old_symbolic_id = None + for alternate_msgid, alternate_symbol in alternative.old_names: + if alternate_msgid == msgid or alternate_symbol == symbol: + old_symbolic_id = alternate_msgid + old_symbolic_name = alternate_symbol + if symbol not in (alternative.symbol, old_symbolic_name): + if msgid == old_symbolic_id: + self._raise_duplicate_symbol(msgid, symbol, old_symbolic_name) + else: + self._raise_duplicate_symbol(msgid, symbol, alternative.symbol) + return None + + @staticmethod + def _raise_duplicate_symbol(msgid, symbol, other_symbol): + """Raise an error when a symbol is duplicated. + + :param str msgid: The msgid corresponding to the symbols + :param str symbol: Offending symbol + :param str other_symbol: Other offending symbol + :raises InvalidMessageError: when a symbol is duplicated. + """ + error_message = "Message id '{msgid}' cannot have both ".format(msgid=msgid) + error_message += "'{other_symbol}' and '{symbol}' as symbolic name.".format( + other_symbol=other_symbol, symbol=symbol + ) + raise InvalidMessageError(error_message) + + @staticmethod + def _raise_duplicate_msg_id(symbol, msgid, other_msgid): + """Raise an error when a msgid is duplicated. + + :param str symbol: The symbol corresponding to the msgids + :param str msgid: Offending msgid + :param str other_msgid: Other offending msgid + :raises InvalidMessageError: when a msgid is duplicated. + """ + error_message = "Message symbol '{symbol}' cannot be used for ".format( + symbol=symbol + ) + error_message += "'{other_msgid}' and '{msgid}' at the same time.".format( + other_msgid=other_msgid, msgid=msgid + ) + raise InvalidMessageError(error_message) + + def get_message_definition(self, msgid_or_symbol): + """Returns the Message object for this message. + + :param str msgid_or_symbol: msgid_or_symbol may be either a numeric or symbolic id. + :raises UnknownMessageError: if the message id is not defined. + :rtype: MessageDefinition + :return: A message definition corresponding to msgid_or_symbol + """ + if msgid_or_symbol[1:].isdigit(): + msgid_or_symbol = msgid_or_symbol.upper() + for source in (self._alternative_names, self._messages): + try: + return source[msgid_or_symbol] + except KeyError: + pass + raise UnknownMessageError( + "No such message id {msgid_or_symbol}".format( + msgid_or_symbol=msgid_or_symbol + ) + ) + + def get_msg_display_string(self, msgid): + """Generates a user-consumable representation of a message. + + Can be just the message ID or the ID and the symbol. + """ + return repr(self.get_message_definition(msgid).symbol) + + def help_message(self, msgids): + """Display help messages for the given message identifiers""" + for msgid in msgids: + try: + print(self.get_message_definition(msgid).format_help(checkerref=True)) + print("") + except UnknownMessageError as ex: + print(ex) + print("") + continue + + def list_messages(self): + """Output full messages list documentation in ReST format. """ + messages = sorted(self._messages.values(), key=lambda m: m.msgid) + for message in messages: + if not message.may_be_emitted(): + continue + print(message.format_help(checkerref=False)) + print("") + + +class ReportsHandlerMixIn: + """a mix-in class containing all the reports and stats manipulation + related methods for the main lint class + """ + + def __init__(self): + self._reports = collections.defaultdict(list) + self._reports_state = {} + + def report_order(self): + """ Return a list of reports, sorted in the order + in which they must be called. + """ + return list(self._reports) + + def register_report(self, reportid, r_title, r_cb, checker): + """register a report + + reportid is the unique identifier for the report + r_title the report's title + r_cb the method to call to make the report + checker is the checker defining the report + """ + reportid = reportid.upper() + self._reports[checker].append((reportid, r_title, r_cb)) + + def enable_report(self, reportid): + """disable the report of the given id""" + reportid = reportid.upper() + self._reports_state[reportid] = True + + def disable_report(self, reportid): + """disable the report of the given id""" + reportid = reportid.upper() + self._reports_state[reportid] = False + + def report_is_enabled(self, reportid): + """return true if the report associated to the given identifier is + enabled + """ + return self._reports_state.get(reportid, True) + + def make_reports(self, stats, old_stats): + """render registered reports""" + sect = Section("Report", "%s statements analysed." % (self.stats["statement"])) + for checker in self.report_order(): + for reportid, r_title, r_cb in self._reports[checker]: + if not self.report_is_enabled(reportid): + continue + report_sect = Section(r_title) + try: + r_cb(report_sect, stats, old_stats) + except EmptyReportError: + continue + report_sect.report_id = reportid + sect.append(report_sect) + return sect + + def add_stats(self, **kwargs): + """add some stats entries to the statistic dictionary + raise an AssertionError if there is a key conflict + """ + for key, value in kwargs.items(): + if key[-1] == "_": + key = key[:-1] + assert key not in self.stats + self.stats[key] = value + return self.stats + + +def _basename_in_blacklist_re(base_name, black_list_re): + """Determines if the basename is matched in a regex blacklist + + :param str base_name: The basename of the file + :param list black_list_re: A collection of regex patterns to match against. + Successful matches are blacklisted. + + :returns: `True` if the basename is blacklisted, `False` otherwise. + :rtype: bool + """ + for file_pattern in black_list_re: + if file_pattern.match(base_name): + return True + return False + + +def _modpath_from_file(filename, is_namespace): + def _is_package_cb(path, parts): + return modutils.check_modpath_has_init(path, parts) or is_namespace + + return modutils.modpath_from_file_with_callback( + filename, is_package_cb=_is_package_cb + ) + + +def expand_modules(files_or_modules, black_list, black_list_re): + """take a list of files/modules/packages and return the list of tuple + (file, module name) which have to be actually checked + """ + result = [] + errors = [] + for something in files_or_modules: + if os.path.basename(something) in black_list: + continue + if _basename_in_blacklist_re(os.path.basename(something), black_list_re): + continue + if exists(something): + # this is a file or a directory + try: + modname = ".".join(modutils.modpath_from_file(something)) + except ImportError: + modname = splitext(basename(something))[0] + if isdir(something): + filepath = join(something, "__init__.py") + else: + filepath = something + else: + # suppose it's a module or package + modname = something + try: + filepath = modutils.file_from_modpath(modname.split(".")) + if filepath is None: + continue + except (ImportError, SyntaxError) as ex: + # FIXME p3k : the SyntaxError is a Python bug and should be + # removed as soon as possible http://bugs.python.org/issue10588 + errors.append({"key": "fatal", "mod": modname, "ex": ex}) + continue + + filepath = normpath(filepath) + modparts = (modname or something).split(".") + + try: + spec = modutils.file_info_from_modpath(modparts, path=sys.path) + except ImportError: + # Might not be acceptable, don't crash. + is_namespace = False + is_directory = isdir(something) + else: + is_namespace = modutils.is_namespace(spec) + is_directory = modutils.is_directory(spec) + + if not is_namespace: + result.append( + { + "path": filepath, + "name": modname, + "isarg": True, + "basepath": filepath, + "basename": modname, + } + ) + + has_init = ( + not (modname.endswith(".__init__") or modname == "__init__") + and basename(filepath) == "__init__.py" + ) + + if has_init or is_namespace or is_directory: + for subfilepath in modutils.get_module_files( + dirname(filepath), black_list, list_all=is_namespace + ): + if filepath == subfilepath: + continue + if _basename_in_blacklist_re(basename(subfilepath), black_list_re): + continue + + modpath = _modpath_from_file(subfilepath, is_namespace) + submodname = ".".join(modpath) + result.append( + { + "path": subfilepath, + "name": submodname, + "isarg": False, + "basepath": filepath, + "basename": modname, + } + ) + return result, errors + + +class PyLintASTWalker: + def __init__(self, linter): + # callbacks per node types + self.nbstatements = 0 + self.visit_events = collections.defaultdict(list) + self.leave_events = collections.defaultdict(list) + self.linter = linter + + def _is_method_enabled(self, method): + if not hasattr(method, "checks_msgs"): + return True + for msg_desc in method.checks_msgs: + if self.linter.is_message_enabled(msg_desc): + return True + return False + + def add_checker(self, checker): + """walk to the checker's dir and collect visit and leave methods""" + # XXX : should be possible to merge needed_checkers and add_checker + vcids = set() + lcids = set() + visits = self.visit_events + leaves = self.leave_events + for member in dir(checker): + cid = member[6:] + if cid == "default": + continue + if member.startswith("visit_"): + v_meth = getattr(checker, member) + # don't use visit_methods with no activated message: + if self._is_method_enabled(v_meth): + visits[cid].append(v_meth) + vcids.add(cid) + elif member.startswith("leave_"): + l_meth = getattr(checker, member) + # don't use leave_methods with no activated message: + if self._is_method_enabled(l_meth): + leaves[cid].append(l_meth) + lcids.add(cid) + visit_default = getattr(checker, "visit_default", None) + if visit_default: + for cls in nodes.ALL_NODE_CLASSES: + cid = cls.__name__.lower() + if cid not in vcids: + visits[cid].append(visit_default) + # for now we have no "leave_default" method in Pylint + + def walk(self, astroid): + """call visit events of astroid checkers for the given node, recurse on + its children, then leave events. + """ + cid = astroid.__class__.__name__.lower() + + # Detect if the node is a new name for a deprecated alias. + # In this case, favour the methods for the deprecated + # alias if any, in order to maintain backwards + # compatibility. + visit_events = self.visit_events.get(cid, ()) + leave_events = self.leave_events.get(cid, ()) + + if astroid.is_statement: + self.nbstatements += 1 + # generate events for this node on each checker + for cb in visit_events or (): + cb(astroid) + # recurse on children + for child in astroid.get_children(): + self.walk(child) + for cb in leave_events or (): + cb(astroid) + + +PY_EXTS = (".py", ".pyc", ".pyo", ".pyw", ".so", ".dll") + + +def register_plugins(linter, directory): + """load all module and package in the given directory, looking for a + 'register' function in each one, used to register pylint checkers + """ + imported = {} + for filename in os.listdir(directory): + base, extension = splitext(filename) + if base in imported or base == "__pycache__": + continue + if ( + extension in PY_EXTS + and base != "__init__" + or (not extension and isdir(join(directory, base))) + ): + try: + module = modutils.load_module_from_file(join(directory, filename)) + except ValueError: + # empty module name (usually emacs auto-save files) + continue + except ImportError as exc: + print( + "Problem importing module %s: %s" % (filename, exc), file=sys.stderr + ) + else: + if hasattr(module, "register"): + module.register(linter) + imported[base] = 1 + + +def get_global_option(checker, option, default=None): + """ Retrieve an option defined by the given *checker* or + by all known option providers. + + It will look in the list of all options providers + until the given *option* will be found. + If the option wasn't found, the *default* value will be returned. + """ + # First, try in the given checker's config. + # After that, look in the options providers. + + try: + return getattr(checker.config, option.replace("-", "_")) + except AttributeError: + pass + for provider in checker.linter.options_providers: + for options in provider.options: + if options[0] == option: + return getattr(provider.config, option.replace("-", "_")) + return default + + +def deprecated_option( + shortname=None, opt_type=None, help_msg=None, deprecation_msg=None +): + def _warn_deprecated(option, optname, *args): # pylint: disable=unused-argument + if deprecation_msg: + sys.stderr.write(deprecation_msg % (optname,)) + + option = { + "help": help_msg, + "hide": True, + "type": opt_type, + "action": "callback", + "callback": _warn_deprecated, + "deprecated": True, + } + if shortname: + option["shortname"] = shortname + return option + + +def _splitstrip(string, sep=","): + """return a list of stripped string by splitting the string given as + argument on `sep` (',' by default). Empty string are discarded. + + >>> _splitstrip('a, b, c , 4,,') + ['a', 'b', 'c', '4'] + >>> _splitstrip('a') + ['a'] + >>> _splitstrip('a,\nb,\nc,') + ['a', 'b', 'c'] + + :type string: str or unicode + :param string: a csv line + + :type sep: str or unicode + :param sep: field separator, default to the comma (',') + + :rtype: str or unicode + :return: the unquoted string (or the input string if it wasn't quoted) + """ + return [word.strip() for word in string.split(sep) if word.strip()] + + +def _unquote(string): + """remove optional quotes (simple or double) from the string + + :type string: str or unicode + :param string: an optionally quoted string + + :rtype: str or unicode + :return: the unquoted string (or the input string if it wasn't quoted) + """ + if not string: + return string + if string[0] in "\"'": + string = string[1:] + if string[-1] in "\"'": + string = string[:-1] + return string + + +def _normalize_text(text, line_len=80, indent=""): + """Wrap the text on the given line length.""" + return "\n".join( + textwrap.wrap( + text, width=line_len, initial_indent=indent, subsequent_indent=indent + ) + ) + + +def _check_csv(value): + if isinstance(value, (list, tuple)): + return value + return _splitstrip(value) + + +def _comment(string): + """return string as a comment""" + lines = [line.strip() for line in string.splitlines()] + return "# " + ("%s# " % os.linesep).join(lines) + + +def _format_option_value(optdict, value): + """return the user input's value from a 'compiled' value""" + if isinstance(value, (list, tuple)): + value = ",".join(_format_option_value(optdict, item) for item in value) + elif isinstance(value, dict): + value = ",".join("%s:%s" % (k, v) for k, v in value.items()) + elif hasattr(value, "match"): # optdict.get('type') == 'regexp' + # compiled regexp + value = value.pattern + elif optdict.get("type") == "yn": + value = "yes" if value else "no" + elif isinstance(value, str) and value.isspace(): + value = "'%s'" % value + return value + + +def _ini_format_section(stream, section, options, doc=None): + """format an options section using the INI format""" + if doc: + print(_comment(doc), file=stream) + print("[%s]" % section, file=stream) + _ini_format(stream, options) + + +def _ini_format(stream, options): + """format options using the INI format""" + for optname, optdict, value in options: + value = _format_option_value(optdict, value) + help_opt = optdict.get("help") + if help_opt: + help_opt = _normalize_text(help_opt, line_len=79, indent="# ") + print(file=stream) + print(help_opt, file=stream) + else: + print(file=stream) + if value is None: + print("#%s=" % optname, file=stream) + else: + value = str(value).strip() + if re.match(r"^([\w-]+,)+[\w-]+$", str(value)): + separator = "\n " + " " * len(optname) + value = separator.join(x + "," for x in str(value).split(",")) + # remove trailing ',' from last element of the list + value = value[:-1] + print("%s=%s" % (optname, value), file=stream) + + +format_section = _ini_format_section + + +def _rest_format_section(stream, section, options, doc=None): + """format an options section using as ReST formatted output""" + if section: + print("%s\n%s" % (section, "'" * len(section)), file=stream) + if doc: + print(_normalize_text(doc, line_len=79, indent=""), file=stream) + print(file=stream) + for optname, optdict, value in options: + help_opt = optdict.get("help") + print(":%s:" % optname, file=stream) + if help_opt: + help_opt = _normalize_text(help_opt, line_len=79, indent=" ") + print(help_opt, file=stream) + if value: + value = str(_format_option_value(optdict, value)) + print(file=stream) + print(" Default: ``%s``" % value.replace("`` ", "```` ``"), file=stream) diff --git a/basic python programmes/venv/Lib/site-packages/setuptools-39.1.0-py3.7.egg b/basic python programmes/venv/Lib/site-packages/setuptools-39.1.0-py3.7.egg new file mode 100644 index 0000000..6f0d0df Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/setuptools-39.1.0-py3.7.egg differ diff --git a/basic python programmes/venv/Lib/site-packages/setuptools.pth b/basic python programmes/venv/Lib/site-packages/setuptools.pth new file mode 100644 index 0000000..e8c36d4 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/setuptools.pth @@ -0,0 +1 @@ +./setuptools-39.1.0-py3.7.egg diff --git a/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/INSTALLER b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/LICENSE b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/LICENSE new file mode 100644 index 0000000..365d107 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/LICENSE @@ -0,0 +1,18 @@ +Copyright (c) 2010-2018 Benjamin Peterson + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/METADATA b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/METADATA new file mode 100644 index 0000000..df8db11 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/METADATA @@ -0,0 +1,52 @@ +Metadata-Version: 2.1 +Name: six +Version: 1.12.0 +Summary: Python 2 and 3 compatibility utilities +Home-page: https://github.com/benjaminp/six +Author: Benjamin Peterson +Author-email: benjamin@python.org +License: MIT +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 3 +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities +Requires-Python: >=2.6, !=3.0.*, !=3.1.* + +.. image:: https://img.shields.io/pypi/v/six.svg + :target: https://pypi.org/project/six/ + :alt: six on PyPI + +.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master + :target: https://travis-ci.org/benjaminp/six + :alt: six on TravisCI + +.. image:: https://readthedocs.org/projects/six/badge/?version=latest + :target: https://six.readthedocs.io/ + :alt: six's documentation on Read the Docs + +.. image:: https://img.shields.io/badge/license-MIT-green.svg + :target: https://github.com/benjaminp/six/blob/master/LICENSE + :alt: MIT License badge + +Six is a Python 2 and 3 compatibility library. It provides utility functions +for smoothing over the differences between the Python versions with the goal of +writing Python code that is compatible on both Python versions. See the +documentation for more information on what is provided. + +Six supports every Python version since 2.6. It is contained in only one Python +file, so it can be easily copied into your project. (The copyright and license +notice must be retained.) + +Online documentation is at https://six.readthedocs.io/. + +Bugs can be reported to https://github.com/benjaminp/six. The code can also +be found there. + +For questions about six or porting in general, email the python-porting mailing +list: https://mail.python.org/mailman/listinfo/python-porting + + diff --git a/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/RECORD b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/RECORD new file mode 100644 index 0000000..710e6c0 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/RECORD @@ -0,0 +1,8 @@ +six.py,sha256=h9jch2pS86y4R36pKRS3LOYUCVFNIJMRwjZ4fJDtJ44,32452 +six-1.12.0.dist-info/LICENSE,sha256=5zL1TaWPPpzwxI6LUSlIk2_Pc2G9WK-mOpo8OSv3lK0,1066 +six-1.12.0.dist-info/METADATA,sha256=CRdYkKPKCFJr7-qA8PDpBklGXfXJ3xu4mu5tkLBDL04,1940 +six-1.12.0.dist-info/WHEEL,sha256=_wJFdOYk7i3xxT8ElOkUJvOdOvfNGbR9g-bf6UQT6sU,110 +six-1.12.0.dist-info/top_level.txt,sha256=_iVH_iYEtEXnD8nYGQYpYFUvkUW9sEO1GYbkeKSAais,4 +six-1.12.0.dist-info/RECORD,, +six-1.12.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +__pycache__/six.cpython-37.pyc,, diff --git a/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/WHEEL b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/WHEEL new file mode 100644 index 0000000..c4bde30 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.3) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/top_level.txt new file mode 100644 index 0000000..ffe2fce --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/six-1.12.0.dist-info/top_level.txt @@ -0,0 +1 @@ +six diff --git a/basic python programmes/venv/Lib/site-packages/six.py b/basic python programmes/venv/Lib/site-packages/six.py new file mode 100644 index 0000000..89b2188 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/six.py @@ -0,0 +1,952 @@ +# Copyright (c) 2010-2018 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.12.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + try: + if from_value is None: + raise value + raise value from from_value + finally: + value = None +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(type): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + if hasattr(cls, '__qualname__'): + orig_vars['__qualname__'] = cls.__qualname__ + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def ensure_binary(s, encoding='utf-8', errors='strict'): + """Coerce **s** to six.binary_type. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + """ + if isinstance(s, text_type): + return s.encode(encoding, errors) + elif isinstance(s, binary_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + +def ensure_str(s, encoding='utf-8', errors='strict'): + """Coerce *s* to `str`. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + if PY2 and isinstance(s, text_type): + s = s.encode(encoding, errors) + elif PY3 and isinstance(s, binary_type): + s = s.decode(encoding, errors) + return s + + +def ensure_text(s, encoding='utf-8', errors='strict'): + """Coerce *s* to six.text_type. + + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/PKG-INFO b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/PKG-INFO new file mode 100644 index 0000000..6ac9651 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/PKG-INFO @@ -0,0 +1,163 @@ +Metadata-Version: 1.1 +Name: wrapt +Version: 1.10.11 +Summary: Module for decorators, wrappers and monkey patching. +Home-page: https://github.com/GrahamDumpleton/wrapt +Author: Graham Dumpleton +Author-email: Graham.Dumpleton@gmail.com +License: BSD +Description: wrapt + ===== + + |Travis| |Coveralls| |PyPI| + + The aim of the **wrapt** module is to provide a transparent object proxy + for Python, which can be used as the basis for the construction of function + wrappers and decorator functions. + + The **wrapt** module focuses very much on correctness. It therefore goes + way beyond existing mechanisms such as ``functools.wraps()`` to ensure that + decorators preserve introspectability, signatures, type checking abilities + etc. The decorators that can be constructed using this module will work in + far more scenarios than typical decorators and provide more predictable and + consistent behaviour. + + To ensure that the overhead is as minimal as possible, a C extension module + is used for performance critical components. An automatic fallback to a + pure Python implementation is also provided where a target system does not + have a compiler to allow the C extension to be compiled. + + Documentation + ------------- + + For further information on the **wrapt** module see: + + * http://wrapt.readthedocs.org/ + + Quick Start + ----------- + + To implement your decorator you need to first define a wrapper function. + This will be called each time a decorated function is called. The wrapper + function needs to take four positional arguments: + + * ``wrapped`` - The wrapped function which in turns needs to be called by your wrapper function. + * ``instance`` - The object to which the wrapped function was bound when it was called. + * ``args`` - The list of positional arguments supplied when the decorated function was called. + * ``kwargs`` - The dictionary of keyword arguments supplied when the decorated function was called. + + The wrapper function would do whatever it needs to, but would usually in + turn call the wrapped function that is passed in via the ``wrapped`` + argument. + + The decorator ``@wrapt.decorator`` then needs to be applied to the wrapper + function to convert it into a decorator which can in turn be applied to + other functions. + + :: + + import wrapt + + @wrapt.decorator + def pass_through(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + @pass_through + def function(): + pass + + If you wish to implement a decorator which accepts arguments, then wrap the + definition of the decorator in a function closure. Any arguments supplied + to the outer function when the decorator is applied, will be available to + the inner wrapper when the wrapped function is called. + + :: + + import wrapt + + def with_arguments(myarg1, myarg2): + @wrapt.decorator + def wrapper(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + return wrapper + + @with_arguments(1, 2) + def function(): + pass + + When applied to a normal function or static method, the wrapper function + when called will be passed ``None`` as the ``instance`` argument. + + When applied to an instance method, the wrapper function when called will + be passed the instance of the class the method is being called on as the + ``instance`` argument. This will be the case even when the instance method + was called explicitly via the class and the instance passed as the first + argument. That is, the instance will never be passed as part of ``args``. + + When applied to a class method, the wrapper function when called will be + passed the class type as the ``instance`` argument. + + When applied to a class, the wrapper function when called will be passed + ``None`` as the ``instance`` argument. The ``wrapped`` argument in this + case will be the class. + + The above rules can be summarised with the following example. + + :: + + import inspect + + @wrapt.decorator + def universal(wrapped, instance, args, kwargs): + if instance is None: + if inspect.isclass(wrapped): + # Decorator was applied to a class. + return wrapped(*args, **kwargs) + else: + # Decorator was applied to a function or staticmethod. + return wrapped(*args, **kwargs) + else: + if inspect.isclass(instance): + # Decorator was applied to a classmethod. + return wrapped(*args, **kwargs) + else: + # Decorator was applied to an instancemethod. + return wrapped(*args, **kwargs) + + Using these checks it is therefore possible to create a universal decorator + that can be applied in all situations. It is no longer necessary to create + different variants of decorators for normal functions and instance methods, + or use additional wrappers to convert a function decorator into one that + will work for instance methods. + + In all cases, the wrapped function passed to the wrapper function is called + in the same way, with ``args`` and ``kwargs`` being passed. The + ``instance`` argument doesn't need to be used in calling the wrapped + function. + + Repository + ---------- + + Full source code for the **wrapt** module, including documentation files + and unit tests, can be obtained from github. + + * https://github.com/GrahamDumpleton/wrapt + + .. |Travis| image:: https://img.shields.io/travis/GrahamDumpleton/wrapt/develop.svg?style=plastic + :target: https://travis-ci.org/GrahamDumpleton/wrapt?branch=develop + .. |Coveralls| image:: https://img.shields.io/coveralls/GrahamDumpleton/wrapt/develop.svg?style=plastic + :target: https://coveralls.io/github/GrahamDumpleton/wrapt?branch=develop + .. |PyPI| image:: https://img.shields.io/pypi/v/wrapt.svg?style=plastic + :target: https://pypi.python.org/pypi/wrapt + +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: BSD License +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy diff --git a/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/SOURCES.txt b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/SOURCES.txt new file mode 100644 index 0000000..36c25d7 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/SOURCES.txt @@ -0,0 +1,10 @@ +README.rst +src/wrapt/__init__.py +src/wrapt/arguments.py +src/wrapt/decorators.py +src/wrapt/importer.py +src/wrapt/wrappers.py +src/wrapt.egg-info/PKG-INFO +src/wrapt.egg-info/SOURCES.txt +src/wrapt.egg-info/dependency_links.txt +src/wrapt.egg-info/top_level.txt \ No newline at end of file diff --git a/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/dependency_links.txt b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/installed-files.txt b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/installed-files.txt new file mode 100644 index 0000000..80abb34 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/installed-files.txt @@ -0,0 +1,14 @@ +..\wrapt\__init__.py +..\wrapt\__pycache__\__init__.cpython-37.pyc +..\wrapt\__pycache__\arguments.cpython-37.pyc +..\wrapt\__pycache__\decorators.cpython-37.pyc +..\wrapt\__pycache__\importer.cpython-37.pyc +..\wrapt\__pycache__\wrappers.cpython-37.pyc +..\wrapt\arguments.py +..\wrapt\decorators.py +..\wrapt\importer.py +..\wrapt\wrappers.py +PKG-INFO +SOURCES.txt +dependency_links.txt +top_level.txt diff --git a/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/top_level.txt b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/top_level.txt new file mode 100644 index 0000000..ba11553 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt-1.10.11-py3.7.egg-info/top_level.txt @@ -0,0 +1 @@ +wrapt diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/__init__.py b/basic python programmes/venv/Lib/site-packages/wrapt/__init__.py new file mode 100644 index 0000000..182a1e1 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt/__init__.py @@ -0,0 +1,19 @@ +__version_info__ = ('1', '10', '11') +__version__ = '.'.join(__version_info__) + +from .wrappers import (ObjectProxy, CallableObjectProxy, FunctionWrapper, + BoundFunctionWrapper, WeakFunctionProxy, resolve_path, apply_patch, + wrap_object, wrap_object_attribute, function_wrapper, + wrap_function_wrapper, patch_function_wrapper, + transient_function_wrapper) + +from .decorators import (adapter_factory, AdapterFactory, decorator, + synchronized) + +from .importer import (register_post_import_hook, when_imported, + notify_module_loaded, discover_post_import_hooks) + +try: + from inspect import getcallargs +except ImportError: + from .arguments import getcallargs diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/__init__.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000..b2e2520 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/__init__.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/arguments.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/arguments.cpython-37.pyc new file mode 100644 index 0000000..d485f03 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/arguments.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/decorators.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/decorators.cpython-37.pyc new file mode 100644 index 0000000..338b601 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/decorators.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/importer.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/importer.cpython-37.pyc new file mode 100644 index 0000000..2b8a88b Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/importer.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/wrappers.cpython-37.pyc b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/wrappers.cpython-37.pyc new file mode 100644 index 0000000..bdd6794 Binary files /dev/null and b/basic python programmes/venv/Lib/site-packages/wrapt/__pycache__/wrappers.cpython-37.pyc differ diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/arguments.py b/basic python programmes/venv/Lib/site-packages/wrapt/arguments.py new file mode 100644 index 0000000..428ffae --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt/arguments.py @@ -0,0 +1,96 @@ +# This is a copy of the inspect.getcallargs() function from Python 2.7 +# so we can provide it for use under Python 2.6. As the code in this +# file derives from the Python distribution, it falls under the version +# of the PSF license used for Python 2.7. + +from inspect import getargspec, ismethod +import sys + +def getcallargs(func, *positional, **named): + """Get the mapping of arguments to values. + + A dict is returned, with keys the function argument names (including the + names of the * and ** arguments, if any), and values the respective bound + values from 'positional' and 'named'.""" + args, varargs, varkw, defaults = getargspec(func) + f_name = func.__name__ + arg2value = {} + + # The following closures are basically because of tuple parameter unpacking. + assigned_tuple_params = [] + def assign(arg, value): + if isinstance(arg, str): + arg2value[arg] = value + else: + assigned_tuple_params.append(arg) + value = iter(value) + for i, subarg in enumerate(arg): + try: + subvalue = next(value) + except StopIteration: + raise ValueError('need more than %d %s to unpack' % + (i, 'values' if i > 1 else 'value')) + assign(subarg, subvalue) + try: + next(value) + except StopIteration: + pass + else: + raise ValueError('too many values to unpack') + def is_assigned(arg): + if isinstance(arg, str): + return arg in arg2value + return arg in assigned_tuple_params + if ismethod(func) and func.im_self is not None: + # implicit 'self' (or 'cls' for classmethods) argument + positional = (func.im_self,) + positional + num_pos = len(positional) + num_total = num_pos + len(named) + num_args = len(args) + num_defaults = len(defaults) if defaults else 0 + for arg, value in zip(args, positional): + assign(arg, value) + if varargs: + if num_pos > num_args: + assign(varargs, positional[-(num_pos-num_args):]) + else: + assign(varargs, ()) + elif 0 < num_args < num_pos: + raise TypeError('%s() takes %s %d %s (%d given)' % ( + f_name, 'at most' if defaults else 'exactly', num_args, + 'arguments' if num_args > 1 else 'argument', num_total)) + elif num_args == 0 and num_total: + if varkw: + if num_pos: + # XXX: We should use num_pos, but Python also uses num_total: + raise TypeError('%s() takes exactly 0 arguments ' + '(%d given)' % (f_name, num_total)) + else: + raise TypeError('%s() takes no arguments (%d given)' % + (f_name, num_total)) + for arg in args: + if isinstance(arg, str) and arg in named: + if is_assigned(arg): + raise TypeError("%s() got multiple values for keyword " + "argument '%s'" % (f_name, arg)) + else: + assign(arg, named.pop(arg)) + if defaults: # fill in any missing values with the defaults + for arg, value in zip(args[-num_defaults:], defaults): + if not is_assigned(arg): + assign(arg, value) + if varkw: + assign(varkw, named) + elif named: + unexpected = next(iter(named)) + if isinstance(unexpected, unicode): + unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') + raise TypeError("%s() got an unexpected keyword argument '%s'" % + (f_name, unexpected)) + unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) + if unassigned: + num_required = num_args - num_defaults + raise TypeError('%s() takes %s %d %s (%d given)' % ( + f_name, 'at least' if defaults else 'exactly', num_required, + 'arguments' if num_required > 1 else 'argument', num_total)) + return arg2value diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/decorators.py b/basic python programmes/venv/Lib/site-packages/wrapt/decorators.py new file mode 100644 index 0000000..2ad3494 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt/decorators.py @@ -0,0 +1,512 @@ +"""This module implements decorators for implementing other decorators +as well as some commonly used decorators. + +""" + +import sys + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +if PY3: + string_types = str, + + import builtins + exec_ = getattr(builtins, "exec") + del builtins + +else: + string_types = basestring, + + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + +from functools import partial +from inspect import ismethod, isclass, formatargspec +from collections import namedtuple +from threading import Lock, RLock + +try: + from inspect import signature +except ImportError: + pass + +from .wrappers import (FunctionWrapper, BoundFunctionWrapper, ObjectProxy, + CallableObjectProxy) + +# Adapter wrapper for the wrapped function which will overlay certain +# properties from the adapter function onto the wrapped function so that +# functions such as inspect.getargspec(), inspect.getfullargspec(), +# inspect.signature() and inspect.getsource() return the correct results +# one would expect. + +class _AdapterFunctionCode(CallableObjectProxy): + + def __init__(self, wrapped_code, adapter_code): + super(_AdapterFunctionCode, self).__init__(wrapped_code) + self._self_adapter_code = adapter_code + + @property + def co_argcount(self): + return self._self_adapter_code.co_argcount + + @property + def co_code(self): + return self._self_adapter_code.co_code + + @property + def co_flags(self): + return self._self_adapter_code.co_flags + + @property + def co_kwonlyargcount(self): + return self._self_adapter_code.co_kwonlyargcount + + @property + def co_varnames(self): + return self._self_adapter_code.co_varnames + +class _AdapterFunctionSurrogate(CallableObjectProxy): + + def __init__(self, wrapped, adapter): + super(_AdapterFunctionSurrogate, self).__init__(wrapped) + self._self_adapter = adapter + + @property + def __code__(self): + return _AdapterFunctionCode(self.__wrapped__.__code__, + self._self_adapter.__code__) + + @property + def __defaults__(self): + return self._self_adapter.__defaults__ + + @property + def __kwdefaults__(self): + return self._self_adapter.__kwdefaults__ + + @property + def __signature__(self): + if 'signature' not in globals(): + return self._self_adapter.__signature__ + else: + # Can't allow this to fail on Python 3 else it falls + # through to using __wrapped__, but that will be the + # wrong function we want to derive the signature + # from. Thus generate the signature ourselves. + + return signature(self._self_adapter) + + if PY2: + func_code = __code__ + func_defaults = __defaults__ + +class _BoundAdapterWrapper(BoundFunctionWrapper): + + @property + def __func__(self): + return _AdapterFunctionSurrogate(self.__wrapped__.__func__, + self._self_parent._self_adapter) + + if PY2: + im_func = __func__ + +class AdapterWrapper(FunctionWrapper): + + __bound_function_wrapper__ = _BoundAdapterWrapper + + def __init__(self, *args, **kwargs): + adapter = kwargs.pop('adapter') + super(AdapterWrapper, self).__init__(*args, **kwargs) + self._self_surrogate = _AdapterFunctionSurrogate( + self.__wrapped__, adapter) + self._self_adapter = adapter + + @property + def __code__(self): + return self._self_surrogate.__code__ + + @property + def __defaults__(self): + return self._self_surrogate.__defaults__ + + @property + def __kwdefaults__(self): + return self._self_surrogate.__kwdefaults__ + + if PY2: + func_code = __code__ + func_defaults = __defaults__ + + @property + def __signature__(self): + return self._self_surrogate.__signature__ + +class AdapterFactory(object): + def __call__(self, wrapped): + raise NotImplementedError() + +class DelegatedAdapterFactory(AdapterFactory): + def __init__(self, factory): + super(DelegatedAdapterFactory, self).__init__() + self.factory = factory + def __call__(self, wrapped): + return self.factory(wrapped) + +adapter_factory = DelegatedAdapterFactory + +# Decorator for creating other decorators. This decorator and the +# wrappers which they use are designed to properly preserve any name +# attributes, function signatures etc, in addition to the wrappers +# themselves acting like a transparent proxy for the original wrapped +# function so the wrapper is effectively indistinguishable from the +# original wrapped function. + +def decorator(wrapper=None, enabled=None, adapter=None): + # The decorator should be supplied with a single positional argument + # which is the wrapper function to be used to implement the + # decorator. This may be preceded by a step whereby the keyword + # arguments are supplied to customise the behaviour of the + # decorator. The 'adapter' argument is used to optionally denote a + # separate function which is notionally used by an adapter + # decorator. In that case parts of the function '__code__' and + # '__defaults__' attributes are used from the adapter function + # rather than those of the wrapped function. This allows for the + # argument specification from inspect.getargspec() and similar + # functions to be overridden with a prototype for a different + # function than what was wrapped. The 'enabled' argument provides a + # way to enable/disable the use of the decorator. If the type of + # 'enabled' is a boolean, then it is evaluated immediately and the + # wrapper not even applied if it is False. If not a boolean, it will + # be evaluated when the wrapper is called for an unbound wrapper, + # and when binding occurs for a bound wrapper. When being evaluated, + # if 'enabled' is callable it will be called to obtain the value to + # be checked. If False, the wrapper will not be called and instead + # the original wrapped function will be called directly instead. + + if wrapper is not None: + # Helper function for creating wrapper of the appropriate + # time when we need it down below. + + def _build(wrapped, wrapper, enabled=None, adapter=None): + if adapter: + if isinstance(adapter, AdapterFactory): + adapter = adapter(wrapped) + + if not callable(adapter): + ns = {} + if not isinstance(adapter, string_types): + adapter = formatargspec(*adapter) + exec_('def adapter{0}: pass'.format(adapter), ns, ns) + adapter = ns['adapter'] + + return AdapterWrapper(wrapped=wrapped, wrapper=wrapper, + enabled=enabled, adapter=adapter) + + return FunctionWrapper(wrapped=wrapped, wrapper=wrapper, + enabled=enabled) + + # The wrapper has been provided so return the final decorator. + # The decorator is itself one of our function wrappers so we + # can determine when it is applied to functions, instance methods + # or class methods. This allows us to bind the instance or class + # method so the appropriate self or cls attribute is supplied + # when it is finally called. + + def _wrapper(wrapped, instance, args, kwargs): + # We first check for the case where the decorator was applied + # to a class type. + # + # @decorator + # class mydecoratorclass(object): + # def __init__(self, arg=None): + # self.arg = arg + # def __call__(self, wrapped, instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorclass(arg=1) + # def function(): + # pass + # + # In this case an instance of the class is to be used as the + # decorator wrapper function. If args was empty at this point, + # then it means that there were optional keyword arguments + # supplied to be used when creating an instance of the class + # to be used as the wrapper function. + + if instance is None and isclass(wrapped) and not args: + # We still need to be passed the target function to be + # wrapped as yet, so we need to return a further function + # to be able to capture it. + + def _capture(target_wrapped): + # Now have the target function to be wrapped and need + # to create an instance of the class which is to act + # as the decorator wrapper function. Before we do that, + # we need to first check that use of the decorator + # hadn't been disabled by a simple boolean. If it was, + # the target function to be wrapped is returned instead. + + _enabled = enabled + if type(_enabled) is bool: + if not _enabled: + return target_wrapped + _enabled = None + + # Now create an instance of the class which is to act + # as the decorator wrapper function. Any arguments had + # to be supplied as keyword only arguments so that is + # all we pass when creating it. + + target_wrapper = wrapped(**kwargs) + + # Finally build the wrapper itself and return it. + + return _build(target_wrapped, target_wrapper, + _enabled, adapter) + + return _capture + + # We should always have the target function to be wrapped at + # this point as the first (and only) value in args. + + target_wrapped = args[0] + + # Need to now check that use of the decorator hadn't been + # disabled by a simple boolean. If it was, then target + # function to be wrapped is returned instead. + + _enabled = enabled + if type(_enabled) is bool: + if not _enabled: + return target_wrapped + _enabled = None + + # We now need to build the wrapper, but there are a couple of + # different cases we need to consider. + + if instance is None: + if isclass(wrapped): + # In this case the decorator was applied to a class + # type but optional keyword arguments were not supplied + # for initialising an instance of the class to be used + # as the decorator wrapper function. + # + # @decorator + # class mydecoratorclass(object): + # def __init__(self, arg=None): + # self.arg = arg + # def __call__(self, wrapped, instance, + # args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorclass + # def function(): + # pass + # + # We still need to create an instance of the class to + # be used as the decorator wrapper function, but no + # arguments are pass. + + target_wrapper = wrapped() + + else: + # In this case the decorator was applied to a normal + # function, or possibly a static method of a class. + # + # @decorator + # def mydecoratorfuntion(wrapped, instance, + # args, kwargs): + # return wrapped(*args, **kwargs) + # + # @mydecoratorfunction + # def function(): + # pass + # + # That normal function becomes the decorator wrapper + # function. + + target_wrapper = wrapper + + else: + if isclass(instance): + # In this case the decorator was applied to a class + # method. + # + # class myclass(object): + # @decorator + # @classmethod + # def decoratorclassmethod(cls, wrapped, + # instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # instance = myclass() + # + # @instance.decoratorclassmethod + # def function(): + # pass + # + # This one is a bit strange because binding was actually + # performed on the wrapper created by our decorator + # factory. We need to apply that binding to the decorator + # wrapper function which which the decorator factory + # was applied to. + + target_wrapper = wrapper.__get__(None, instance) + + else: + # In this case the decorator was applied to an instance + # method. + # + # class myclass(object): + # @decorator + # def decoratorclassmethod(self, wrapped, + # instance, args, kwargs): + # return wrapped(*args, **kwargs) + # + # instance = myclass() + # + # @instance.decoratorclassmethod + # def function(): + # pass + # + # This one is a bit strange because binding was actually + # performed on the wrapper created by our decorator + # factory. We need to apply that binding to the decorator + # wrapper function which which the decorator factory + # was applied to. + + target_wrapper = wrapper.__get__(instance, type(instance)) + + # Finally build the wrapper itself and return it. + + return _build(target_wrapped, target_wrapper, _enabled, adapter) + + # We first return our magic function wrapper here so we can + # determine in what context the decorator factory was used. In + # other words, it is itself a universal decorator. + + return _build(wrapper, _wrapper) + + else: + # The wrapper still has not been provided, so we are just + # collecting the optional keyword arguments. Return the + # decorator again wrapped in a partial using the collected + # arguments. + + return partial(decorator, enabled=enabled, adapter=adapter) + +# Decorator for implementing thread synchronization. It can be used as a +# decorator, in which case the synchronization context is determined by +# what type of function is wrapped, or it can also be used as a context +# manager, where the user needs to supply the correct synchronization +# context. It is also possible to supply an object which appears to be a +# synchronization primitive of some sort, by virtue of having release() +# and acquire() methods. In that case that will be used directly as the +# synchronization primitive without creating a separate lock against the +# derived or supplied context. + +def synchronized(wrapped): + # Determine if being passed an object which is a synchronization + # primitive. We can't check by type for Lock, RLock, Semaphore etc, + # as the means of creating them isn't the type. Therefore use the + # existence of acquire() and release() methods. This is more + # extensible anyway as it allows custom synchronization mechanisms. + + if hasattr(wrapped, 'acquire') and hasattr(wrapped, 'release'): + # We remember what the original lock is and then return a new + # decorator which accesses and locks it. When returning the new + # decorator we wrap it with an object proxy so we can override + # the context manager methods in case it is being used to wrap + # synchronized statements with a 'with' statement. + + lock = wrapped + + @decorator + def _synchronized(wrapped, instance, args, kwargs): + # Execute the wrapped function while the original supplied + # lock is held. + + with lock: + return wrapped(*args, **kwargs) + + class _PartialDecorator(CallableObjectProxy): + + def __enter__(self): + lock.acquire() + return lock + + def __exit__(self, *args): + lock.release() + + return _PartialDecorator(wrapped=_synchronized) + + # Following only apply when the lock is being created automatically + # based on the context of what was supplied. In this case we supply + # a final decorator, but need to use FunctionWrapper directly as we + # want to derive from it to add context manager methods in case it is + # being used to wrap synchronized statements with a 'with' statement. + + def _synchronized_lock(context): + # Attempt to retrieve the lock for the specific context. + + lock = vars(context).get('_synchronized_lock', None) + + if lock is None: + # There is no existing lock defined for the context we + # are dealing with so we need to create one. This needs + # to be done in a way to guarantee there is only one + # created, even if multiple threads try and create it at + # the same time. We can't always use the setdefault() + # method on the __dict__ for the context. This is the + # case where the context is a class, as __dict__ is + # actually a dictproxy. What we therefore do is use a + # meta lock on this wrapper itself, to control the + # creation and assignment of the lock attribute against + # the context. + + meta_lock = vars(synchronized).setdefault( + '_synchronized_meta_lock', Lock()) + + with meta_lock: + # We need to check again for whether the lock we want + # exists in case two threads were trying to create it + # at the same time and were competing to create the + # meta lock. + + lock = vars(context).get('_synchronized_lock', None) + + if lock is None: + lock = RLock() + setattr(context, '_synchronized_lock', lock) + + return lock + + def _synchronized_wrapper(wrapped, instance, args, kwargs): + # Execute the wrapped function while the lock for the + # desired context is held. If instance is None then the + # wrapped function is used as the context. + + with _synchronized_lock(instance or wrapped): + return wrapped(*args, **kwargs) + + class _FinalDecorator(FunctionWrapper): + + def __enter__(self): + self._self_lock = _synchronized_lock(self.__wrapped__) + self._self_lock.acquire() + return self._self_lock + + def __exit__(self, *args): + self._self_lock.release() + + return _FinalDecorator(wrapped=wrapped, wrapper=_synchronized_wrapper) diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/importer.py b/basic python programmes/venv/Lib/site-packages/wrapt/importer.py new file mode 100644 index 0000000..7fd2d8d --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt/importer.py @@ -0,0 +1,228 @@ +"""This module implements a post import hook mechanism styled after what is +described in PEP-369. Note that it doesn't cope with modules being reloaded. + +""" + +import sys +import threading + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +if PY3: + import importlib + string_types = str, +else: + string_types = basestring, + +from .decorators import synchronized + +# The dictionary registering any post import hooks to be triggered once +# the target module has been imported. Once a module has been imported +# and the hooks fired, the list of hooks recorded against the target +# module will be truncacted but the list left in the dictionary. This +# acts as a flag to indicate that the module had already been imported. + +_post_import_hooks = {} +_post_import_hooks_init = False +_post_import_hooks_lock = threading.RLock() + +# Register a new post import hook for the target module name. This +# differs from the PEP-369 implementation in that it also allows the +# hook function to be specified as a string consisting of the name of +# the callback in the form 'module:function'. This will result in a +# proxy callback being registered which will defer loading of the +# specified module containing the callback function until required. + +def _create_import_hook_from_string(name): + def import_hook(module): + module_name, function = name.split(':') + attrs = function.split('.') + __import__(module_name) + callback = sys.modules[module_name] + for attr in attrs: + callback = getattr(callback, attr) + return callback(module) + return import_hook + +@synchronized(_post_import_hooks_lock) +def register_post_import_hook(hook, name): + # Create a deferred import hook if hook is a string name rather than + # a callable function. + + if isinstance(hook, string_types): + hook = _create_import_hook_from_string(hook) + + # Automatically install the import hook finder if it has not already + # been installed. + + global _post_import_hooks_init + + if not _post_import_hooks_init: + _post_import_hooks_init = True + sys.meta_path.insert(0, ImportHookFinder()) + + # Determine if any prior registration of a post import hook for + # the target modules has occurred and act appropriately. + + hooks = _post_import_hooks.get(name, None) + + if hooks is None: + # No prior registration of post import hooks for the target + # module. We need to check whether the module has already been + # imported. If it has we fire the hook immediately and add an + # empty list to the registry to indicate that the module has + # already been imported and hooks have fired. Otherwise add + # the post import hook to the registry. + + module = sys.modules.get(name, None) + + if module is not None: + _post_import_hooks[name] = [] + hook(module) + + else: + _post_import_hooks[name] = [hook] + + elif hooks == []: + # A prior registration of port import hooks for the target + # module was done and the hooks already fired. Fire the hook + # immediately. + + module = sys.modules[name] + hook(module) + + else: + # A prior registration of port import hooks for the target + # module was done but the module has not yet been imported. + + _post_import_hooks[name].append(hook) + +# Register post import hooks defined as package entry points. + +def _create_import_hook_from_entrypoint(entrypoint): + def import_hook(module): + __import__(entrypoint.module_name) + callback = sys.modules[entrypoint.module_name] + for attr in entrypoint.attrs: + callback = getattr(callback, attr) + return callback(module) + return import_hook + +def discover_post_import_hooks(group): + try: + import pkg_resources + except ImportError: + return + + for entrypoint in pkg_resources.iter_entry_points(group=group): + callback = _create_import_hook_from_entrypoint(entrypoint) + register_post_import_hook(callback, entrypoint.name) + +# Indicate that a module has been loaded. Any post import hooks which +# were registered against the target module will be invoked. If an +# exception is raised in any of the post import hooks, that will cause +# the import of the target module to fail. + +@synchronized(_post_import_hooks_lock) +def notify_module_loaded(module): + name = getattr(module, '__name__', None) + hooks = _post_import_hooks.get(name, None) + + if hooks: + _post_import_hooks[name] = [] + + for hook in hooks: + hook(module) + +# A custom module import finder. This intercepts attempts to import +# modules and watches out for attempts to import target modules of +# interest. When a module of interest is imported, then any post import +# hooks which are registered will be invoked. + +class _ImportHookLoader: + + def load_module(self, fullname): + module = sys.modules[fullname] + notify_module_loaded(module) + + return module + +class _ImportHookChainedLoader: + + def __init__(self, loader): + self.loader = loader + + def load_module(self, fullname): + module = self.loader.load_module(fullname) + notify_module_loaded(module) + + return module + +class ImportHookFinder: + + def __init__(self): + self.in_progress = {} + + @synchronized(_post_import_hooks_lock) + def find_module(self, fullname, path=None): + # If the module being imported is not one we have registered + # post import hooks for, we can return immediately. We will + # take no further part in the importing of this module. + + if not fullname in _post_import_hooks: + return None + + # When we are interested in a specific module, we will call back + # into the import system a second time to defer to the import + # finder that is supposed to handle the importing of the module. + # We set an in progress flag for the target module so that on + # the second time through we don't trigger another call back + # into the import system and cause a infinite loop. + + if fullname in self.in_progress: + return None + + self.in_progress[fullname] = True + + # Now call back into the import system again. + + try: + if PY3: + # For Python 3 we need to use find_loader() from + # the importlib module. It doesn't actually + # import the target module and only finds the + # loader. If a loader is found, we need to return + # our own loader which will then in turn call the + # real loader to import the module and invoke the + # post import hooks. + + loader = importlib.find_loader(fullname, path) + + if loader: + return _ImportHookChainedLoader(loader) + + else: + # For Python 2 we don't have much choice but to + # call back in to __import__(). This will + # actually cause the module to be imported. If no + # module could be found then ImportError will be + # raised. Otherwise we return a loader which + # returns the already loaded module and invokes + # the post import hooks. + + __import__(fullname) + + return _ImportHookLoader() + + finally: + del self.in_progress[fullname] + +# Decorator for marking that a function should be called as a post +# import hook when the target module is imported. + +def when_imported(name): + def register(hook): + register_post_import_hook(hook, name) + return hook + return register diff --git a/basic python programmes/venv/Lib/site-packages/wrapt/wrappers.py b/basic python programmes/venv/Lib/site-packages/wrapt/wrappers.py new file mode 100644 index 0000000..2125305 --- /dev/null +++ b/basic python programmes/venv/Lib/site-packages/wrapt/wrappers.py @@ -0,0 +1,901 @@ +import os +import sys +import functools +import operator +import weakref +import inspect + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +if PY3: + string_types = str, +else: + string_types = basestring, + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + return meta("NewBase", bases, {}) + +class _ObjectProxyMethods(object): + + # We use properties to override the values of __module__ and + # __doc__. If we add these in ObjectProxy, the derived class + # __dict__ will still be setup to have string variants of these + # attributes and the rules of descriptors means that they appear to + # take precedence over the properties in the base class. To avoid + # that, we copy the properties into the derived class type itself + # via a meta class. In that way the properties will always take + # precedence. + + @property + def __module__(self): + return self.__wrapped__.__module__ + + @__module__.setter + def __module__(self, value): + self.__wrapped__.__module__ = value + + @property + def __doc__(self): + return self.__wrapped__.__doc__ + + @__doc__.setter + def __doc__(self, value): + self.__wrapped__.__doc__ = value + + # We similar use a property for __dict__. We need __dict__ to be + # explicit to ensure that vars() works as expected. + + @property + def __dict__(self): + return self.__wrapped__.__dict__ + + # Need to also propagate the special __weakref__ attribute for case + # where decorating classes which will define this. If do not define + # it and use a function like inspect.getmembers() on a decorator + # class it will fail. This can't be in the derived classes. + + @property + def __weakref__(self): + return self.__wrapped__.__weakref__ + +class _ObjectProxyMetaType(type): + def __new__(cls, name, bases, dictionary): + # Copy our special properties into the class so that they + # always take precedence over attributes of the same name added + # during construction of a derived class. This is to save + # duplicating the implementation for them in all derived classes. + + dictionary.update(vars(_ObjectProxyMethods)) + + return type.__new__(cls, name, bases, dictionary) + +class ObjectProxy(with_metaclass(_ObjectProxyMetaType)): + + __slots__ = '__wrapped__' + + def __init__(self, wrapped): + object.__setattr__(self, '__wrapped__', wrapped) + + # Python 3.2+ has the __qualname__ attribute, but it does not + # allow it to be overridden using a property and it must instead + # be an actual string object instead. + + try: + object.__setattr__(self, '__qualname__', wrapped.__qualname__) + except AttributeError: + pass + + @property + def __name__(self): + return self.__wrapped__.__name__ + + @__name__.setter + def __name__(self, value): + self.__wrapped__.__name__ = value + + @property + def __class__(self): + return self.__wrapped__.__class__ + + @__class__.setter + def __class__(self, value): + self.__wrapped__.__class__ = value + + @property + def __annotations__(self): + return self.__wrapped__.__anotations__ + + @__annotations__.setter + def __annotations__(self, value): + self.__wrapped__.__annotations__ = value + + def __dir__(self): + return dir(self.__wrapped__) + + def __str__(self): + return str(self.__wrapped__) + + if PY3: + def __bytes__(self): + return bytes(self.__wrapped__) + + def __repr__(self): + return '<%s at 0x%x for %s at 0x%x>' % ( + type(self).__name__, id(self), + type(self.__wrapped__).__name__, + id(self.__wrapped__)) + + def __reversed__(self): + return reversed(self.__wrapped__) + + if PY3: + def __round__(self): + return round(self.__wrapped__) + + def __lt__(self, other): + return self.__wrapped__ < other + + def __le__(self, other): + return self.__wrapped__ <= other + + def __eq__(self, other): + return self.__wrapped__ == other + + def __ne__(self, other): + return self.__wrapped__ != other + + def __gt__(self, other): + return self.__wrapped__ > other + + def __ge__(self, other): + return self.__wrapped__ >= other + + def __hash__(self): + return hash(self.__wrapped__) + + def __nonzero__(self): + return bool(self.__wrapped__) + + def __bool__(self): + return bool(self.__wrapped__) + + def __setattr__(self, name, value): + if name.startswith('_self_'): + object.__setattr__(self, name, value) + + elif name == '__wrapped__': + object.__setattr__(self, name, value) + try: + object.__delattr__(self, '__qualname__') + except AttributeError: + pass + try: + object.__setattr__(self, '__qualname__', value.__qualname__) + except AttributeError: + pass + + elif name == '__qualname__': + setattr(self.__wrapped__, name, value) + object.__setattr__(self, name, value) + + elif hasattr(type(self), name): + object.__setattr__(self, name, value) + + else: + setattr(self.__wrapped__, name, value) + + def __getattr__(self, name): + # If we are being to lookup '__wrapped__' then the + # '__init__()' method cannot have been called. + + if name == '__wrapped__': + raise ValueError('wrapper has not been initialised') + + return getattr(self.__wrapped__, name) + + def __delattr__(self, name): + if name.startswith('_self_'): + object.__delattr__(self, name) + + elif name == '__wrapped__': + raise TypeError('__wrapped__ must be an object') + + elif name == '__qualname__': + object.__delattr__(self, name) + delattr(self.__wrapped__, name) + + elif hasattr(type(self), name): + object.__delattr__(self, name) + + else: + delattr(self.__wrapped__, name) + + def __add__(self, other): + return self.__wrapped__ + other + + def __sub__(self, other): + return self.__wrapped__ - other + + def __mul__(self, other): + return self.__wrapped__ * other + + def __div__(self, other): + return operator.div(self.__wrapped__, other) + + def __truediv__(self, other): + return operator.truediv(self.__wrapped__, other) + + def __floordiv__(self, other): + return self.__wrapped__ // other + + def __mod__(self, other): + return self.__wrapped__ % other + + def __divmod__(self, other): + return divmod(self.__wrapped__, other) + + def __pow__(self, other, *args): + return pow(self.__wrapped__, other, *args) + + def __lshift__(self, other): + return self.__wrapped__ << other + + def __rshift__(self, other): + return self.__wrapped__ >> other + + def __and__(self, other): + return self.__wrapped__ & other + + def __xor__(self, other): + return self.__wrapped__ ^ other + + def __or__(self, other): + return self.__wrapped__ | other + + def __radd__(self, other): + return other + self.__wrapped__ + + def __rsub__(self, other): + return other - self.__wrapped__ + + def __rmul__(self, other): + return other * self.__wrapped__ + + def __rdiv__(self, other): + return operator.div(other, self.__wrapped__) + + def __rtruediv__(self, other): + return operator.truediv(other, self.__wrapped__) + + def __rfloordiv__(self, other): + return other // self.__wrapped__ + + def __rmod__(self, other): + return other % self.__wrapped__ + + def __rdivmod__(self, other): + return divmod(other, self.__wrapped__) + + def __rpow__(self, other, *args): + return pow(other, self.__wrapped__, *args) + + def __rlshift__(self, other): + return other << self.__wrapped__ + + def __rrshift__(self, other): + return other >> self.__wrapped__ + + def __rand__(self, other): + return other & self.__wrapped__ + + def __rxor__(self, other): + return other ^ self.__wrapped__ + + def __ror__(self, other): + return other | self.__wrapped__ + + def __iadd__(self, other): + self.__wrapped__ += other + return self + + def __isub__(self, other): + self.__wrapped__ -= other + return self + + def __imul__(self, other): + self.__wrapped__ *= other + return self + + def __idiv__(self, other): + self.__wrapped__ = operator.idiv(self.__wrapped__, other) + return self + + def __itruediv__(self, other): + self.__wrapped__ = operator.itruediv(self.__wrapped__, other) + return self + + def __ifloordiv__(self, other): + self.__wrapped__ //= other + return self + + def __imod__(self, other): + self.__wrapped__ %= other + return self + + def __ipow__(self, other): + self.__wrapped__ **= other + return self + + def __ilshift__(self, other): + self.__wrapped__ <<= other + return self + + def __irshift__(self, other): + self.__wrapped__ >>= other + return self + + def __iand__(self, other): + self.__wrapped__ &= other + return self + + def __ixor__(self, other): + self.__wrapped__ ^= other + return self + + def __ior__(self, other): + self.__wrapped__ |= other + return self + + def __neg__(self): + return -self.__wrapped__ + + def __pos__(self): + return +self.__wrapped__ + + def __abs__(self): + return abs(self.__wrapped__) + + def __invert__(self): + return ~self.__wrapped__ + + def __int__(self): + return int(self.__wrapped__) + + def __long__(self): + return long(self.__wrapped__) + + def __float__(self): + return float(self.__wrapped__) + + def __oct__(self): + return oct(self.__wrapped__) + + def __hex__(self): + return hex(self.__wrapped__) + + def __index__(self): + return operator.index(self.__wrapped__) + + def __len__(self): + return len(self.__wrapped__) + + def __contains__(self, value): + return value in self.__wrapped__ + + def __getitem__(self, key): + return self.__wrapped__[key] + + def __setitem__(self, key, value): + self.__wrapped__[key] = value + + def __delitem__(self, key): + del self.__wrapped__[key] + + def __getslice__(self, i, j): + return self.__wrapped__[i:j] + + def __setslice__(self, i, j, value): + self.__wrapped__[i:j] = value + + def __delslice__(self, i, j): + del self.__wrapped__[i:j] + + def __enter__(self): + return self.__wrapped__.__enter__() + + def __exit__(self, *args, **kwargs): + return self.__wrapped__.__exit__(*args, **kwargs) + + def __iter__(self): + return iter(self.__wrapped__) + +class CallableObjectProxy(ObjectProxy): + + def __call__(self, *args, **kwargs): + return self.__wrapped__(*args, **kwargs) + +class _FunctionWrapperBase(ObjectProxy): + + __slots__ = ('_self_instance', '_self_wrapper', '_self_enabled', + '_self_binding', '_self_parent') + + def __init__(self, wrapped, instance, wrapper, enabled=None, + binding='function', parent=None): + + super(_FunctionWrapperBase, self).__init__(wrapped) + + object.__setattr__(self, '_self_instance', instance) + object.__setattr__(self, '_self_wrapper', wrapper) + object.__setattr__(self, '_self_enabled', enabled) + object.__setattr__(self, '_self_binding', binding) + object.__setattr__(self, '_self_parent', parent) + + def __get__(self, instance, owner): + # This method is actually doing double duty for both unbound and + # bound derived wrapper classes. It should possibly be broken up + # and the distinct functionality moved into the derived classes. + # Can't do that straight away due to some legacy code which is + # relying on it being here in this base class. + # + # The distinguishing attribute which determines whether we are + # being called in an unbound or bound wrapper is the parent + # attribute. If binding has never occurred, then the parent will + # be None. + # + # First therefore, is if we are called in an unbound wrapper. In + # this case we perform the binding. + # + # We have one special case to worry about here. This is where we + # are decorating a nested class. In this case the wrapped class + # would not have a __get__() method to call. In that case we + # simply return self. + # + # Note that we otherwise still do binding even if instance is + # None and accessing an unbound instance method from a class. + # This is because we need to be able to later detect that + # specific case as we will need to extract the instance from the + # first argument of those passed in. + + if self._self_parent is None: + if not inspect.isclass(self.__wrapped__): + descriptor = self.__wrapped__.__get__(instance, owner) + + return self.__bound_function_wrapper__(descriptor, instance, + self._self_wrapper, self._self_enabled, + self._self_binding, self) + + return self + + # Now we have the case of binding occurring a second time on what + # was already a bound function. In this case we would usually + # return ourselves again. This mirrors what Python does. + # + # The special case this time is where we were originally bound + # with an instance of None and we were likely an instance + # method. In that case we rebind against the original wrapped + # function from the parent again. + + if self._self_instance is None and self._self_binding == 'function': + descriptor = self._self_parent.__wrapped__.__get__( + instance, owner) + + return self._self_parent.__bound_function_wrapper__( + descriptor, instance, self._self_wrapper, + self._self_enabled, self._self_binding, + self._self_parent) + + return self + + def __call__(self, *args, **kwargs): + # If enabled has been specified, then evaluate it at this point + # and if the wrapper is not to be executed, then simply return + # the bound function rather than a bound wrapper for the bound + # function. When evaluating enabled, if it is callable we call + # it, otherwise we evaluate it as a boolean. + + if self._self_enabled is not None: + if callable(self._self_enabled): + if not self._self_enabled(): + return self.__wrapped__(*args, **kwargs) + elif not self._self_enabled: + return self.__wrapped__(*args, **kwargs) + + # This can occur where initial function wrapper was applied to + # a function that was already bound to an instance. In that case + # we want to extract the instance from the function and use it. + + if self._self_binding == 'function': + if self._self_instance is None: + instance = getattr(self.__wrapped__, '__self__', None) + if instance is not None: + return self._self_wrapper(self.__wrapped__, instance, + args, kwargs) + + # This is generally invoked when the wrapped function is being + # called as a normal function and is not bound to a class as an + # instance method. This is also invoked in the case where the + # wrapped function was a method, but this wrapper was in turn + # wrapped using the staticmethod decorator. + + return self._self_wrapper(self.__wrapped__, self._self_instance, + args, kwargs) + +class BoundFunctionWrapper(_FunctionWrapperBase): + + def __call__(self, *args, **kwargs): + # If enabled has been specified, then evaluate it at this point + # and if the wrapper is not to be executed, then simply return + # the bound function rather than a bound wrapper for the bound + # function. When evaluating enabled, if it is callable we call + # it, otherwise we evaluate it as a boolean. + + if self._self_enabled is not None: + if callable(self._self_enabled): + if not self._self_enabled(): + return self.__wrapped__(*args, **kwargs) + elif not self._self_enabled: + return self.__wrapped__(*args, **kwargs) + + # We need to do things different depending on whether we are + # likely wrapping an instance method vs a static method or class + # method. + + if self._self_binding == 'function': + if self._self_instance is None: + # This situation can occur where someone is calling the + # instancemethod via the class type and passing the instance + # as the first argument. We need to shift the args before + # making the call to the wrapper and effectively bind the + # instance to the wrapped function using a partial so the + # wrapper doesn't see anything as being different. + + if not args: + raise TypeError('missing 1 required positional argument') + + instance, args = args[0], args[1:] + wrapped = functools.partial(self.__wrapped__, instance) + return self._self_wrapper(wrapped, instance, args, kwargs) + + return self._self_wrapper(self.__wrapped__, self._self_instance, + args, kwargs) + + else: + # As in this case we would be dealing with a classmethod or + # staticmethod, then _self_instance will only tell us whether + # when calling the classmethod or staticmethod they did it via an + # instance of the class it is bound to and not the case where + # done by the class type itself. We thus ignore _self_instance + # and use the __self__ attribute of the bound function instead. + # For a classmethod, this means instance will be the class type + # and for a staticmethod it will be None. This is probably the + # more useful thing we can pass through even though we loose + # knowledge of whether they were called on the instance vs the + # class type, as it reflects what they have available in the + # decoratored function. + + instance = getattr(self.__wrapped__, '__self__', None) + + return self._self_wrapper(self.__wrapped__, instance, args, + kwargs) + +class FunctionWrapper(_FunctionWrapperBase): + + __bound_function_wrapper__ = BoundFunctionWrapper + + def __init__(self, wrapped, wrapper, enabled=None): + # What it is we are wrapping here could be anything. We need to + # try and detect specific cases though. In particular, we need + # to detect when we are given something that is a method of a + # class. Further, we need to know when it is likely an instance + # method, as opposed to a class or static method. This can + # become problematic though as there isn't strictly a fool proof + # method of knowing. + # + # The situations we could encounter when wrapping a method are: + # + # 1. The wrapper is being applied as part of a decorator which + # is a part of the class definition. In this case what we are + # given is the raw unbound function, classmethod or staticmethod + # wrapper objects. + # + # The problem here is that we will not know we are being applied + # in the context of the class being set up. This becomes + # important later for the case of an instance method, because in + # that case we just see it as a raw function and can't + # distinguish it from wrapping a normal function outside of + # a class context. + # + # 2. The wrapper is being applied when performing monkey + # patching of the class type afterwards and the method to be + # wrapped was retrieved direct from the __dict__ of the class + # type. This is effectively the same as (1) above. + # + # 3. The wrapper is being applied when performing monkey + # patching of the class type afterwards and the method to be + # wrapped was retrieved from the class type. In this case + # binding will have been performed where the instance against + # which the method is bound will be None at that point. + # + # This case is a problem because we can no longer tell if the + # method was a static method, plus if using Python3, we cannot + # tell if it was an instance method as the concept of an + # unnbound method no longer exists. + # + # 4. The wrapper is being applied when performing monkey + # patching of an instance of a class. In this case binding will + # have been perfomed where the instance was not None. + # + # This case is a problem because we can no longer tell if the + # method was a static method. + # + # Overall, the best we can do is look at the original type of the + # object which was wrapped prior to any binding being done and + # see if it is an instance of classmethod or staticmethod. In + # the case where other decorators are between us and them, if + # they do not propagate the __class__ attribute so that the + # isinstance() checks works, then likely this will do the wrong + # thing where classmethod and staticmethod are used. + # + # Since it is likely to be very rare that anyone even puts + # decorators around classmethod and staticmethod, likelihood of + # that being an issue is very small, so we accept it and suggest + # that those other decorators be fixed. It is also only an issue + # if a decorator wants to actually do things with the arguments. + # + # As to not being able to identify static methods properly, we + # just hope that that isn't something people are going to want + # to wrap, or if they do suggest they do it the correct way by + # ensuring that it is decorated in the class definition itself, + # or patch it in the __dict__ of the class type. + # + # So to get the best outcome we can, whenever we aren't sure what + # it is, we label it as a 'function'. If it was already bound and + # that is rebound later, we assume that it will be an instance + # method and try an cope with the possibility that the 'self' + # argument it being passed as an explicit argument and shuffle + # the arguments around to extract 'self' for use as the instance. + + if isinstance(wrapped, classmethod): + binding = 'classmethod' + + elif isinstance(wrapped, staticmethod): + binding = 'staticmethod' + + elif hasattr(wrapped, '__self__'): + if inspect.isclass(wrapped.__self__): + binding = 'classmethod' + else: + binding = 'function' + + else: + binding = 'function' + + super(FunctionWrapper, self).__init__(wrapped, None, wrapper, + enabled, binding) + +try: + if not os.environ.get('WRAPT_DISABLE_EXTENSIONS'): + from ._wrappers import (ObjectProxy, CallableObjectProxy, + FunctionWrapper, BoundFunctionWrapper, _FunctionWrapperBase) +except ImportError: + pass + +# Helper functions for applying wrappers to existing functions. + +def resolve_path(module, name): + if isinstance(module, string_types): + __import__(module) + module = sys.modules[module] + + parent = module + + path = name.split('.') + attribute = path[0] + + original = getattr(parent, attribute) + for attribute in path[1:]: + parent = original + + # We can't just always use getattr() because in doing + # that on a class it will cause binding to occur which + # will complicate things later and cause some things not + # to work. For the case of a class we therefore access + # the __dict__ directly. To cope though with the wrong + # class being given to us, or a method being moved into + # a base class, we need to walk the class hierarchy to + # work out exactly which __dict__ the method was defined + # in, as accessing it from __dict__ will fail if it was + # not actually on the class given. Fallback to using + # getattr() if we can't find it. If it truly doesn't + # exist, then that will fail. + + if inspect.isclass(original): + for cls in inspect.getmro(original): + if attribute in vars(cls): + original = vars(cls)[attribute] + break + else: + original = getattr(original, attribute) + + else: + original = getattr(original, attribute) + + return (parent, attribute, original) + +def apply_patch(parent, attribute, replacement): + setattr(parent, attribute, replacement) + +def wrap_object(module, name, factory, args=(), kwargs={}): + (parent, attribute, original) = resolve_path(module, name) + wrapper = factory(original, *args, **kwargs) + apply_patch(parent, attribute, wrapper) + return wrapper + +# Function for applying a proxy object to an attribute of a class +# instance. The wrapper works by defining an attribute of the same name +# on the class which is a descriptor and which intercepts access to the +# instance attribute. Note that this cannot be used on attributes which +# are themselves defined by a property object. + +class AttributeWrapper(object): + + def __init__(self, attribute, factory, args, kwargs): + self.attribute = attribute + self.factory = factory + self.args = args + self.kwargs = kwargs + + def __get__(self, instance, owner): + value = instance.__dict__[self.attribute] + return self.factory(value, *self.args, **self.kwargs) + + def __set__(self, instance, value): + instance.__dict__[self.attribute] = value + + def __delete__(self, instance): + del instance.__dict__[self.attribute] + +def wrap_object_attribute(module, name, factory, args=(), kwargs={}): + path, attribute = name.rsplit('.', 1) + parent = resolve_path(module, path)[2] + wrapper = AttributeWrapper(attribute, factory, args, kwargs) + apply_patch(parent, attribute, wrapper) + return wrapper + +# Functions for creating a simple decorator using a FunctionWrapper, +# plus short cut functions for applying wrappers to functions. These are +# for use when doing monkey patching. For a more featured way of +# creating decorators see the decorator decorator instead. + +def function_wrapper(wrapper): + def _wrapper(wrapped, instance, args, kwargs): + target_wrapped = args[0] + if instance is None: + target_wrapper = wrapper + elif inspect.isclass(instance): + target_wrapper = wrapper.__get__(None, instance) + else: + target_wrapper = wrapper.__get__(instance, type(instance)) + return FunctionWrapper(target_wrapped, target_wrapper) + return FunctionWrapper(wrapper, _wrapper) + +def wrap_function_wrapper(module, name, wrapper): + return wrap_object(module, name, FunctionWrapper, (wrapper,)) + +def patch_function_wrapper(module, name): + def _wrapper(wrapper): + return wrap_object(module, name, FunctionWrapper, (wrapper,)) + return _wrapper + +def transient_function_wrapper(module, name): + def _decorator(wrapper): + def _wrapper(wrapped, instance, args, kwargs): + target_wrapped = args[0] + if instance is None: + target_wrapper = wrapper + elif inspect.isclass(instance): + target_wrapper = wrapper.__get__(None, instance) + else: + target_wrapper = wrapper.__get__(instance, type(instance)) + def _execute(wrapped, instance, args, kwargs): + (parent, attribute, original) = resolve_path(module, name) + replacement = FunctionWrapper(original, target_wrapper) + setattr(parent, attribute, replacement) + try: + return wrapped(*args, **kwargs) + finally: + setattr(parent, attribute, original) + return FunctionWrapper(target_wrapped, _execute) + return FunctionWrapper(wrapper, _wrapper) + return _decorator + +# A weak function proxy. This will work on instance methods, class +# methods, static methods and regular functions. Special treatment is +# needed for the method types because the bound method is effectively a +# transient object and applying a weak reference to one will immediately +# result in it being destroyed and the weakref callback called. The weak +# reference is therefore applied to the instance the method is bound to +# and the original function. The function is then rebound at the point +# of a call via the weak function proxy. + +def _weak_function_proxy_callback(ref, proxy, callback): + if proxy._self_expired: + return + + proxy._self_expired = True + + # This could raise an exception. We let it propagate back and let + # the weakref.proxy() deal with it, at which point it generally + # prints out a short error message direct to stderr and keeps going. + + if callback is not None: + callback(proxy) + +class WeakFunctionProxy(ObjectProxy): + + __slots__ = ('_self_expired', '_self_instance') + + def __init__(self, wrapped, callback=None): + # We need to determine if the wrapped function is actually a + # bound method. In the case of a bound method, we need to keep a + # reference to the original unbound function and the instance. + # This is necessary because if we hold a reference to the bound + # function, it will be the only reference and given it is a + # temporary object, it will almost immediately expire and + # the weakref callback triggered. So what is done is that we + # hold a reference to the instance and unbound function and + # when called bind the function to the instance once again and + # then call it. Note that we avoid using a nested function for + # the callback here so as not to cause any odd reference cycles. + + _callback = callback and functools.partial( + _weak_function_proxy_callback, proxy=self, + callback=callback) + + self._self_expired = False + + if isinstance(wrapped, _FunctionWrapperBase): + self._self_instance = weakref.ref(wrapped._self_instance, + _callback) + + if wrapped._self_parent is not None: + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped._self_parent, _callback)) + + else: + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped, _callback)) + + return + + try: + self._self_instance = weakref.ref(wrapped.__self__, _callback) + + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped.__func__, _callback)) + + except AttributeError: + self._self_instance = None + + super(WeakFunctionProxy, self).__init__( + weakref.proxy(wrapped, _callback)) + + def __call__(self, *args, **kwargs): + # We perform a boolean check here on the instance and wrapped + # function as that will trigger the reference error prior to + # calling if the reference had expired. + + instance = self._self_instance and self._self_instance() + function = self.__wrapped__ and self.__wrapped__ + + # If the wrapped function was originally a bound function, for + # which we retained a reference to the instance and the unbound + # function we need to rebind the function and then call it. If + # not just called the wrapped function. + + if instance is None: + return self.__wrapped__(*args, **kwargs) + + return function.__get__(instance, type(instance))(*args, **kwargs) diff --git a/basic python programmes/venv/Lib/tcl8.6/init.tcl b/basic python programmes/venv/Lib/tcl8.6/init.tcl new file mode 100644 index 0000000..b3990df --- /dev/null +++ b/basic python programmes/venv/Lib/tcl8.6/init.tcl @@ -0,0 +1,819 @@ +# init.tcl -- +# +# Default system startup file for Tcl-based applications. Defines +# "unknown" procedure and auto-load facilities. +# +# Copyright (c) 1991-1993 The Regents of the University of California. +# Copyright (c) 1994-1996 Sun Microsystems, Inc. +# Copyright (c) 1998-1999 Scriptics Corporation. +# Copyright (c) 2004 by Kevin B. Kenny. All rights reserved. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# + +# This test intentionally written in pre-7.5 Tcl +if {[info commands package] == ""} { + error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" +} +package require -exact Tcl 8.6.8 + +# Compute the auto path to use in this interpreter. +# The values on the path come from several locations: +# +# The environment variable TCLLIBPATH +# +# tcl_library, which is the directory containing this init.tcl script. +# [tclInit] (Tcl_Init()) searches around for the directory containing this +# init.tcl and defines tcl_library to that location before sourcing it. +# +# The parent directory of tcl_library. Adding the parent +# means that packages in peer directories will be found automatically. +# +# Also add the directory ../lib relative to the directory where the +# executable is located. This is meant to find binary packages for the +# same architecture as the current executable. +# +# tcl_pkgPath, which is set by the platform-specific initialization routines +# On UNIX it is compiled in +# On Windows, it is not used + +if {![info exists auto_path]} { + if {[info exists env(TCLLIBPATH)]} { + set auto_path $env(TCLLIBPATH) + } else { + set auto_path "" + } +} +namespace eval tcl { + variable Dir + foreach Dir [list $::tcl_library [file dirname $::tcl_library]] { + if {$Dir ni $::auto_path} { + lappend ::auto_path $Dir + } + } + set Dir [file join [file dirname [file dirname \ + [info nameofexecutable]]] lib] + if {$Dir ni $::auto_path} { + lappend ::auto_path $Dir + } + catch { + foreach Dir $::tcl_pkgPath { + if {$Dir ni $::auto_path} { + lappend ::auto_path $Dir + } + } + } + + if {![interp issafe]} { + variable Path [encoding dirs] + set Dir [file join $::tcl_library encoding] + if {$Dir ni $Path} { + lappend Path $Dir + encoding dirs $Path + } + } + + # TIP #255 min and max functions + namespace eval mathfunc { + proc min {args} { + if {![llength $args]} { + return -code error \ + "too few arguments to math function \"min\"" + } + set val Inf + foreach arg $args { + # This will handle forcing the numeric value without + # ruining the internal type of a numeric object + if {[catch {expr {double($arg)}} err]} { + return -code error $err + } + if {$arg < $val} {set val $arg} + } + return $val + } + proc max {args} { + if {![llength $args]} { + return -code error \ + "too few arguments to math function \"max\"" + } + set val -Inf + foreach arg $args { + # This will handle forcing the numeric value without + # ruining the internal type of a numeric object + if {[catch {expr {double($arg)}} err]} { + return -code error $err + } + if {$arg > $val} {set val $arg} + } + return $val + } + namespace export min max + } +} + +# Windows specific end of initialization + +if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} { + namespace eval tcl { + proc EnvTraceProc {lo n1 n2 op} { + global env + set x $env($n2) + set env($lo) $x + set env([string toupper $lo]) $x + } + proc InitWinEnv {} { + global env tcl_platform + foreach p [array names env] { + set u [string toupper $p] + if {$u ne $p} { + switch -- $u { + COMSPEC - + PATH { + set temp $env($p) + unset env($p) + set env($u) $temp + trace add variable env($p) write \ + [namespace code [list EnvTraceProc $p]] + trace add variable env($u) write \ + [namespace code [list EnvTraceProc $p]] + } + } + } + } + if {![info exists env(COMSPEC)]} { + set env(COMSPEC) cmd.exe + } + } + InitWinEnv + } +} + +# Setup the unknown package handler + + +if {[interp issafe]} { + package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown} +} else { + # Set up search for Tcl Modules (TIP #189). + # and setup platform specific unknown package handlers + if {$tcl_platform(os) eq "Darwin" + && $tcl_platform(platform) eq "unix"} { + package unknown {::tcl::tm::UnknownHandler \ + {::tcl::MacOSXPkgUnknown ::tclPkgUnknown}} + } else { + package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown} + } + + # Set up the 'clock' ensemble + + namespace eval ::tcl::clock [list variable TclLibDir $::tcl_library] + + proc ::tcl::initClock {} { + # Auto-loading stubs for 'clock.tcl' + + foreach cmd {add format scan} { + proc ::tcl::clock::$cmd args { + variable TclLibDir + source -encoding utf-8 [file join $TclLibDir clock.tcl] + return [uplevel 1 [info level 0]] + } + } + + rename ::tcl::initClock {} + } + ::tcl::initClock +} + +# Conditionalize for presence of exec. + +if {[namespace which -command exec] eq ""} { + + # Some machines do not have exec. Also, on all + # platforms, safe interpreters do not have exec. + + set auto_noexec 1 +} + +# Define a log command (which can be overwitten to log errors +# differently, specially when stderr is not available) + +if {[namespace which -command tclLog] eq ""} { + proc tclLog {string} { + catch {puts stderr $string} + } +} + +# unknown -- +# This procedure is called when a Tcl command is invoked that doesn't +# exist in the interpreter. It takes the following steps to make the +# command available: +# +# 1. See if the autoload facility can locate the command in a +# Tcl script file. If so, load it and execute it. +# 2. If the command was invoked interactively at top-level: +# (a) see if the command exists as an executable UNIX program. +# If so, "exec" the command. +# (b) see if the command requests csh-like history substitution +# in one of the common forms !!, !<number>, or ^old^new. If +# so, emulate csh's history substitution. +# (c) see if the command is a unique abbreviation for another +# command. If so, invoke the command. +# +# Arguments: +# args - A list whose elements are the words of the original +# command, including the command name. + +proc unknown args { + variable ::tcl::UnknownPending + global auto_noexec auto_noload env tcl_interactive errorInfo errorCode + + if {[info exists errorInfo]} { + set savedErrorInfo $errorInfo + } + if {[info exists errorCode]} { + set savedErrorCode $errorCode + } + + set name [lindex $args 0] + if {![info exists auto_noload]} { + # + # Make sure we're not trying to load the same proc twice. + # + if {[info exists UnknownPending($name)]} { + return -code error "self-referential recursion\ + in \"unknown\" for command \"$name\"" + } + set UnknownPending($name) pending + set ret [catch { + auto_load $name [uplevel 1 {::namespace current}] + } msg opts] + unset UnknownPending($name) + if {$ret != 0} { + dict append opts -errorinfo "\n (autoloading \"$name\")" + return -options $opts $msg + } + if {![array size UnknownPending]} { + unset UnknownPending + } + if {$msg} { + if {[info exists savedErrorCode]} { + set ::errorCode $savedErrorCode + } else { + unset -nocomplain ::errorCode + } + if {[info exists savedErrorInfo]} { + set errorInfo $savedErrorInfo + } else { + unset -nocomplain errorInfo + } + set code [catch {uplevel 1 $args} msg opts] + if {$code == 1} { + # + # Compute stack trace contribution from the [uplevel]. + # Note the dependence on how Tcl_AddErrorInfo, etc. + # construct the stack trace. + # + set errInfo [dict get $opts -errorinfo] + set errCode [dict get $opts -errorcode] + set cinfo $args + if {[string bytelength $cinfo] > 150} { + set cinfo [string range $cinfo 0 150] + while {[string bytelength $cinfo] > 150} { + set cinfo [string range $cinfo 0 end-1] + } + append cinfo ... + } + set tail "\n (\"uplevel\" body line 1)\n invoked\ + from within\n\"uplevel 1 \$args\"" + set expect "$msg\n while executing\n\"$cinfo\"$tail" + if {$errInfo eq $expect} { + # + # The stack has only the eval from the expanded command + # Do not generate any stack trace here. + # + dict unset opts -errorinfo + dict incr opts -level + return -options $opts $msg + } + # + # Stack trace is nested, trim off just the contribution + # from the extra "eval" of $args due to the "catch" above. + # + set last [string last $tail $errInfo] + if {$last + [string length $tail] != [string length $errInfo]} { + # Very likely cannot happen + return -options $opts $msg + } + set errInfo [string range $errInfo 0 $last-1] + set tail "\"$cinfo\"" + set last [string last $tail $errInfo] + if {$last + [string length $tail] != [string length $errInfo]} { + return -code error -errorcode $errCode \ + -errorinfo $errInfo $msg + } + set errInfo [string range $errInfo 0 $last-1] + set tail "\n invoked from within\n" + set last [string last $tail $errInfo] + if {$last + [string length $tail] == [string length $errInfo]} { + return -code error -errorcode $errCode \ + -errorinfo [string range $errInfo 0 $last-1] $msg + } + set tail "\n while executing\n" + set last [string last $tail $errInfo] + if {$last + [string length $tail] == [string length $errInfo]} { + return -code error -errorcode $errCode \ + -errorinfo [string range $errInfo 0 $last-1] $msg + } + return -options $opts $msg + } else { + dict incr opts -level + return -options $opts $msg + } + } + } + + if {([info level] == 1) && ([info script] eq "") + && [info exists tcl_interactive] && $tcl_interactive} { + if {![info exists auto_noexec]} { + set new [auto_execok $name] + if {$new ne ""} { + set redir "" + if {[namespace which -command console] eq ""} { + set redir ">&@stdout <@stdin" + } + uplevel 1 [list ::catch \ + [concat exec $redir $new [lrange $args 1 end]] \ + ::tcl::UnknownResult ::tcl::UnknownOptions] + dict incr ::tcl::UnknownOptions -level + return -options $::tcl::UnknownOptions $::tcl::UnknownResult + } + } + if {$name eq "!!"} { + set newcmd [history event] + } elseif {[regexp {^!(.+)$} $name -> event]} { + set newcmd [history event $event] + } elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $name -> old new]} { + set newcmd [history event -1] + catch {regsub -all -- $old $newcmd $new newcmd} + } + if {[info exists newcmd]} { + tclLog $newcmd + history change $newcmd 0 + uplevel 1 [list ::catch $newcmd \ + ::tcl::UnknownResult ::tcl::UnknownOptions] + dict incr ::tcl::UnknownOptions -level + return -options $::tcl::UnknownOptions $::tcl::UnknownResult + } + + set ret [catch {set candidates [info commands $name*]} msg] + if {$name eq "::"} { + set name "" + } + if {$ret != 0} { + dict append opts -errorinfo \ + "\n (expanding command prefix \"$name\" in unknown)" + return -options $opts $msg + } + # Filter out bogus matches when $name contained + # a glob-special char [Bug 946952] + if {$name eq ""} { + # Handle empty $name separately due to strangeness + # in [string first] (See RFE 1243354) + set cmds $candidates + } else { + set cmds [list] + foreach x $candidates { + if {[string first $name $x] == 0} { + lappend cmds $x + } + } + } + if {[llength $cmds] == 1} { + uplevel 1 [list ::catch [lreplace $args 0 0 [lindex $cmds 0]] \ + ::tcl::UnknownResult ::tcl::UnknownOptions] + dict incr ::tcl::UnknownOptions -level + return -options $::tcl::UnknownOptions $::tcl::UnknownResult + } + if {[llength $cmds]} { + return -code error "ambiguous command name \"$name\": [lsort $cmds]" + } + } + return -code error -errorcode [list TCL LOOKUP COMMAND $name] \ + "invalid command name \"$name\"" +} + +# auto_load -- +# Checks a collection of library directories to see if a procedure +# is defined in one of them. If so, it sources the appropriate +# library file to create the procedure. Returns 1 if it successfully +# loaded the procedure, 0 otherwise. +# +# Arguments: +# cmd - Name of the command to find and load. +# namespace (optional) The namespace where the command is being used - must be +# a canonical namespace as returned [namespace current] +# for instance. If not given, namespace current is used. + +proc auto_load {cmd {namespace {}}} { + global auto_index auto_path + + if {$namespace eq ""} { + set namespace [uplevel 1 [list ::namespace current]] + } + set nameList [auto_qualify $cmd $namespace] + # workaround non canonical auto_index entries that might be around + # from older auto_mkindex versions + lappend nameList $cmd + foreach name $nameList { + if {[info exists auto_index($name)]} { + namespace eval :: $auto_index($name) + # There's a couple of ways to look for a command of a given + # name. One is to use + # info commands $name + # Unfortunately, if the name has glob-magic chars in it like * + # or [], it may not match. For our purposes here, a better + # route is to use + # namespace which -command $name + if {[namespace which -command $name] ne ""} { + return 1 + } + } + } + if {![info exists auto_path]} { + return 0 + } + + if {![auto_load_index]} { + return 0 + } + foreach name $nameList { + if {[info exists auto_index($name)]} { + namespace eval :: $auto_index($name) + if {[namespace which -command $name] ne ""} { + return 1 + } + } + } + return 0 +} + +# auto_load_index -- +# Loads the contents of tclIndex files on the auto_path directory +# list. This is usually invoked within auto_load to load the index +# of available commands. Returns 1 if the index is loaded, and 0 if +# the index is already loaded and up to date. +# +# Arguments: +# None. + +proc auto_load_index {} { + variable ::tcl::auto_oldpath + global auto_index auto_path + + if {[info exists auto_oldpath] && ($auto_oldpath eq $auto_path)} { + return 0 + } + set auto_oldpath $auto_path + + # Check if we are a safe interpreter. In that case, we support only + # newer format tclIndex files. + + set issafe [interp issafe] + for {set i [expr {[llength $auto_path] - 1}]} {$i >= 0} {incr i -1} { + set dir [lindex $auto_path $i] + set f "" + if {$issafe} { + catch {source [file join $dir tclIndex]} + } elseif {[catch {set f [open [file join $dir tclIndex]]}]} { + continue + } else { + set error [catch { + set id [gets $f] + if {$id eq "# Tcl autoload index file, version 2.0"} { + eval [read $f] + } elseif {$id eq "# Tcl autoload index file: each line identifies a Tcl"} { + while {[gets $f line] >= 0} { + if {([string index $line 0] eq "#") \ + || ([llength $line] != 2)} { + continue + } + set name [lindex $line 0] + set auto_index($name) \ + "source [file join $dir [lindex $line 1]]" + } + } else { + error "[file join $dir tclIndex] isn't a proper Tcl index file" + } + } msg opts] + if {$f ne ""} { + close $f + } + if {$error} { + return -options $opts $msg + } + } + } + return 1 +} + +# auto_qualify -- +# +# Compute a fully qualified names list for use in the auto_index array. +# For historical reasons, commands in the global namespace do not have leading +# :: in the index key. The list has two elements when the command name is +# relative (no leading ::) and the namespace is not the global one. Otherwise +# only one name is returned (and searched in the auto_index). +# +# Arguments - +# cmd The command name. Can be any name accepted for command +# invocations (Like "foo::::bar"). +# namespace The namespace where the command is being used - must be +# a canonical namespace as returned by [namespace current] +# for instance. + +proc auto_qualify {cmd namespace} { + + # count separators and clean them up + # (making sure that foo:::::bar will be treated as foo::bar) + set n [regsub -all {::+} $cmd :: cmd] + + # Ignore namespace if the name starts with :: + # Handle special case of only leading :: + + # Before each return case we give an example of which category it is + # with the following form : + # (inputCmd, inputNameSpace) -> output + + if {[string match ::* $cmd]} { + if {$n > 1} { + # (::foo::bar , *) -> ::foo::bar + return [list $cmd] + } else { + # (::global , *) -> global + return [list [string range $cmd 2 end]] + } + } + + # Potentially returning 2 elements to try : + # (if the current namespace is not the global one) + + if {$n == 0} { + if {$namespace eq "::"} { + # (nocolons , ::) -> nocolons + return [list $cmd] + } else { + # (nocolons , ::sub) -> ::sub::nocolons nocolons + return [list ${namespace}::$cmd $cmd] + } + } elseif {$namespace eq "::"} { + # (foo::bar , ::) -> ::foo::bar + return [list ::$cmd] + } else { + # (foo::bar , ::sub) -> ::sub::foo::bar ::foo::bar + return [list ${namespace}::$cmd ::$cmd] + } +} + +# auto_import -- +# +# Invoked during "namespace import" to make see if the imported commands +# reside in an autoloaded library. If so, the commands are loaded so +# that they will be available for the import links. If not, then this +# procedure does nothing. +# +# Arguments - +# pattern The pattern of commands being imported (like "foo::*") +# a canonical namespace as returned by [namespace current] + +proc auto_import {pattern} { + global auto_index + + # If no namespace is specified, this will be an error case + + if {![string match *::* $pattern]} { + return + } + + set ns [uplevel 1 [list ::namespace current]] + set patternList [auto_qualify $pattern $ns] + + auto_load_index + + foreach pattern $patternList { + foreach name [array names auto_index $pattern] { + if {([namespace which -command $name] eq "") + && ([namespace qualifiers $pattern] eq [namespace qualifiers $name])} { + namespace eval :: $auto_index($name) + } + } + } +} + +# auto_execok -- +# +# Returns string that indicates name of program to execute if +# name corresponds to a shell builtin or an executable in the +# Windows search path, or "" otherwise. Builds an associative +# array auto_execs that caches information about previous checks, +# for speed. +# +# Arguments: +# name - Name of a command. + +if {$tcl_platform(platform) eq "windows"} { +# Windows version. +# +# Note that file executable doesn't work under Windows, so we have to +# look for files with .exe, .com, or .bat extensions. Also, the path +# may be in the Path or PATH environment variables, and path +# components are separated with semicolons, not colons as under Unix. +# +proc auto_execok name { + global auto_execs env tcl_platform + + if {[info exists auto_execs($name)]} { + return $auto_execs($name) + } + set auto_execs($name) "" + + set shellBuiltins [list assoc cls copy date del dir echo erase ftype \ + md mkdir mklink move rd ren rename rmdir start time type ver vol] + if {[info exists env(PATHEXT)]} { + # Add an initial ; to have the {} extension check first. + set execExtensions [split ";$env(PATHEXT)" ";"] + } else { + set execExtensions [list {} .com .exe .bat .cmd] + } + + if {[string tolower $name] in $shellBuiltins} { + # When this is command.com for some reason on Win2K, Tcl won't + # exec it unless the case is right, which this corrects. COMSPEC + # may not point to a real file, so do the check. + set cmd $env(COMSPEC) + if {[file exists $cmd]} { + set cmd [file attributes $cmd -shortname] + } + return [set auto_execs($name) [list $cmd /c $name]] + } + + if {[llength [file split $name]] != 1} { + foreach ext $execExtensions { + set file ${name}${ext} + if {[file exists $file] && ![file isdirectory $file]} { + return [set auto_execs($name) [list $file]] + } + } + return "" + } + + set path "[file dirname [info nameof]];.;" + if {[info exists env(WINDIR)]} { + set windir $env(WINDIR) + } + if {[info exists windir]} { + if {$tcl_platform(os) eq "Windows NT"} { + append path "$windir/system32;" + } + append path "$windir/system;$windir;" + } + + foreach var {PATH Path path} { + if {[info exists env($var)]} { + append path ";$env($var)" + } + } + + foreach ext $execExtensions { + unset -nocomplain checked + foreach dir [split $path {;}] { + # Skip already checked directories + if {[info exists checked($dir)] || ($dir eq "")} { + continue + } + set checked($dir) {} + set file [file join $dir ${name}${ext}] + if {[file exists $file] && ![file isdirectory $file]} { + return [set auto_execs($name) [list $file]] + } + } + } + return "" +} + +} else { +# Unix version. +# +proc auto_execok name { + global auto_execs env + + if {[info exists auto_execs($name)]} { + return $auto_execs($name) + } + set auto_execs($name) "" + if {[llength [file split $name]] != 1} { + if {[file executable $name] && ![file isdirectory $name]} { + set auto_execs($name) [list $name] + } + return $auto_execs($name) + } + foreach dir [split $env(PATH) :] { + if {$dir eq ""} { + set dir . + } + set file [file join $dir $name] + if {[file executable $file] && ![file isdirectory $file]} { + set auto_execs($name) [list $file] + return $auto_execs($name) + } + } + return "" +} + +} + +# ::tcl::CopyDirectory -- +# +# This procedure is called by Tcl's core when attempts to call the +# filesystem's copydirectory function fail. The semantics of the call +# are that 'dest' does not yet exist, i.e. dest should become the exact +# image of src. If dest does exist, we throw an error. +# +# Note that making changes to this procedure can change the results +# of running Tcl's tests. +# +# Arguments: +# action - "renaming" or "copying" +# src - source directory +# dest - destination directory +proc tcl::CopyDirectory {action src dest} { + set nsrc [file normalize $src] + set ndest [file normalize $dest] + + if {$action eq "renaming"} { + # Can't rename volumes. We could give a more precise + # error message here, but that would break the test suite. + if {$nsrc in [file volumes]} { + return -code error "error $action \"$src\" to\ + \"$dest\": trying to rename a volume or move a directory\ + into itself" + } + } + if {[file exists $dest]} { + if {$nsrc eq $ndest} { + return -code error "error $action \"$src\" to\ + \"$dest\": trying to rename a volume or move a directory\ + into itself" + } + if {$action eq "copying"} { + # We used to throw an error here, but, looking more closely + # at the core copy code in tclFCmd.c, if the destination + # exists, then we should only call this function if -force + # is true, which means we just want to over-write. So, + # the following code is now commented out. + # + # return -code error "error $action \"$src\" to\ + # \"$dest\": file already exists" + } else { + # Depending on the platform, and on the current + # working directory, the directories '.', '..' + # can be returned in various combinations. Anyway, + # if any other file is returned, we must signal an error. + set existing [glob -nocomplain -directory $dest * .*] + lappend existing {*}[glob -nocomplain -directory $dest \ + -type hidden * .*] + foreach s $existing { + if {[file tail $s] ni {. ..}} { + return -code error "error $action \"$src\" to\ + \"$dest\": file already exists" + } + } + } + } else { + if {[string first $nsrc $ndest] != -1} { + set srclen [expr {[llength [file split $nsrc]] - 1}] + set ndest [lindex [file split $ndest] $srclen] + if {$ndest eq [file tail $nsrc]} { + return -code error "error $action \"$src\" to\ + \"$dest\": trying to rename a volume or move a directory\ + into itself" + } + } + file mkdir $dest + } + # Have to be careful to capture both visible and hidden files. + # We will also be more generous to the file system and not + # assume the hidden and non-hidden lists are non-overlapping. + # + # On Unix 'hidden' files begin with '.'. On other platforms + # or filesystems hidden files may have other interpretations. + set filelist [concat [glob -nocomplain -directory $src *] \ + [glob -nocomplain -directory $src -types hidden *]] + + foreach s [lsort -unique $filelist] { + if {[file tail $s] ni {. ..}} { + file copy -force -- $s [file join $dest [file tail $s]] + } + } + return +} diff --git a/basic python programmes/venv/Scripts/Activate.ps1 b/basic python programmes/venv/Scripts/Activate.ps1 new file mode 100644 index 0000000..ec5b722 --- /dev/null +++ b/basic python programmes/venv/Scripts/Activate.ps1 @@ -0,0 +1,51 @@ +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + if (Test-Path function:_OLD_VIRTUAL_PROMPT) { + copy-item function:_OLD_VIRTUAL_PROMPT function:prompt + remove-item function:_OLD_VIRTUAL_PROMPT + } + + if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { + copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME + remove-item env:_OLD_VIRTUAL_PYTHONHOME + } + + if (Test-Path env:_OLD_VIRTUAL_PATH) { + copy-item env:_OLD_VIRTUAL_PATH env:PATH + remove-item env:_OLD_VIRTUAL_PATH + } + + if (Test-Path env:VIRTUAL_ENV) { + remove-item env:VIRTUAL_ENV + } + + if (!$NonDestructive) { + # Self destruct! + remove-item function:deactivate + } +} + +deactivate -nondestructive + +$env:VIRTUAL_ENV="F:\pythonp\venv" + +if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) { + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT {""} + copy-item function:prompt function:_OLD_VIRTUAL_PROMPT + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green '(venv) ' + _OLD_VIRTUAL_PROMPT + } +} + +# Clear PYTHONHOME +if (Test-Path env:PYTHONHOME) { + copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME + remove-item env:PYTHONHOME +} + +# Add the venv to the PATH +copy-item env:PATH env:_OLD_VIRTUAL_PATH +$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH" diff --git a/basic python programmes/venv/Scripts/_asyncio.pyd b/basic python programmes/venv/Scripts/_asyncio.pyd new file mode 100644 index 0000000..c3cf56b Binary files /dev/null and b/basic python programmes/venv/Scripts/_asyncio.pyd differ diff --git a/basic python programmes/venv/Scripts/_bz2.pyd b/basic python programmes/venv/Scripts/_bz2.pyd new file mode 100644 index 0000000..eebef06 Binary files /dev/null and b/basic python programmes/venv/Scripts/_bz2.pyd differ diff --git a/basic python programmes/venv/Scripts/_contextvars.pyd b/basic python programmes/venv/Scripts/_contextvars.pyd new file mode 100644 index 0000000..ac7d069 Binary files /dev/null and b/basic python programmes/venv/Scripts/_contextvars.pyd differ diff --git a/basic python programmes/venv/Scripts/_ctypes.pyd b/basic python programmes/venv/Scripts/_ctypes.pyd new file mode 100644 index 0000000..2800f63 Binary files /dev/null and b/basic python programmes/venv/Scripts/_ctypes.pyd differ diff --git a/basic python programmes/venv/Scripts/_ctypes_test.pyd b/basic python programmes/venv/Scripts/_ctypes_test.pyd new file mode 100644 index 0000000..1dc22b7 Binary files /dev/null and b/basic python programmes/venv/Scripts/_ctypes_test.pyd differ diff --git a/basic python programmes/venv/Scripts/_decimal.pyd b/basic python programmes/venv/Scripts/_decimal.pyd new file mode 100644 index 0000000..b058b53 Binary files /dev/null and b/basic python programmes/venv/Scripts/_decimal.pyd differ diff --git a/basic python programmes/venv/Scripts/_distutils_findvs.pyd b/basic python programmes/venv/Scripts/_distutils_findvs.pyd new file mode 100644 index 0000000..4eff367 Binary files /dev/null and b/basic python programmes/venv/Scripts/_distutils_findvs.pyd differ diff --git a/basic python programmes/venv/Scripts/_elementtree.pyd b/basic python programmes/venv/Scripts/_elementtree.pyd new file mode 100644 index 0000000..630b299 Binary files /dev/null and b/basic python programmes/venv/Scripts/_elementtree.pyd differ diff --git a/basic python programmes/venv/Scripts/_hashlib.pyd b/basic python programmes/venv/Scripts/_hashlib.pyd new file mode 100644 index 0000000..408f2d7 Binary files /dev/null and b/basic python programmes/venv/Scripts/_hashlib.pyd differ diff --git a/basic python programmes/venv/Scripts/_lzma.pyd b/basic python programmes/venv/Scripts/_lzma.pyd new file mode 100644 index 0000000..bcb4156 Binary files /dev/null and b/basic python programmes/venv/Scripts/_lzma.pyd differ diff --git a/basic python programmes/venv/Scripts/_msi.pyd b/basic python programmes/venv/Scripts/_msi.pyd new file mode 100644 index 0000000..87c64b5 Binary files /dev/null and b/basic python programmes/venv/Scripts/_msi.pyd differ diff --git a/basic python programmes/venv/Scripts/_multiprocessing.pyd b/basic python programmes/venv/Scripts/_multiprocessing.pyd new file mode 100644 index 0000000..0437952 Binary files /dev/null and b/basic python programmes/venv/Scripts/_multiprocessing.pyd differ diff --git a/basic python programmes/venv/Scripts/_overlapped.pyd b/basic python programmes/venv/Scripts/_overlapped.pyd new file mode 100644 index 0000000..33bdbf5 Binary files /dev/null and b/basic python programmes/venv/Scripts/_overlapped.pyd differ diff --git a/basic python programmes/venv/Scripts/_queue.pyd b/basic python programmes/venv/Scripts/_queue.pyd new file mode 100644 index 0000000..b08ae94 Binary files /dev/null and b/basic python programmes/venv/Scripts/_queue.pyd differ diff --git a/basic python programmes/venv/Scripts/_socket.pyd b/basic python programmes/venv/Scripts/_socket.pyd new file mode 100644 index 0000000..a4d4667 Binary files /dev/null and b/basic python programmes/venv/Scripts/_socket.pyd differ diff --git a/basic python programmes/venv/Scripts/_sqlite3.pyd b/basic python programmes/venv/Scripts/_sqlite3.pyd new file mode 100644 index 0000000..f151311 Binary files /dev/null and b/basic python programmes/venv/Scripts/_sqlite3.pyd differ diff --git a/basic python programmes/venv/Scripts/_ssl.pyd b/basic python programmes/venv/Scripts/_ssl.pyd new file mode 100644 index 0000000..8dc7577 Binary files /dev/null and b/basic python programmes/venv/Scripts/_ssl.pyd differ diff --git a/basic python programmes/venv/Scripts/_testbuffer.pyd b/basic python programmes/venv/Scripts/_testbuffer.pyd new file mode 100644 index 0000000..6de3261 Binary files /dev/null and b/basic python programmes/venv/Scripts/_testbuffer.pyd differ diff --git a/basic python programmes/venv/Scripts/_testcapi.pyd b/basic python programmes/venv/Scripts/_testcapi.pyd new file mode 100644 index 0000000..05e07d1 Binary files /dev/null and b/basic python programmes/venv/Scripts/_testcapi.pyd differ diff --git a/basic python programmes/venv/Scripts/_testconsole.pyd b/basic python programmes/venv/Scripts/_testconsole.pyd new file mode 100644 index 0000000..bf51c93 Binary files /dev/null and b/basic python programmes/venv/Scripts/_testconsole.pyd differ diff --git a/basic python programmes/venv/Scripts/_testimportmultiple.pyd b/basic python programmes/venv/Scripts/_testimportmultiple.pyd new file mode 100644 index 0000000..bce5bc1 Binary files /dev/null and b/basic python programmes/venv/Scripts/_testimportmultiple.pyd differ diff --git a/basic python programmes/venv/Scripts/_testmultiphase.pyd b/basic python programmes/venv/Scripts/_testmultiphase.pyd new file mode 100644 index 0000000..ffbcecd Binary files /dev/null and b/basic python programmes/venv/Scripts/_testmultiphase.pyd differ diff --git a/basic python programmes/venv/Scripts/_tkinter.pyd b/basic python programmes/venv/Scripts/_tkinter.pyd new file mode 100644 index 0000000..e881fb6 Binary files /dev/null and b/basic python programmes/venv/Scripts/_tkinter.pyd differ diff --git a/basic python programmes/venv/Scripts/activate b/basic python programmes/venv/Scripts/activate new file mode 100644 index 0000000..29d08aa --- /dev/null +++ b/basic python programmes/venv/Scripts/activate @@ -0,0 +1,76 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "$1" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="F:\pythonp\venv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/Scripts:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + if [ "x(venv) " != x ] ; then + PS1="(venv) ${PS1:-}" + else + if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then + # special case for Aspen magic directories + # see http://www.zetadev.com/software/aspen/ + PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" + fi + fi + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r +fi diff --git a/basic python programmes/venv/Scripts/activate.bat b/basic python programmes/venv/Scripts/activate.bat new file mode 100644 index 0000000..3dc2d53 --- /dev/null +++ b/basic python programmes/venv/Scripts/activate.bat @@ -0,0 +1,45 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:" %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set "_OLD_CODEPAGE=%%a" +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set "VIRTUAL_ENV=F:\pythonp\venv" + +if not defined PROMPT ( + set "PROMPT=$P$G" +) + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" +) + +set "_OLD_VIRTUAL_PROMPT=%PROMPT%" +set "PROMPT=(venv) %PROMPT%" + +if defined PYTHONHOME ( + set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%" + set PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) else ( + set "_OLD_VIRTUAL_PATH=%PATH%" +) + +set "PATH=%VIRTUAL_ENV%\Scripts;%PATH%" + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set "_OLD_CODEPAGE=" +) diff --git a/basic python programmes/venv/Scripts/deactivate.bat b/basic python programmes/venv/Scripts/deactivate.bat new file mode 100644 index 0000000..1205c61 --- /dev/null +++ b/basic python programmes/venv/Scripts/deactivate.bat @@ -0,0 +1,21 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= + +:END diff --git a/basic python programmes/venv/Scripts/easy_install-3.7-script.py b/basic python programmes/venv/Scripts/easy_install-3.7-script.py new file mode 100644 index 0000000..8499f7e --- /dev/null +++ b/basic python programmes/venv/Scripts/easy_install-3.7-script.py @@ -0,0 +1,12 @@ +#!F:\pythonp\venv\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==39.1.0','console_scripts','easy_install-3.7' +__requires__ = 'setuptools==39.1.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('setuptools==39.1.0', 'console_scripts', 'easy_install-3.7')() + ) diff --git a/basic python programmes/venv/Scripts/easy_install-3.7.exe b/basic python programmes/venv/Scripts/easy_install-3.7.exe new file mode 100644 index 0000000..675e6bf Binary files /dev/null and b/basic python programmes/venv/Scripts/easy_install-3.7.exe differ diff --git a/basic python programmes/venv/Scripts/easy_install-script.py b/basic python programmes/venv/Scripts/easy_install-script.py new file mode 100644 index 0000000..2ba7308 --- /dev/null +++ b/basic python programmes/venv/Scripts/easy_install-script.py @@ -0,0 +1,12 @@ +#!F:\pythonp\venv\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==39.1.0','console_scripts','easy_install' +__requires__ = 'setuptools==39.1.0' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('setuptools==39.1.0', 'console_scripts', 'easy_install')() + ) diff --git a/basic python programmes/venv/Scripts/easy_install.exe b/basic python programmes/venv/Scripts/easy_install.exe new file mode 100644 index 0000000..675e6bf Binary files /dev/null and b/basic python programmes/venv/Scripts/easy_install.exe differ diff --git a/basic python programmes/venv/Scripts/epylint.exe b/basic python programmes/venv/Scripts/epylint.exe new file mode 100644 index 0000000..006c154 Binary files /dev/null and b/basic python programmes/venv/Scripts/epylint.exe differ diff --git a/basic python programmes/venv/Scripts/isort.exe b/basic python programmes/venv/Scripts/isort.exe new file mode 100644 index 0000000..0a41630 Binary files /dev/null and b/basic python programmes/venv/Scripts/isort.exe differ diff --git a/basic python programmes/venv/Scripts/libcrypto-1_1-x64.dll b/basic python programmes/venv/Scripts/libcrypto-1_1-x64.dll new file mode 100644 index 0000000..98bc522 Binary files /dev/null and b/basic python programmes/venv/Scripts/libcrypto-1_1-x64.dll differ diff --git a/basic python programmes/venv/Scripts/libssl-1_1-x64.dll b/basic python programmes/venv/Scripts/libssl-1_1-x64.dll new file mode 100644 index 0000000..dbe1aa7 Binary files /dev/null and b/basic python programmes/venv/Scripts/libssl-1_1-x64.dll differ diff --git a/basic python programmes/venv/Scripts/pip-script.py b/basic python programmes/venv/Scripts/pip-script.py new file mode 100644 index 0000000..d334e9a --- /dev/null +++ b/basic python programmes/venv/Scripts/pip-script.py @@ -0,0 +1,12 @@ +#!F:\pythonp\venv\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip' +__requires__ = 'pip==10.0.1' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==10.0.1', 'console_scripts', 'pip')() + ) diff --git a/basic python programmes/venv/Scripts/pip.exe b/basic python programmes/venv/Scripts/pip.exe new file mode 100644 index 0000000..675e6bf Binary files /dev/null and b/basic python programmes/venv/Scripts/pip.exe differ diff --git a/basic python programmes/venv/Scripts/pip3-script.py b/basic python programmes/venv/Scripts/pip3-script.py new file mode 100644 index 0000000..9627f0e --- /dev/null +++ b/basic python programmes/venv/Scripts/pip3-script.py @@ -0,0 +1,12 @@ +#!F:\pythonp\venv\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip3' +__requires__ = 'pip==10.0.1' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==10.0.1', 'console_scripts', 'pip3')() + ) diff --git a/basic python programmes/venv/Scripts/pip3.7-script.py b/basic python programmes/venv/Scripts/pip3.7-script.py new file mode 100644 index 0000000..21954b4 --- /dev/null +++ b/basic python programmes/venv/Scripts/pip3.7-script.py @@ -0,0 +1,12 @@ +#!F:\pythonp\venv\Scripts\python.exe +# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip3.7' +__requires__ = 'pip==10.0.1' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pip==10.0.1', 'console_scripts', 'pip3.7')() + ) diff --git a/basic python programmes/venv/Scripts/pip3.7.exe b/basic python programmes/venv/Scripts/pip3.7.exe new file mode 100644 index 0000000..675e6bf Binary files /dev/null and b/basic python programmes/venv/Scripts/pip3.7.exe differ diff --git a/basic python programmes/venv/Scripts/pip3.exe b/basic python programmes/venv/Scripts/pip3.exe new file mode 100644 index 0000000..675e6bf Binary files /dev/null and b/basic python programmes/venv/Scripts/pip3.exe differ diff --git a/basic python programmes/venv/Scripts/pyexpat.pyd b/basic python programmes/venv/Scripts/pyexpat.pyd new file mode 100644 index 0000000..0f64fd2 Binary files /dev/null and b/basic python programmes/venv/Scripts/pyexpat.pyd differ diff --git a/basic python programmes/venv/Scripts/pylint.exe b/basic python programmes/venv/Scripts/pylint.exe new file mode 100644 index 0000000..f88ff26 Binary files /dev/null and b/basic python programmes/venv/Scripts/pylint.exe differ diff --git a/basic python programmes/venv/Scripts/pyreverse.exe b/basic python programmes/venv/Scripts/pyreverse.exe new file mode 100644 index 0000000..08ea80d Binary files /dev/null and b/basic python programmes/venv/Scripts/pyreverse.exe differ diff --git a/basic python programmes/venv/Scripts/python.exe b/basic python programmes/venv/Scripts/python.exe new file mode 100644 index 0000000..7013af8 Binary files /dev/null and b/basic python programmes/venv/Scripts/python.exe differ diff --git a/basic python programmes/venv/Scripts/python3.dll b/basic python programmes/venv/Scripts/python3.dll new file mode 100644 index 0000000..0d609ed Binary files /dev/null and b/basic python programmes/venv/Scripts/python3.dll differ diff --git a/basic python programmes/venv/Scripts/python37.dll b/basic python programmes/venv/Scripts/python37.dll new file mode 100644 index 0000000..2453692 Binary files /dev/null and b/basic python programmes/venv/Scripts/python37.dll differ diff --git a/basic python programmes/venv/Scripts/pythonw.exe b/basic python programmes/venv/Scripts/pythonw.exe new file mode 100644 index 0000000..524cfff Binary files /dev/null and b/basic python programmes/venv/Scripts/pythonw.exe differ diff --git a/basic python programmes/venv/Scripts/select.pyd b/basic python programmes/venv/Scripts/select.pyd new file mode 100644 index 0000000..dc43eff Binary files /dev/null and b/basic python programmes/venv/Scripts/select.pyd differ diff --git a/basic python programmes/venv/Scripts/sqlite3.dll b/basic python programmes/venv/Scripts/sqlite3.dll new file mode 100644 index 0000000..12fa391 Binary files /dev/null and b/basic python programmes/venv/Scripts/sqlite3.dll differ diff --git a/basic python programmes/venv/Scripts/symilar.exe b/basic python programmes/venv/Scripts/symilar.exe new file mode 100644 index 0000000..20af40d Binary files /dev/null and b/basic python programmes/venv/Scripts/symilar.exe differ diff --git a/basic python programmes/venv/Scripts/tcl86t.dll b/basic python programmes/venv/Scripts/tcl86t.dll new file mode 100644 index 0000000..9844092 Binary files /dev/null and b/basic python programmes/venv/Scripts/tcl86t.dll differ diff --git a/basic python programmes/venv/Scripts/tk86t.dll b/basic python programmes/venv/Scripts/tk86t.dll new file mode 100644 index 0000000..910bbef Binary files /dev/null and b/basic python programmes/venv/Scripts/tk86t.dll differ diff --git a/basic python programmes/venv/Scripts/unicodedata.pyd b/basic python programmes/venv/Scripts/unicodedata.pyd new file mode 100644 index 0000000..387dd0d Binary files /dev/null and b/basic python programmes/venv/Scripts/unicodedata.pyd differ diff --git a/basic python programmes/venv/Scripts/vcruntime140.dll b/basic python programmes/venv/Scripts/vcruntime140.dll new file mode 100644 index 0000000..1ea2577 Binary files /dev/null and b/basic python programmes/venv/Scripts/vcruntime140.dll differ diff --git a/basic python programmes/venv/Scripts/winsound.pyd b/basic python programmes/venv/Scripts/winsound.pyd new file mode 100644 index 0000000..54e557a Binary files /dev/null and b/basic python programmes/venv/Scripts/winsound.pyd differ diff --git a/basic python programmes/venv/pip-selfcheck.json b/basic python programmes/venv/pip-selfcheck.json new file mode 100644 index 0000000..e7d663c --- /dev/null +++ b/basic python programmes/venv/pip-selfcheck.json @@ -0,0 +1 @@ +{"last_check":"2018-12-22T13:16:32Z","pypi_version":"18.1"} \ No newline at end of file diff --git a/basic python programmes/venv/pythontesting.py b/basic python programmes/venv/pythontesting.py new file mode 100644 index 0000000..4ddfcec --- /dev/null +++ b/basic python programmes/venv/pythontesting.py @@ -0,0 +1,8 @@ +# factorial programme + +n = int (input("Enter a number to find its factorial : ")) +fact = n +for x in range(n): + if x!=0: + fact = fact * x +print(fact) \ No newline at end of file diff --git a/basic python programmes/venv/pyvenv.cfg b/basic python programmes/venv/pyvenv.cfg new file mode 100644 index 0000000..78a2080 --- /dev/null +++ b/basic python programmes/venv/pyvenv.cfg @@ -0,0 +1,3 @@ +home = C:\Python\Python37 +include-system-site-packages = false +version = 3.7.1